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.
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,
To make the switch to your repository, you can use the command
git remote set-url origin https://git.ktxsoftware.com/r/GT2015/[Teamname].git.
Checking the result with
git remote -v now shows:
origin https://git.ktxsoftware.com/r/GT2015/[Teamname].git (fetch) origin https://git.ktxsoftware.com/r/GT2015/[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
and then push into the correct branch for the exercise.