I've become quite comfortable with GIT after the initial uphill battle with its seemingly overwhelming list of commands. You begin to realize how many things you can do in GIT that you couldn't previously do in other revision control systems once you adapt your workflow to something that works better with GIT. Coming from CVS on the pacman project, it took some changing of habits but overall I can be much more efficient now.
The basics come first
Because GIT works with an index between your working tree and the previous revision, committing and diffing can become much more powerful. For one, you don't need to commit at the whole project or file level as you do with CVS or SVN. Without going into too much detail, I'd recommend reading
man git-add, and especially looking at the interactive option. Once you have git-added a file, you can make further changes and they will not automatically be committed until you add them again- at first this seems weird, but is quite powerful. Read up on
git-diff --cached as well.
GIT makes it relatively easy to submit patches for review, because the subject and description of the patch can all get sent out with it. Patches made using the GIT tools are far easier to apply correctly than those using the standard diff utility. They are also easier to create once you get things set up.
For creation of patches, don't think the way you would with CVS/SVN, where you never actually commit your changes. The best method I've found is to create a topic branch (remember that branches are extremely cheap in GIT) using
git checkout -b fixfoo from the master branch. From there, change and test the code until you get things working right. Then commit the patch, with a good description line and as much description is necessary. Sign off on it too for good measure. Then the following set of commands can send your patch right off to wherever it needs to go:
git-format-patch master git-send-email <patch files>
A few hints about the above- the patch files are always numbered and named with their subject line, so pick good subjects. git-send-email also needs some initial setup to get it working as expected. Using git-config, I set the
sendemail.smtpserver variable to
/usr/bin/msmtp. I then configured msmtp with my email account settings.
At least in my position, I tend to apply patches more than send them out. This is fairly straightforward. A quick hint for those that use Gmail: you are able to use the "Show original" link on a message to get a plain-text file that will apply with the git patch tools, with one exception- once you save the file, you will need to delete the first (blank) line of the file.
For those not using Gmail, I'm sure you can figure out how to get plain text emails out of your client, or at least into mbox/Maildir format. I tend to only apply one patch at a time, so it is quite simple:
git-am -s < /tmp/<patchfile>
The advantage this has over using
patch is simple- it actually creates a GIT commit and you don't need to rewrite the description message. Of course, we have a few people on the mailing list that don't submit patches this way...
I could look at it as a blessing or a curse, but GIT allows extensive local development that can exist independent of the master branch. With CVS, you really have to keep multiple checkouts and pray that updates of the repository don't smash your changes. With GIT, you can manage all these topic branches in one local repository. At the time of writing this, I have some 11 local branches, each with a different purpose. When it comes time to merge these in, I won't have to pray like I did with CVS that the merge or application of the patches will work- I know it will be relatively smooth.
One of the most helpful commands when it comes to keeping your work up-to-date with the master branch is
git-rebase. The manpage gives a good overview (as does just about every GIT manpage, they are highly recommended reading). At first, the command line syntax of the option can be daunting but that is only because it can be quite powerful. When it comes down to it, 95% of the time the usage will look like this:
git-rebase master <yourbranch>
This will rebase the bottom of your branch (or patch stack) onto the tip of master. You may have to resolve some conflicts while doing this, but using git-mergetool should prove to be very helpful. In addition, running
mkdir .git/rr-cache is recommended- it will create a cache directory that records these hand merges and will use them later if appropriate, saving you time and thinking. If this directory exists, the rest will be automatic; see
man git-rerere for details.
More to come
For now I'm going to leave off with this- GIT isn't something you can master in a day, but you can quickly become quite proficient in doing things fast with it.
Some future topics I'd like to touch on, so keep your eyes open for these: qgit and how I use it all the time git-stash (new in v1.5.3) and its alternatives * git-merge and its infrequent but helpful usage
In addition, feel free to send me an email with anything that you think is GIT related and worth posting about. Or really about anything Arch and programming related, because that is what this blog mostly caters to.