29

For example, I have a dev branch and a stable branch.

In case I have cherry-picked several commit from dev to stable.

Is there any way to let Git aware of the cherry-picked commits, and avoid doubly-merging it if I later merge, rebase or cherry-pick an overlapped range, from dev back to stable? (for which is a basic merge tracking feature in SVN)

Daniel Serodio
  • 4,229
  • 5
  • 37
  • 33
Adrian Shum
  • 38,812
  • 10
  • 83
  • 131

3 Answers3

15

Also notable is that -x flag for cherry-pick adds the SHA of the original commit to the end of the commit message.

I like to add the abbreviated SHA to the end of the commit summary, too, to make it easier to associate the cherry-picked commit with the original when looking at the log. Indicating who did the cherry pick can be helpful too, with the -s signoff flag.

Example:

> git cherry-pick -sex 27d4985

#333: fixes all the things (27d4985)

- how it fixes all the things

(cherry picked from commit 27d49855238364d0184ad344884a366b5b16e)

Signed-off-by: Chuck Norris <chuck@example.com>
Araxia
  • 1,136
  • 11
  • 22
12

git cherry-pick is a funny case of git rebase rather than git merge, so it actually rewrites the commit you cherry-picked so it will apply the same changes to the top of the branch you cherry-picked into. Since git's commit ids are based on the content of the commit, the new commit has a different id and is therefore considered an entirely different commit by git.

git merge, on the other hand, creates a merge commit; this is the means by which git implements merge tracking. A merge commit marks a point at which two (or more) divergent histories converged. It's acceptable to call git merge [commit-id] instead of git cherry-pick [commit-id] to explicitly create a merge commit, but this brings in not only the effects of the single cherry-picked commit but also the entire set of changes in that branch's divergent history.

With all that said, "double-merging" is not usually a problem in git. If you try to merge with a history that contains a changeset that's already present it'll just become a no-op when the histories are glued together; git really cares only about the state of the tree in each commit, not about the changes that got it into that state.

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138
  • 1
    Just to conclude: There is no way to track cherry-picked commits. However double-merging is usually not a problem in GIT, is that right? I feel a bit uncertain about the latter statement. I don't see anything special in GIT's design that makes double-merging less troublesome as other version control system (like, SVN) – Adrian Shum Sep 29 '10 at 09:41
  • @Adrian: Agree for double-mergin. There is a potential problem if between the two (identical) merges something changed in the merge target. – schoetbi Nov 22 '11 at 06:08
5

There is actually a command named git cherry that prints every commit that is not merged between two branches.

For each printed commit, the "+" sign means you can merge it, the "-" sign means you already cherry-pick that commit.

The output is far from being pretty.

For those who came from SVN and are used to svnmerge.py, I made a "svnmerge avail -l" equivalent bash script for git, that I called gitavail:

#!/bin/bash

# get current branch
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

# get tracked branch (1st argument), if no arg or arguments are only options, assume master
if test -z $1 || grep -q '^-' <<< $1;
then TRACKED_BRANCH=master
else TRACKED_BRANCH=$1; shift
fi

# Log commits available for merge from tracked branch
LOG_OPTIONS=$*
for i in $(git cherry $CURRENT_BRANCH $TRACKED_BRANCH | egrep '^\+' | awk '{print $2}'); do git --no-pager log -n1 $i ${LOG_OPTIONS}; echo; done

Assuming you are on a branch, and you want to list what is eligible to merge from master branch, just run:

gitavail --name-status

And you'll have an output very similar to "svnmerge avail -l".

I guess the cherry-pick commits must not be manually modified (what about conflicts?), if the patch id changes, git cherry won't realize the commit has already been cherry-picked.

Guillaume Perrot
  • 4,278
  • 3
  • 27
  • 37
  • Though I haven't had chance to try this out but seems that it does exactly what I want. :) +1 and accepted answer goes to you :) – Adrian Shum Sep 12 '13 at 06:27