Git memo
I’m planning to use git, a popular new version control system, for all the developments that I don’t want to publish on a forge (like Sourceforge). Because it’s distributed, it’s possible to perform commits offline. This solves my nightmare of making modifications that break the project and spending hours to track down the problem. So far I like git very much. Here’s a memo of commands and useful information.
Tell git who you are
$ git config –global user.name “FirstName LastName”
$ git config –global user.email “user@example.com”
You can run those commands without –global inside a repository.
Fancy colors
$ git config –global color.ui “auto”
Initialize a local repository
$ cd /path/to/project
$ git init
The repository is initially empty, it’s necessary to add the files and directories that we want to track.
$ git add file
$ git commit
The convention for commit messages is:
Short summary of changes.
Long description of changes… Blablablabla.
$ git rm file
$ git mv oldfile newfile
Cloning repositories
Local:
$ git clone /path/to/repo name
Git protocol:
$ git clone git://git.rubini.us/code name
SSH:
$ git clone ssh://myserver.com/var/git/myapp.git name
HTTP:
$ git clone http://yourserver.com/~you/proj.git name
To import new changes from the original repository:
$ git pull
To import changes from another copy of the repository:
$ git pull /path/to/repo
To apply your commits to the original repository (provided you have permissions):
$ git push
To create an alias:
$ git remote add aliasname /path/to/repo
$ git pull aliasname
pull is equivalent to fetch + merge
$ git fetch aliasname
$ git merge aliasname/master
Repository status and history
$ git status
$ git log [file|tag|range]
Use -p to show the log as patches.
$ git diff [file|tag|range]
$ git show [commit-id]
To show an old file:
$ git show v2.5:fs/locks.c
Revert changes
To revert committed changes:
$ git revert commit-id
To revert uncommitted changes:
$ git checkout -f
Creating patches
$ git diff [commit-id-before] [commit-id-after] > my.patch
format-patch is a command to create ready-to-send patches. One commit is created in one file.
To extract the three topmost commits from the current branch:
$ git format-patch -3
To extract patches from a range of commits:
$ git format-patch commit-id-start..commit-id-end
To extract patches since a commit:
$ git format-patch commit-id
Note: In the latter case, this extracts patches since the commit-id excluded.
Tags
List of tags:
$ git tag -l
Tag current work:
$ git tag v1.0
Tag a commit:
$git tag name commit-id
And to get the commit-id from the name:
$ git rev-parse name
Switch to a tag:
$ git checkout 0.9
HEAD refers to head of the current branch.
Working with branches
To see the current branch:
$ git branch
To see the list of branches:
$ git branch -a
* denotes the current working branch.
For remote branches:
$ git branch -r
To create a new branch and switch to it:
$ git checkout -b branch-name
You may create a branch from a starting reference:
$ git checkout -b branch-name from-branch|commit-id|tag
To switch to another branch:
$ git checkout branch-name
It’s a possible to switch to a revision:
$ git checkout commit-id
Note: if some files differ between the current branch and the branch you check out and are currently open in your text editor, it will warn you that the files have changed. In that case, just reload them.
Working with remote branches
You cannot switch to a remote branch, you need to create a local one which is the copy of the remote one:
$ git checkout -b my-branch origin/my-branch
$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git
$ git fetch linux-nfs
Finding regressions
To find a regression that happened between v2.6.18 and master:
$ git bisect start
$ git bisect good v2.6.18
$ git bisect bad master
git will try several revisions until it identifies the revision that caused the regression. You need to tell git if the regression occurs or not with:
$ git bisect bad
and
$ git bisect good
Once the revision is identified, use “git show” to examine it.
To return to the branch you were on:
$ git bisect reset
Compression and self-consistency check
$ git gc
$ git fsck
Git workflow
This is a typical workflow to contribute to a project using git.
Retrieve latest code from the remote repository:
$ git pull
Create a new branch to work safely on a new feature:
$ git checkout -b new_feature
Commit your changes:
$ git commit -a
Check if new code was added in the interim:
$ git checkout master
$ git pull
If anything was changed in the master branch:
$ git checkout new_feature
$ git rebase master
rebase unapplies the changes, updates the branch and reapplies the changes back.
Warning! If you are sharing a branch, you must use:
git merge master
If there are conflicts applying your changes during the git rebase command, fix them and use the following to finish applying them:
$ git rebase –continue
Merge the changes in the master branch:
$ git checkout master
$ git merge new_feature
Push your changes to the remote repository if you have permission:
$ git push
Alternatively, submit patches or publish your own copy of the repository so that other people can pull changes from you.
Finally, you may want to delete the branch:
$ git branch -d new_feature
Sharing repositories with the world
SSH is used to push commits and HTTP to allow people to pull from the repository.
$ ssh you@yourserver.com
$ mkdir /home/you/public_html/proj.git
$ cd /home/you/public_html/proj.git
$ git –bare init
$ git –bare update-server-info
$ chmod a+x hooks/post-update
$ exit
Note: init is still called init-db in Debian Etch.
$ cd /path/to/local/repo
$ git remote add origin ssh://yourserver.com/home/you/public_html/proj.git
$ git push origin master
Next time you can omit the arguments:
$ git push
Now you can use
$ git remote
$ git remote show origin
People can now clone your repository, either by SSH or HTTP.
$ git clone ssh://yourserver.com/home/you/public_html/proj.git
$ git clone http://yourserver.com/proj.git
gitweb
In Debian, gitweb installs to /usr/lib/cgi-bin/gitweb.cgi.
I added the line below to my VirtualHost:
ScriptAlias /gitweb /usr/lib/cgi-bin/gitweb.cgi
I also edited /etc/gitweb.conf to configure the git root as well as the git logo and CSS stylesheet.
Cloning a Subversion repository
$ git-svn clone http://svn.site.org/svnroot/projet -T trunk -b branches -t tags
To import new modifications from Subversion:
$ git-svn rebase
To apply commits to Subversion:
$ git-svn dcommit
References
http://rubinius.lighthouseapp.com/projects/5089/using-git
http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#public-repositories
http://www.kernel.org/pub/software/scm/git/docs/everyday.html
http://www.eleves.ens.fr/home/oudomphe/comp/ware/git.xhtml.fr
http://toolmantim.com/article/2007/12/5/setting_up_a_new_remote_git_repository