Inspired by Dave Miller’s discovery of git-stash, I decided to make an effort to learn more about git, instead of learning just the bare minimum to get work done and holding the rest of it out at arm’s length like a dead skunk. I found that git actually does a lot of the things I have been doing by hand with patch and diff on top of git, sometimes even in a more convenient and safer way! I still have a wish-list of features, but I feel confident that (a) they exist, and (b) someone (perhaps you!) will tell me how to use them.
I’ve found that my natural mental model for revisions is a stack of patches, and that I like the parts of git that just map directly to what I used to do by hand with patches or quilt (e.g., git-stash). This seems like a pointless tautology (“git is like automated patch management! Because source control is automated patch management!”), but it is meaningful because when I’ve used other source control systems, my mental model looked more like branches and sequential changesets and merges, whereas patches can be broken up, applied in different orders, etc.. Another handy patch-related feature I like (but haven’t used yet) is git-add in interactive mode, which lets you mark only certain chunks of patches for commit instead of all the changes in a file. I can’t say I’ll miss hand-editing patches.
git-rebase is another feature I really, really needed, since I was going back and fixing in bugs in old commits so that I could then figure out where I’d introduced other bugs. Rebasing involves several different commands, all of which I simply copy verbatim from some random git HOWTO page. Something that causes me major stress during a rebase is that the elapsed time between the initial checkout and the rebase command is fairly long, and the only way I know what commit ID to start the rebase with is by searching my bash history (via Ctrl-R) for my last checkout command (and hoping that I am checking the right shell instance).
Another thing I couldn’t figure out how to do efficiently during my commit grooming is to checkout the next patch ahead in the branch. So say you have commits A, B, C, D on this branch, where D is the HEAD, and you checkout B and run your regression test on it and it’s fine, so then you want to checkout C next. The way I ended up doing this is checking out HEAD again, looking through the commit log, finding the commit I’d just checked out, finding the commit following, and checking out that commit id again. At one point, I thought I would be all smart and keep the output of a git-log in another window so I wouldn’t have to do the checkout-HEAD part, but then I did a rebase and checked out a commit from the unrebased tree and spent a few minutes panicking over where my changes had disappeared to. Anyway, what I want is “git-checkout NEXT” – all the HEAD^^^ business wasn’t working for me because I was about 10 patches deep, and then I have to count carets in my head, when I don’t want to count, I just want the next patch in the sequence. (This is where I hope someone will leave a comment telling me how to do this while implying that I am a moron for not knowing already. Thanks in advance!) (Update: Yes, I know about the HEAD~5 syntax. No, it doesn’t do what I want, I want NEXT.)
While I’m at it, WTF is with git-checkout and git-branch? git-checkout deals with checking out files, except when it deals with branches, and git-branch doesn’t do everything you want to do with branches (in particular, checking them out). I still type “git-branch “, get an error, and just automatically retry with “git-checkout “, and vice versa.
After all this, I have to report that in general, using git still feels like wielding a 50-hp chain saw with no blade guard, except not as safe. And of course, this speaks for itself:
evilcat:~ val$ git-[TAB][TAB] Display all 137 possibilities? (y or n)