Table of Contents
Getting source
Installing git
Since git is used by Linux kernel developers it's easily available on most modern distributions. If you use, say, Fedora, run this (as root) to install the git distributed version control system:
yum install git*
This is a crude way to perform such an installation, and will install many possibly unwanted packages.
More elegant is to install just what is sought, to avoid over-filling a development environment with un-needed and potentially unwanted packages:
yum install git
If you are using CentOS you may wish to add and temporarily enable the EPEL repository before installing git via yum. More information here Alternatively, more current git RPM packages are available here from the primary 'upstream' for the development of git
Branching
Let's develop a new 'super' features. You should never write new code develop new code against the 'master' branch. In the mirror source code repository, 'master' is used only to provide a record of the former subversion mainline.
To write new code, create a new branch and check it out. (Since the branch is local, creating a new branch takes only a second or two).
git checkout -b super-feature
Option -b means that you are creating a new branch and checking it out. If you later want to switch to this branch, run the same command without a -b option. 'git checkout' is similar to 'svn switch' (not to 'svn checkout').
You can make some changes now using your favorite editor
Once you happy with your changes, and they pass your local testing, commit them. You'll be only checking in to your local git repository, so commit early, commit often.
git commit -a
Option -a means that you want to add all changed files to the commit. Alternatively you can run
git add
and add the files one by one, or on a directory by directory bases. Differently than in subversion, when using git you must tell it explicitly which files you are committing.
Git is more liberal and forgiving than subversion. You can amend a commit later if you forgot about something. You can even rewrite the history several commits back, as long as you did not externally share your changes with any other archive.
Generating patches
Before you generate a patch against release-4.6, it's a good idea to rebase release-4.6 against the git mainline and then rebase your branch against a fresh copy of: release-4.6
- Switch to active development release-4.6 branch
git checkout release-4.6
Retrieve the latest commits from git repo
git svn rebase
Git is quite efficient at merging your changes during rebase. Check here about how to resolve conflicts if you have any (not sure where "here" was meant to be, but 'git mergetool' is useful).
Now you're ready to generate the patches.
git format-patch master
Or you can redirect your patches to another directory:
git format-patch master -o ~/patches
Git will generate one patch file for every commit on the branch. Since git lets you modify the history of the commits you can generate a series of patches that can show the logical development of your feature. Alternatively you can choose to generate a single patch like this:
git diff master > super-feature.patch
You can attach patches to JIRA issues or send them on the list for discussion.
Let's assume that you have been hacking for a while on a branch (say: XECS-2387) and your work spans more than one component (in this example, let's assume: sipXbridge and sipXconfig ). You want to commit your sipXbridge changes to the version control system, because you are happy with them but want to submit some other changes as a patch to the owner of that other component because he wants to inspect your patch before accepting it. Here is how to proceed.
git commit sipXconfig/ -m"XECS-2378: sipxconfig changes for supporting hidden parameters"
git commit sipXbridge/ -m"XECS-2378: sipxbridge changes for supporting hidden parameters"
git format-patch master -o ~/patches # Note that this will create two patches
git rebase XECS-2378 master
git rebase -i HEAD~3
and remove the line that you want to remove when the editor brings up the interactive screen (i.e. the sipXconfig patch in this case). Then do the
git commit
as above. Pick up the other patch and attach it to the issue, thus maintaining friendly relations with the owner of the other component.
Accepting patches sent by other developers
Quite often people will comment on your patches. Sometime developers will generate patches on top of your patch. You can commit them to your git repository.
If someone sends you a patch generated with git
git checkout super-feature # make sure you are in the proper branch
git am -3 0005-some-fixes.patch
That will commit the patch to super-feature branch - it will preserve the name of the patch author and their comments.
'-3' means that git will try to merge the patch. If there are conflicts use:
git mergetool
to resolve them.
You can list multiple commits, or an entire directory full of patches:
git am -3 patches/*patch
You can make your changes on top of the patch and commit them separately. Or you can amend the previous commit with your changes.
... hack ... hack ...hack
git commit -a --amend # -a means add all changes, --amend means fix previous commit
You can also easily accept/review patches generated with svn diff, gendiff etc.
QUERY: ???? is this prior line a correct syntax for a git example – RPH
git apply -p0 0005-some-fixes.patch
That will apply the patch but not commit it (if patch was not generated by git it does not have enough information to create commit). It's slightly more convenient than using patch command since it'll behave in an atomic way (the apply will succeed or fail - it won't leave your workspace partially patched)
More tips
- If you know subversion pretty well check this out: http://git.or.cz/course/svn.html
- There are a few tech talks with helpful information about git:
- Video
- Audio
- Book
- Reference
There is several git GUIs - if you use Gnome giggle is a good choice
yum install giggle
giggle &
If you encounter problems when rebasing or merging 'git mergetool' command can be used to launch graphical 3-way merging tool. Make sure that you run it from the root of your git repository.
git rebase master
- ... reports merge conflicts
git mergetool - launches your favorite merge tool (meld in my case)
- after you merge all conflicting changes
git rebase --continue
'checkout' and 'status' are probably 2 most commonly used commands. To add svn-like aliases for them:
git config --global alias.co checkout
git config --global alias.st status
And now you can use those aliases, 'st' and 'co' instead of the fully spelled out keywords:
git st # instead of git status
git co master # instead of git checkout master
Enable colorized output for various commands:
git config --global color.branch auto
git config --global color.diff auto
git config --global color.interactive auto
git config --global color.status auto
If you use bash, use git-completion.bash. It enables simply pressing: <TAB> to display a list of potential commands, arguments and parameters. For example:
git checkout <TAB>
will show the list of branches.
Source it in your ~/.bashrc:
. /path-to/git-completion.bash
To have the current branch appear on your bash prompt:
export PS1='[xecsdev:\u@\h`__git_ps1` \W]\$ '
If you want to roll back to a particular point in history ( say some feature that is currently broken, but formerly worked a week ago and is blocking your progress ): Look at your git repository using giggle. You will see each commit has a global UUID. You can pick out the specific point in history when the world still looked rosy by doing:
git checkout -b proxy-still-worked UUID