-
Notifications
You must be signed in to change notification settings - Fork 13
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.
To get a copy of the THOR source code, you ran
$ git clone https://github.com/exoclime/THOR.git
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
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>"
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.
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.
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)
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>
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.
For a visual display of the history, try out gitk
.
For emacs
users, the magit
package looks pretty powerful.
For visual diffs, use meld