DATT4520 & DIGM5520: Generative Art in Mixed Reality / Spatial Computing in Responsive Environments

Working with Git and Github

Git is a version control system.

Git helps you keep track of code changes.

Git is used to collaborate on code.

Version control systems like git emerged from the problem of how to let a lot of people work on one code base at once, without ever losing anybody's work or breaking the project etc.

There are two ways to interact with git -- either using a command line terminal (including the one built into the VS Code editor), or using a visual app (like the Github app). I strongly recommend learning to use the command line version, partly because it works everywhere, and partly because sometimes the the Github app gets stuck and you have to go to the command line to fix it anyway.

The basic idea:

Remember, Git and Github are different things.

Installing Git

First, check whether you already have it, by typing this into your terminal console and pressing 'enter':

git --version

If you get a message back saying that the git command can't be found, you need to install Git. Follow the instructions here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git

Before using git you need to configure it with your name & email, so that your code changes are properly identified:

git config --global user.name "your name here"
git config --global user.email "your@email.here"

Clone a repo

First, you need the appropriate address of the repo to clone. On Github this can be found in the green "Code" dropdown button on the main page. E.g. our project's Github URL is: https://github.com/worldmaking/2024-datt4520-digm5520 The Git URL for this repo is: https://github.com/worldmaking/2024-datt4520-digm5520.git (notice that it ends with .git)

Then, make sure that you are in the right parent folder in your console/terminal, and then:

git clone --recursive https://github.com/worldmaking/2024-datt4520-digm5520.git 

This will create a local copy of the "main" branch of the repo, which you can now work on locally, making edits as needed.

At this point the usual workflow is to:

Committing a change

If you edited a file that was already tracked in the repo, it will already be staged. You can verify this with

git status

If this command lists any untracked files that should be part of the repo, you need to add them:

git add myfilename

Again you can git status to verify this has worked.

Now you can commit the change to your local history. A commit requires a descriptive message, typically just a few words, to say what changed:

git commit -a -m "I fixed problem X"

Or just

git commit -am "I fixed problem X"

The -a part means commit everything staged. The -m part means "here is the message describing this change".

Now the changes are part of your history, and you have just created a new version.

What not to add

Do not add large files to git repos: Git is only designed for working with small files, like simple text files. Large media assets should never be in a git repo. We have to find a different solution for managing these if we need them.

DO not add temporary or system files: Things like _DS_Store files or other normally-hidden files, or temporary files, or locally-generated files (like node_modules) should not be part of the repo. We can tell git to ignore certain paths and file types using the .gitignore file. For example, our project's .gitignore file currently contains things like the following -- any file with these pathname patterns will be ignored by git:

logs
*.log
node_modules/
.env
temp/
.temp
.cache

Synchronizing with the remote repo

After committing, the next thing we need to do is make sure we are up to date with the remote repo, because maybe somebody else has been pushing changes since you last did this. Always pull the latest changes before you push your own.

Get the latest changes with:

git pull

At this point, usually everything goes well and you get the message that you are up to date. This is the point where git combines your changes with all the other changes that have happened to the repo since you last pulled it.

However, there is a chance that at this point you get a conflict -- which means that your changes cannot be combined with somebody else's changes without losing work. So at this point git will ask you to resolve the conflict before you can do anything else. Follow the instructions that it gives you to do this.

Once any conflicts are resolved, we can then push our changes to the remote repo like this:

git push

Working with branches

Branches are a way to store a parallel version history, which we can merge back later if we wish to.

There are two common cases where we want to use branches:

Here are the important commands

List all branches:

git branch -a

Switch to a different branch:

git checkout thebranchname
git pull

git checkout develop
git pull

git checkout main
git pull

When you do this, you'll see all your local files on disk change to match the state of the branch on the repo.

Now you can make changes on this branch, and use git status, git add and git commit to add and commit files as normal. These commits go to the branch you are now working in. And you can push these changes to the remote branch using git push.

