git merge after git cherry-pick: avoiding duplicate commits

Imagine we have the master branch and a branch b:

  o---X   <-- master
   \
    b1---b2---b3---b4   <-- b

Now we urgently need the commits b1 and b3 in master, but not the remaining commits in b. So what we do is checkout the master branch and cherry-pick commits b1 and b3:

$ git checkout master
$ git cherry-pick “b1’s SHA”
$ git cherry-pick “b3’s SHA”

The result would be:

  o---X---b1'---b3'   <-- master
   \
    b1---b2---b3---b4   <-- b

Let’s say we do another commit on master and we get:

  o---X---b1'---b3'---Y   <-- master
   \
    b1---b2---b3---b4   <-- b

If we would now merge branch b into master:

$ git merge b

We would get the following:

  o---X---b1'---b3'---Y--- M  <-- master
   \                     /
     b1----b2----b3----b4   <-- b

That means the changes introduced by b1 and b3 would appear twice in the history. To avoid that we can rebase instead of merge:

$ git rebase master b

Which would yield:

  o---X---b1'---b3'---Y   <-- master
                       \
                        b2---b4   <-- b

Finally:

$ git checkout master
$ git merge b

gives us:

  o---X---b1'---b3'---Y---b2---b4   <-- master, b

Reference: http://kerneltrap.org/mailarchive/git/2008/7/23/2648694

5 Responses to git merge after git cherry-pick: avoiding duplicate commits

  1. Mike says:

    Good old git.

    Thanks for writing this up; you saved me worrying about the result of just such a situation in a project.

  2. sukima says:

    I just got bit in the face with this problem. Thanks for providing an explanation for the duplicate commits.

  3. Sylvain says:

    Clear and concise, thank you!

  4. Rebase won’t work if ‘b’ is a branch pushed to origin or any other repository where you have co-workers collaborating. In this case you *have* to do a merge, and you have to find a way to make it work.

    Not sure what the problem is here, but merge should be smart enough to skip over cherry picked commits from the source branch.

  5. kolorafa says:

    “but merge should be smart enough”

    Nope, a lot of time you get duplicated content, for example in commit ‘b1’ you add one line, after merge you will have that line added 2 times. For me it ended in CSS rules duplication but that could end up lot worse.

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: