15 Seconds to a Cleaner Git History
This is a quick tutorial in using
git rebase to tidy up messy commits.
The Making of a Mess
Did you, in a fit of despair and/or pragmatism, make a bunch of messy, disorganized, or poorly described commits? Wish you knew enough git foo to clean up the mess before pushing to origin? You’re about to, and once you do, it’ll take all of 15 seconds to not leave a mess.
The Unmaking of a Mess
Let’s say you’ve made 5-10 crappy commits in a flurry of activity, and now you want to make ammends.
This command will launch your
$EDITOR with lines for each of the 10 most recent commits:
Here, we see each commit and its message prefixed with a command (all defaulted to
pick, which means keep this one as-is). At this point, we could save and exit, and git wouldn’t make any changes to our commit history, but that’s not why we’re here, so let’s do some cleanup:
Here, we’ve changed the command prefix for all but the last of the messy commits to
f, which is short for
fixup, and means merge this one into the previous, and discard its commit message. For the last of the messy commits, we use
r, short for
reword, which will cause the rebase process to halt and give us a chance to edit the message for that commit, which will then include all of the
fixup-marked commits below it.
So, go ahead and save/exit, and your
$EDITOR will open once again.
After writing your apologia, save/exit, and you should see
Successfully rebased and updated refs/heads/master. following some output indicating what kind of changes the rebase is making.
Rebase is neat, but it’s dangerous, because it rewrites commit history. If you rebase history that is already living upstream or on other developer’s machines, you’re headed into a world of pain.
Plain and simple, do not rebase commits that you’ve already pushed (unless you are the sole developer–in that case, rebase at will and use
git push -f).
There’s a lot implied by this little cleanup operation, namely the whole underworld of
rebase, which can be incredibly useful for resolving complex history problems. (If you’re not already, you should be using
git pull --rebase almost exlcusively in your daily workflow to avoid introducing unnecessary merge commits.)
In particular, we didn’t touch on the rest of the interactive rebase commands:
pick: take the commit as-is
reword: edit commit msg
edit: edit files
squash: merge into previous
fixup: merge into previous and discard commit
exec: run shell command
In practice, I’m not on a first-letter basis with any but
f, but who knows what you’ll find useful!
blog comments powered by Disqus