Git is a widely used package for source code versioning, originally developed for usage with the Linux kernel. In contrast to CVS or SVN it is a distributed versioning control system, meaning that it can be fully used locally without any servers. Everybody who checks out a project versioned by Git receives a complete copy of the project’s history. Although it is not exactly necessary, dedicated versioning servers are widely used with Git to make cooperative programming easier. That then again sounds like SVN but is much more flexible. Git can easily synchronize repositories from and to everywhere, making it possible to use multiple servers, sync local copies and syncing directly with colleagues. Putting new code on a server is a two step process. Code is first commited to a local repository using git commit. When that succeeded, the local repository is synced to the remote repository using git push. Getting new code from the server is optionally just a single command - git pull. More complete tutorials for Git can be found all around the internet.

Kore makes heavy use of submodules, a Git feature rarely discussed in tutorials. A submodule is a link inside a project tree to another Git repository. Most Git commands by default ignore submodules. To create a new local copy of a Git repository (usually the first step), call git clone --recursive https://whateveryoulike To get the latest code use git pull and then git submodule update --recursive. Git can get tricky when you try to work inside a submodule. You can read more about it in the “Issues with Submodules” chapter at http://git-scm.com/book/en/Git-Tools-Submodules Some short hints are also available at http://ohshitgit.com/

A short tutorial

In the following, you can see a series of git commands which can get you started.

Please note: The tutorial uses the command line version of git. There are graphical tools that make working with Git easier, such as Tortoise Git for Windows (https://tortoisegit.org/), SourceTree for OSX and Windows (https://www.sourcetreeapp.com/) and SmartGit (http://www.syntevo.com/smartgit/) for Linux, Mac and Windows. But in any way, start with installing Git from https://git-scm.com

git clone --recursive https://github.com/TUDGameTechnology/Exercise1.git

clone will get the latest revision of the “master” branch of the repository, in this case the “exercise 1” repository. A directory named “Exercise1” is created, so don’t forget to cd Exercise1 before continuing.

You can use git status to check the result of this operation:

On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Our remote URL (where we pull changes from and where we push them to) is set up with the URL we provided. You can check this with git remote -v:

origin  https://github.com/TUDGameTechnology/Exercise1.git (fetch)
origin  https://github.com/TUDGameTechnology/Exercise1.git (push)

And we can check the available branches and the branch we are currently working on using git branch -a:

* master
remotes/origin/HEAD -> origin/master
remotes/origin/master

The asterisk marks that we are working on the default branch, master.

To make the switch to your repository, you can use the command git remote set-url origin https://git.kode.tech/r/GT2017/[Teamname].git.

Checking the result with git remote -v now shows:

origin  https://git.kode.tech/r/GT2017/[Teamname].git (fetch)
origin  https://git.kode.tech/r/GT2017/[Teamname].git (push)

To upload the solution to exercise 1, we want to upload our work into a branch with the name exercise1 (note: this is used when grading the exercises, the latest revision from this branch is used to automatically build the exercise).

We get started using git branch exercise1. Afterwards, git branch -a shows us:

exercise1
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master

We have created the exercise1 branch, but we are not working in it. One way to continue is to push our current state into the branch exercise1 by issuing git push origin exercise1.

We now see using git branch -a:

exercise1
* master
remotes/origin/HEAD -> origin/master
remotes/origin/exercise1
remotes/origin/master

We now also have the remote branch exercise1. To start working on this branch, we should switch to this branch. We achieve this using git checkout exercise1:

Switched to branch 'exercise1'

git branch -a confirms this:

* exercise1
master
remotes/origin/HEAD -> origin/master
remotes/origin/exercise1
remotes/origin/master

To complete exercise1, I have made some changes to files. git commit tells me which:

On branch exercise1
Changes not staged for commit:
        modified:   Sources/Exercise.cpp
        modified:   Sources/SimpleGraphics.h

no changes added to commit

I decide that the change in SimpleGraphics.h is not needed. To revert it to the state before the change, I can checkout the file in it’s latest state on the server using git checkout Sources/SimpleGraphics.h. If I already committed or pushed the file, I could still revert the change, of course, but would need other commands.

To commit the remaining change, I use git commit -a to commit the file.

Depending on your system, a text editor opens allowing you to type a commit message. (In case it is vi and you have never seen it before, a) don’t panic and b) check out http://www.nuxified.org/vi_survival_guide ;-)

The result is:

[exercise1 71a8343] Made some changes to a file.
1 file changed, 1 insertion(+)

So far, we have only done this change locally. To push the change onto the server, we can use git push origin exercise1 to push our changes in branch exercise1.

Finally, say we have added a file for the theoretical exercises called “solution1.txt”. git commit -a will not create a commit for it, since it is new and not yet under version control. So we first add it with git add solution1.txt. Afterwards, a git commit will allow us to create a commit, which we can push with git push origin exercise1.

Of course, this is only a small part of what git can do and one way of using it to work with the exercises.

Updating to a new exercise

For each exercise, new code is provided. To get this new code, you can pull it into your repository. First, create or switch to the correct branch for the exercise, e.g. by using

git branch exercise2
git checkout exercise2

For pulling the code into your repository, you can use a command like

git pull https://github.com/TUDGameTechnology/Exercise2.git

for getting the source code of Exercise2.

This will generate some conflicts since the files changed between the versions:

remote: Counting objects: 23, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 23 (delta 0), reused 0 (delta 0), pack-reused 17
Unpacking objects: 100% (23/23), done.
From https://github.com/TUDGameTechnology/Exercise2
 * branch            HEAD       -> FETCH_HEAD
Auto-merging Sources/SimpleGraphics.h
CONFLICT (content): Merge conflict in Sources/SimpleGraphics.h
Auto-merging Sources/SimpleGraphics.cpp
CONFLICT (content): Merge conflict in Sources/SimpleGraphics.cpp
Auto-merging Sources/Exercise.cpp
CONFLICT (content): Merge conflict in Sources/Exercise.cpp
Auto-merging Kore
Automatic merge failed; fix conflicts and then commit the result.

You can read up on resolving conflicts here: https://help.github.com/articles/resolving-a-merge-conflict-from-the-command-line/

(By the way, this is a good point to get a graphical git frontend or at least a diff tool ;-)

To just accept the changes in the newer repository, you can do

git checkout --theirs [File]

for the files in conflict.

Then, add the files to a merge commit by issuing

git add [File]

The conflict in the folder “Kore” is a special case than can happen when the submodule “Kore” has been updated. To update Kore to the version that is referenced in the newer repository, you can issue an

git submodule update --recursive

This will update Kore to the version that is referenced, and will resolve your conflict.

Finally, issue a

git commit

and then push into the correct branch for the exercise.