Git is a largely-expended cvs program. Have a look also here.
This manual supposes that user installed git v1.7 (apt package) at least in his environment.
It is not made for user experts but just for people looking for things that work simply.
It is composed of the following parts:
1. How to get a GIT code repository
2. How to set up your environment
3. How to interact with code repository
4. Branches in local repository
5. Branches in remote repository
6. About tags
8. Patch management
9. Clean up a repository
Make everything automatically with git clone.
git clone git://$URL
Example to get bacasable from Source Forge servers.
git clone git://bacasable.git.sourceforge.net/gitroot/bacasable/bacasable
You can also use this step-by-step method:
git remote add $PROJECT_NAME $GIT_URL
git fetch $PROJECT_NAME
git branch --track $LOCAL_BRANCH_NAME $PROJECT_NAME/$REMOTE_BRANCH_NAME
git checkout master
PROJECT_NAME is the local name of the url leading to remote repository. Feel free to choose something apealing to you.
GIT_URL is the url to remote git repository.
Example to get code from bacasable remote repository:
LOCAL_BRANCH_NAME is the name of the branch you want to track locally.
REMOTE_BRANCH_NAME is the name of the remote branch in remote repository you want to target.
2. How to set up your environment
Before beginning your work, be sure that your environment is setup according to your tastes.
Some people love vi more than emacs. Some Linux distributions use as editor nano by default.
In case you want to set up parameters for your whole user system, use git config –global.
How to set a prefered editor:
git config --global core.editor "vi"
git config --global core.editor "emacs"
Depending on which one you like.
A recommandation is to set up push.default at current.
With that you only push to repository the branch where you are currently.
git config push.default current [change the mode used for push]
There are 4 modes:
'nothing' : Do not push anything
'matching' : Push all matching branches (default)
'tracking' : Push the current branch to whatever it is tracking
'current' : Push the current branch
If you use Source Forge, have a look at the following guide.
Another recommendation: setup the following parameters to control what you commit and identify yourself as the committer.
git config --global user.name "John Doe"
git config --global user.email "firstname.lastname@example.org"
3. Now that you have the code, and that you have set you environment,
you wanna interact with it, no?
Here is how to play with branches and code in your local repository.
Try to modify some files, and save them.
Make a commit by involving in the commit all the files modified.
(This involves just existing files modified. In order to add all the files also, you have to make a “git add”).
git commit -a
After creating new files, they have to be tracked with this.
git add $file
On the contrary, to stop tracking a file and delete it.
git rm $file
To see the status of what can be committed (at the moment of entering this command).
4. Play with branches in local repository
Print out a list of all the existing branches (* marks the current branch being developed).
git branch -a
Create a new branch in local repository from a chosen start point.
git branch $NEW_BRANCH_NAME $START_POINT
START_POINT can be a branch name, a commit ID, or a tag name.
Checkout a chosen local branch.
git checkout $BRANCH_NAME
If you want to create a branch and then to check it out.
git branch $NEW_BRANCH_NAME $START_POINT
git checkout $NEW_BRANCH_NAME
To delete a local branch.
git branch -D $BRANCH_NAME
To rename a local branch.
git branch -M $OLD_BRANCH_NAME NEW_BRANCH_NAME
Get diff between branches, commit IDs or tags.
git diff $POINT_DIFF_BASE $POINT_DIFF_COMPARE
This is useful to generate patches based on a master branch for instance.
Have a look at the last commits done in named branch.
git log -p $BRANCH_NAME (all diffs also appear)
git log $BRANCH_NAME
git log $BRANCH_NAME --name-only (only file names appear)
Not naming a branch is equivalent to print logs of current branch.
This is helpful to get commit IDs.
You can also apply a patch in a GIT repository.
git apply $PATCH
Sometimes after fetching the latest data of a remote repository locally, it may happen that a branch deleted on remote is still listed locally. To delete a remote branch listed locally:
git branch -rd $PROJECT_NAME/$BRANCH_NAME
5. Play with branches in remote repository
This will push your local branch BRANCH_NAME to your remote project whose URL is PROJECT_NAME.
git push $PROJECT_NAME $BRANCH_NAME
The name of branch created on remote is the same as your local branch name.
In the case of not using the same branch name on the remote repository, here is a magic command.
git push $PROJECT_NAME $LOCAL_BRANCH_NAME:$REMOTE_BRANCH_NAME
If you want to delete a branch called BRANCH_NAME in your remote repository.
git push $PROJECT_NAME :$BRANCH_NAME
After pushing a new branch in remote repository, the local branch you pushed will lose tracking of the branch that is now in remote.
git branch -f $LOCAL_BRANCH_NAME $PROJECT_NAME/$REMOTE_BRANCH_NAME
This forces local branch to track the new remote one. It cannot be done on current branch.
6. Interacting with tags:
Git commit system is very powerful, you can find all the necessary information about a project state easily.
But sometimes a programmer wants to put a mark in his project so as to show that an important step has been done.
Tags can play a role to associate a commit in a branch with a tag name.
Create a tag:
git tag -a $TAG_NAME -m "message"
If multiple m options are used, messages are written as separate paragraphs.
Show all the existing tags and their associated message.
git tag -l -n
Push to remote repository all the tags.
git push --tags
Push to remote repository the tag chosen.
git push $PROJECT_NAME $TAG_NAME
Delete a tag in local repository.
git tag -d tagname => delete tag.
Delete a tag in remote repository:
git push PROJECT_NAME :TAG_NAME
Display local and remote tags.
git tag -l
Here is a basic process to rebase on a branch called $BRANCH_CURRENT a set of n last commits pointed by $CURRENT_HEAD_OF_PATCHES (being a tag, a commit ID or a branch head).
By being on a branch called $BRANCH_CURRENT, first checkout a temporary branch:
git checkout -b tmp
Then force the branch to be rebased to move to the head of commit set (last commit from the set of n patches wanted to be rebased).
git branch -f $BRANCH_CURRENT $CURRENT_HEAD_OF_PATCHES
Then make the rebase, take the last n commits from head of patches to be rebased.
git rebase --onto tmp $CURRENT_HEAD_OF_PATCHES~N $BRANCH_CURRENT
There will be for sure conflicts when you rebase $BRANCH_CURRENT, in this case it is necessary to treat them one by one.
git rebase --continue
makes rebase continue to the next conflict.
git rebase --abort
git rebase --skip
skip this conflict.
Once a conflict is solved on a file, do not forget to add it with “git add” before continue rebase.
When only few commits are being moved, git cherry-pick is also useful. For example, by being on $CURRENT_BRANCH:
git cherry-pick master~1 master~4
Takes the 2nd and 5th latest commits applied on master and creates 2 new commits on $CURRENT_BRANCH.
Generate a patch based on diffs between two branches.
git diff $CURRENT_BRANCH $DIFF_BRANCH > $FOLDER/patch_name.patch
Check statistics of this patch if applied.
git apply --stat $FOLDER/patch_name.patch
Check if patch can be correctly applied.
git apply --check $FOLDER/patch_name.patch
Apply a patch.
git apply $FOLDER/patch_name.patch
Generate a patch with context diff (needs package patch-utils).
git diff $DIFF1 $DIFF2 | filterdiff --format=context
Change all the author names and emails of a branch, and rewrite this branch.
git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" == "Your name to change" ];
then export GIT_AUTHOR_NAME="New name"; export GIT_AUTHOR_EMAILemail@example.com;
fi; git commit-tree "$@"'
Remove all the untracked files.
git clean -d -x -n
-n is for a dry run, so it shows what would be removed. Replace -n by -f to really remove the untracked elements.
-d includes repositories, -x for files ignored by git.