Skip to content

Things your mum didn’t tell you about git

October 30, 2011

The other week we had a rather painful experience with git. My team is currently in the unfortunate position of having to maintain two long running branches. This is not a great idea in general but in our case we don’t have a lot of choice. Our merges have generally been somewhat painful so we resolved to perform them more often. The idea being we break the pain down into smaller more manageable hurts. Last week it was my turn, so I set about merging the code from the branch into master. After running the merge I noticed a lot of conflicts. At the time I thought this was strange considering it wasn’t that long ago that we’d run the previous commit. I fired up merge tool anyway and set about resolving the conflicts then started noticing in conflicts in stuff that should definitely not have been conflicting. At that point I stopped and looked back at the git log to try and see if I could figure out what was going on.

What I found was somewhat disturbing. The last two merges didn’t look like merges at all. A normal merge will have two (or more!) parents (unless git fast forwarded it – a feature which you can turn off on the command line). The last two merges only had a single parent and it looked more like they’d been rebased. I couldn’t understand this because I knew for a fact that the last people to merge into the tree had definitely performed a merge and not a rebase. I did a lot of hunting around at this point to try and figure a way out of this mess and to understand why this had occurred when seemingly we’d done the right things.

Since I had an upcoming release to prepare I didn’t have much time to look into this further so Lee took over and started investigating. After a lot of hunting around he came across a blog post which exactly describes the situation we found ourselves in. What happened was this:

  • Person A starts a merge.
  • Person B commits into the branch you’re merging into.
  • Person A finishes the merge then tries to push it. This fails because the merge is now out-of-date.
  • Person A runs ‘git pull –rebase’ so that he/she can commit the merge.

What Person A has not realised at this point is that the rebase has just trashed the merge commit. In our case we’d done this twice without realising the complete mess we’d just made to our history.

Turns out that if this happens you have to start your merge over from scratch or use an option on the git rebase command called –preserve-merges. This option doesn’t exist in the git pull command so you’ll need issue separate fetch and rebase commands. See the original article for more detail about this.

In the end to clean up we had to abandon the current merge, revert the previous merge mess then rerun the merge. Finally we’re back to a sane(ish) commit history.

Advertisements

From → Technical

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: