Skip to content
nabajour edited this page Dec 5, 2018 · 1 revision

Git Survival Guide

Git is a "distributed versioning system". It has a good and extensive documentation that I encourage you to read.

This is not an extensive tutorial and explanation of the workings of git, just some everyday commands that are used in THOR development as reminders or to help you start looking for solutions, and give you just enough knowledge do be dangerous.

Get a repository

To get a copy of the THOR source code, you ran

$ git clone https://github.com/exoclime/THOR.git

Changes

When you work local, you can track your changes with git. To check if there are some changes in the project compared to the stored history:

$ git status

To check the history of the branch you are on

$ git log

Shows the branch with the date of change, user who changed it and its description, and a long hexadecimal string called the SHA1 hash that identifies the change in the Git tree. (As a side note that won't help you learn to use git, for math and algorithmic geeks, Git uses a Merkle tree for its internal representation))

To show the changes

$ git diff

In command line diff, or for an external tool:

$ git difftool --tool=meld

To show a tool with the external tool meld.You can install it with your package manager, other similar tools exist, like kdiff3. If you like it, you can also add it to your ~/.gitconfig and avoid typing the --tool=meld with this block:

[diff]
        external = meld

Managing changes

When working on the code on a branch, you might want to add the changes to the tracked history. You'll see in git status what changes exist. You can collect the ones to apply in the staging area, with:

$ git add <file1> <file2> <file3>

You'll see them appearing in the staging area when looking at git status. There are some instructions there to get them out of the staging area, or revert them to the state they are at in the history. If you are happy with the changes, you can add them to the history with

$ git commit -m "<description of the changes>"

Branches

The above helps you on one branch, to track your changes. If you want to track other bits of development or make several parallel developments on different subjects without them to interfere with each other, you use branches. A branch is a track of changes from a certain point in the history tree.

You can create a branch from the current position with

$ git checkout -b <new_branch-name>

If you didn't do any changes, you can go to another branch with

$ git checkout <existing_branch_name>

This sets the state of all the files in your project to the state recorded in the branch.

To go to a certain point in time, for instance to test how the code was performing at some point before a change that you suspect to impact the behaviour of the software, you can use the hash

$ git checkout <LONG WEIRD HEX HASH NUMBER>

Be careful if you do changes there, you can't change the saved state of the history, you can save the state in new commits in a branch leaving from that state, but if you want it at the top of the tree (called the HEAD), you'll have to merge the changes.

diffing

To make a diff between files in different branches, use

$ git diff <branch1> <branch2> -- <file1> <file2> ... <fileN>

(you can use git diff or git difftool, they accept the same arguments)

To compare to a point in history, uses their hashes:

$ git diff <HASH1> <HASH2> --  <file1> <file2> ... <fileN>

If you emit one of the branch or of the hashes in the commands above, it will compare to the current state of the tree you're in.

merging

If you have to branches (usually not so different), and want to join them (apply the changes of one to another), you can merge.

Go to the branch you use as a base with git checkout <branch1> and want to merge branch2 in, then merge:

$ git merge <branch2>

This will try to merge the files and apply the changes that happened on both branches since the point they diverged. It can sometimes not work automatically and make merge conflicts that are shown in git status and will need to be resolved manually, by looking at the file and choose what piece of code you want at certain points marked by big text markers in the files.

(Another way to merge which makes for a cleaner history if you didn't change or publish stuff is git rebase, which will try to apply all the changes from one branch on top of the other, to have a linear list of changes)

Remotes

All the above can already be pretty useful when working by yourself on your machine, by helping you to track changes and giving you access to all the history of your changes.

Where it gets even better is when you work with other repositories and other people to share code.

You can use git to track the state of other repositories, and compare them to yours. If you used git clone to get your copy of the code, you're automatically tracking the origin remote.

If you are on the master at the top of the tree without changes, you can get the latest state of the code with

$ git pull

This will grab the latest state of origin to the internal database of git (it's also done by git fetch) and apply the changes to the code in your working directory. If you did commit changes, it will need to merge the branch your pulling in. (git pull is effectively fetch + merge)

You can publish your changes to a remote with

$ git push <remote_name> <remote_branch>

If the remote branch is set as default for the branch you're on, you can just use git push

You can see the remotes git knows about with

$ git remote -v show

and add one with

$ git remote add <remote_local_name> <remote_url>

GitHub

pull requests

The usual workflow is to create your own copy of the code on github with fork.

Then, you clone that repository to your local drive with git clone. You can work on that copy with the above commands, and push your changes to your fork. If you think your changes should be integrated in the main THOR repository from exoclime, you can make a pull request. This way, we get a link to your changes and a place to discuss the changes to see that they fit in the structure we built for THOR and can integrate the code.

If the change is a bugfix, integrating should be pretty straightforward, architectural changes or changes that impact the algorithms, physics and dynamics must be integrated in a way that that they benefit everyone or can be enabled and disabled, so that THOR can still be a general purpose system that can fit different use cases.

Nice tools

For a visual display of the history, try out gitk.

For emacs users, the magit package looks pretty powerful. For visual diffs, use meld