Learning more about git

From Wiki for iCub and Friends
Jump to navigation Jump to search

If you are not familiar with git we suggest at least you learn the basics. The official and comprehensive man pages are included in the Git package itself. You can access to them with:

  git --help
  git <command> --help

Quick Git Setup

Setup SSH Keys

You can use git with https, but this requires to insert the username and password every time you need to push on the server (and to fetch or pull if the repository is private). Using ssh will save you some precious time. In order to use ssh you have to create an ssh key and add it to your profile on GitHub.

Your Identity

The first thing you should do is to set your user name and e-mail address.

 git config --global user.name "John Doe"
 git config --global user.email "john.doe@example.com"

Some Color

If you use git mostly from the command line, colors are very useful, you can enable them by running:

 git config --global color.pager true
 git config --global color.ui auto

Bash Prompt

Bash prompt can be tweaked to show you in which branch you are by using __git_ps1. For example you can replace your default prompt in your ~/.bashrc file with:

 if [ "$color_prompt" = yes ]; then
     PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\[\033[00;32m\]$(__git_ps1 " (%s)")\[\033[00m\]\$ '
     PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w$(__git_ps1 " (%s)")\$ '

Migrating from SVN to Git preserving history

Simple projects

If the history of the project you want to migrate is simple (i.e. the project or its files were never moved around the repository), you can use git-svn to perform the migration.

The first step is to create a text file (e.g. authors.txt) that lists all of the users that would appear in your SVN repository and shows what their names would be for Git. The format is 'svn-username = Real Name <email address>', like so:

 mario-rossi = Mario Rossi <mario.rossi@iit.it>
 john-doe = John Doe <john@example.com>

Then, run the following commands:

 mkdir my_project_svn
 cd my_project_svn
 git svn init http://svn.blah.com/blah/trunk/ --no-metadata
 git config svn.authorsfile ../authors.txt
 git svn fetch

If you missed to list a user, the process gets stopped, but you can recover it by filling in the missing information and call "git svn fetch" iteratively.

Once the migration is completed, my_project_svn will still contain references to the original SVN repository; to get rid of them do:

 cd ..
 git clone my_project_svn my_project_git
 git remote remove origin

Finally, to publish my_project_git, create a brand new empty repository on your GitHub account and do:

 git remote add origin https://github.com/my-git-account/my_project_git
 git push origin master

Complicated projects

For projects that are more complicated you should use svn2git.

This includes the following cases:

  • The project folder was moved around.
  • Some files that are in your project were moved from outside your project folder.
  • You want to preserve svn branches or tags and convert them to git branches/tags.

svn2git is harder to use than git2svn, and it will require to download the whole robotcub repository revision database locally, and this will take time and disk space.

On the other side, once the database is downloaded the real migration is very fast because everything happens locally.

You can find some instructions and all the files used for the migration of some of the robotcub repositories: https://github.com/robotology-legacy/robotcub-ruleset

Using GitHub Pages and save space on repository

The GitHub Pages is a service offered by GitHub that can be used to publish software documentation online. Everything is basically done through the special branch called gh-pages. The branch must contain at the root level the index.html file pointing to the static documentation stored somewhere within the branch itself. However, the documentation generated with tools like doxygen might be composed of many products (sometimes images), thus it would be worth saving space on the repo by not retaining any history for those files. Here's a way for achieving that:

Creating the documentation

From master, create a new branch called gh-pages on your GitHub repo; then, locally do:

 git checkout master
 git fetch origin
 git branch gh-pages --track origin/gh-pages
 git checkout gh-pages

Now you have the same branch gh-pages also on your machine which tracks the remote gh-pages. Next step is to create the static documentation locally. Provide thus a sub-folder called doxygen where you have to put the proper generate.txt file that tells doxygen how to compile the documentation.

 cd doxygen
 doxygen ./generate.txt

Usually, to be neat, the file generate.txt contains instructions to put the generated documentation under doxygen/doc (this is recalled later).

Stage, commit and push the doxygen directory so as the index.html file to be located at the root level.

 git add ./doxygen
 git add ./index.html
 git commit -m "provided doxygen documentation"
 git push origin gh-pages

To have a taste of how the index.html file should look like, see here: therein, you have to replace the occurrence of the given github account with references to yours. After publishing the changes, you will have the url http://my-account.github.com/my-repository pointing to the documentation available on the web. It is advisable to cite that url from within the README.md file.

Updating the documentation

By creation, the special gh-pages branch should always mirror the master branch and should contain two things more: the doxygen folder along with the index.html file. Regarding the commit history, gh-pages should be always one commit ahead the master.

Whenever you update master branch then, do the following to update the documentation accordingly:

 git checkout gh-pages
 git rebase master
 cd doxygen
 rm -rf doc
 doxygen ./generate.txt
 git add ./doc
 git log -1
 git commit --amend
 git push --force-with-lease
 git checkout master

The "git log -1" command serves as verification and does display the very last commit message on the gh-pages branch, which must be "provided doxygen documentation", that is the one specified initially at creation time. The combination of "git commit --amend" and "git push --force-with-lease" aim to modify the latest stored commit instead of creating a brand new one and eventually force publishing it. This way, we always retain only one commit for the documentation instead of dealing with its whole history.

Recommended Tutorials

Try git in your browser:


LearnGitBranching - Web application designed to help beginners grasp the powerful concepts behind branching



Git homepage


A few more setup tricks can be found here:


A very comprehensive source of documentation is this:


Git reference:


A Visual Git Reference:


If you are a subversion user, you might find useful this crash course for svn users. Please note that git and svn workflows are slightly different, this is only supposed to be used as reference.


Git documentation wiki (contains several links):


CMake Git resources (more links):


More links:


More tutorials can be found here:


Interesting Readings

7 Git personalities, which one are you? (Suggestions to avoid common mistakes)