Creating a new local branch

This is typically what you need to do a feature-branch. First you need a simple name for the branch, e.g. "feature_mything"

git checkout -b feature_mything

Now you can use git status, git add and git commit to add and commit files as normal, and the commits will go to your local "feature_mything" branch.

If you want to push this work onto the remote repo, so that others can see your new branch, or just to make sure it is stored in the cloud, you can git push it. However the first time you do this, git doesn't yet know where to push it to, because it is a new branch. So the first time you push your branch, you need to set it up to also create a branch on the remote origin repo. You can do it like this:

git push -u origin feature_mything

From this point on, the relationship between your local and remote "feature_mything" branches is set up, and now you can just use git push.

Merging a branch

Let's say your "feature_mything" branch was branched from the "develop" branch. You've worked on the "feature_mything" branch for a while and you are happy that the feature is working and ready to merge back into the "develop" branch. Here's what you need to do.

Make sure all your changes are committed (use git status to verify)

Switch to the receiving branch ("develop") and make sure it is up to date:

git checkout
git pull

If it is all up do date, now you can merge in your feature branch:

git merge feature_mything

If any conflicts arise these need to be resolved immediately.

Otherwise, your merge is now complete. You can now git push the develop branch.

If you are finished with the feature branch, you can delete the local branch like this:

git branch -d feature_mything

To delete a remote branch:

git push origin -d feature_mything

Github Pages

There's a neat feature of Github that allows the easy creation of a public client-side website.

All you have to do is create and work on a branch with the special name gh-pages, then any files that you commit here will be the content of a static website. The URL of this website depends on the github owner account and the repo name:

https://ownername.github.io/reponame

For example, these course notes are actually hosted via a Github project. The project is at https://github.com/worldmaking/digm5520. The URL of the pages is https://worldmaking.github.io/digm5520.

However as our project this year has its own web server we don't need to use the github pages feature for the live project pages, but we may perhaps use this feature to document the project.

Forks

Another way to collaborate via git is to create a Fork. You can do this on Github for any public project. A Fork is a copy of a repo that has the same history but is no longer connected to it. But after making changes to a Fork, you can submit a "Pull Request" to whoever manages the original repo, and they can review your changes before pulling them into their own repo.

Resolving conflicts

Conflicts can happen sometimes when collaborating on code, where different people can create edits that git can't merge by itself. In these cases, git status will tell you you have unmerged paths

See https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line

When two people have modified the same line in a file

After committing your change, and then running a git pull, you get a message saying there is a conflict in a file ("both modified").

Open that file in a text editor (e.g. VS Code). Search the file for the text <<<<<< to see where each conflict begins.

Conflicts are marked in the text file like this:

unchanged content
<<<<<<< HEAD
your changes
=======
the other person's changes
>>>>>>> branch-a
unchanged content

Edit the file manually to the point that it should be, removing the <<<<<<< HEAD, ======= and >>>>>>> branch-a accordingly.

Do this for every conflict in every file that had conflicts.

Verify that your edits are correct and the code is working properly.

Only after verifying this, add your changes using

git add .

And commit with a message, e.g.

git commit -m "Resolve merge conflict by incorporating both suggestions"

It would be a good idea to git pull again to ensure the conflicts are done, and git push if you are collaborating on a remote branch so that other collaborators get your work too.

When one person edits a file and the other deletes the file

Here git status will give you a message "deleted by" for each file in question.

Open the file to have a look at the latest changes, and verify whether the file should be kept or deleted.

To delete it, use git rm filename. To keep it, use git add filename.

Once you have run either git rm filename or git add filename, and you have resolved all other conflicts, you can then commit the changes:

git commit -m "Resolve merge conflict by incorporating both suggestions"

It would be a good idea to git pull again to ensure the conflicts are done, and git push if you are collaborating on a remote branch so that other collaborators get your work too.