Casey W. Stark

Astrophysics, computation, and code

Git Workflow

| Comments

or “How I Learned to Stop Worrying and Love git rebase -i”.

I’ve been working with git in a more professional setting lately. We maintain our new cosmological code, Nyx, in git now and I can’t be as lazy as I have been with other git repos. We maintain 2 bare repos and about a dozen developers pull from us, so I like to be careful about what I push off.

Problem is, I don’t normally work that way. I like to code things quickly and try them, keeping track of changes as I go. Think “cowboy” development with very frequent commits. So, I could end up with a very messy commit history. Luckily, git rebase comes to the rescue.

So at the end of a bout of local coding, the commit history looks something like this.

… many commits down to …

For many reasons, I cannot rebase commits already pushed to a remote, so I need to update the remote tracking branch at this point. A simple git fetch origin master does the job. Now I can rebase off this commit and rewrite my messy history.

I find the tip of origin/master, copy the sha, and run git rebase -i [origin sha]. I think there is simpler way to do this, like git rebase -i origin/master, but I haven’t tried it. I like to be sure I’m rebasing off the right commit for now.

Now, my editor opens up and shows a list of the commits since then. For each commit, I have several choices. Here’s what git displays during a rebase:

# Rebase 3272740..9ef6432 onto 3272740
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

And here’s a snapshot of what I ended up with this time.

So I will squash 5 commits, reword 3 of the commit messages, and leave everything else as is.

After saving and closing the editor, git opens each commit I want to reword or squash while rebasing. I make the changes I want, and git finishes with “Successfully rebased and updated refs/heads/master”.

Now my commits show up as a single line of development off of the latest commit on origin/master.

Let’s just hope the non-sequential commit datetimes don’t confuse anyone.

Don’t forget to git push origin master after all that.

Comments