Some git-fu

Some git-fu I've been finding particularly useful recently:

  1. Untangling concurrent changes into multiple commits: git add -p is the greatest thing since sliced bread. But did you know it features an 's' command which allows you to split a hunk into smaller hunks? Now you can untangle pretty much anything.

  2. Splitting a previous commit into multiple commits: I've been finding this one useful for quite a while. Start with a git rebase -i, mark the commit(s) as edit, and once you get there, do a git reset HEAD^. All the changes in that commit will be moved out of the staging area, and you can git add/git commit to your heart's content. Finish with a quick git rebase --continue to the throat.

  3. Fixing your email address in previous commits: I often make a new repo and forget to change my email address. (For historical, and now silly, reasons, I like to commit to different projects from different addresses, and I often screw it up.) Here's how to do a mass change: git filter-branch --env-filter "export [email protected]" commit..HEAD, where commit is the first commit to be affected. Of course, changing the email address of a commit changes its id (and the id of all subsequent commits), so be careful if you've published them. (Also note that using --env-filter=... won't work. No equal sign technology.)

  4. A git log that includes a list of files modified by each commit: git log --stat, which also gives you a colorized nice histogram of additions/deletions for each file. This is a nice middle ground between git log and git log -p.

  5. Speaking of git log -p, here's how to make it sane in the presence of moves or renames: git log -p -C -M. Otherwise it doesn't check for moves or copies, and happily gives you the full patch. (These should be on by default.)

  6. Comparing two branches: you can use git log --pretty=oneline one..two for changes in one direction (commits that 'two' has that 'one' doesn't); and for the opposite direction. You can also use the triple-dot operator to merge those two lists into one, but typically I find it useful to separate the two. Or you can check out git-wtf, which does this for you.

  7. Preview during commit message: git commit -v will paste the diff into your editor so you can review it while composing the commit message. (It won't be included in the final message, of course.)

  8. gitk: don't use it. You'll get obsessive about merge commits, rebasing, etc., and it just doesn't matter in the end. It took me about 4 months to recover from the bad mindset that gitk put me into.

Hope that was helpful to someone else!


Matt Wilson said...

Thanks for writing this up. git seems to offer as many obscure tricks and customizations as vim.

I'm still at the stage where I switched to git, but I'm not as proficient with git as I was with svn.

Blog Archive