Git – branch merging commands, cherry-picking

Covered in this article:

  • Git cherry-picking commits from another branch
  • Visualizing commits

Cherry-picking commits from another branch

Let’s say we have two branches: master and feature1, and we don’t want to merge all the feature1 commits to master, but rather cherry-pick only some of the commits.
In our case, we want the second recent one – 8ef7c70

| * f7ce3bf (feature1) add feature1 line to f2 - not for merging
| * 8ef7c70 add feature1 line to f1
|/
* 98df444 (origin/master, origin/HEAD) add file f2
* 08e8f59 add line 2
* e46130a initial commit

So we run this command: git cherry-pick

$ git cherry-pick 8ef7c70
[master ccbbcef] add feature1 line to f1
 1 file changed, 1 insertion(+)

If cherry-picking causes no conflict we get a straight commit and our working tree is clean

/repo1 (master)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
nothing to commit, working tree clean

Here’s the graph of the commits

/repo1 (master)
$ git log --oneline --all --graph
* ccbbcef (HEAD -> master) add feature1 line to f1
| * f7ce3bf (feature1) add feature1 line to f2 - not for merging
| * 8ef7c70 add feature1 line to f1
|/
* 98df444 (origin/master, origin/HEAD) add file f2
* 08e8f59 add line 2
* e46130a initial commit

Git – branch merging commands, scenario two – cherry-picking a conflicting edit?

What happens when we are trying to cherry-pick a conflicting edit?

/repo1 (master)
$ git commit -am "master changes to line 1 in f1"
[master 9c759aa] master changes to line 1 in f1
 1 file changed, 1 insertion(+), 1 deletion(-)

We’ll edit f1.txt on feature1 branch (f8d4b9a) and then the same line in the same file on master branch (9c759aa)

/repo1 (master)
$ git log --oneline --all --graph
* 9c759aa (HEAD -> master) master changes to line 1 in f1
* ccbbcef add feature1 line to f1
| * f8d4b9a (feature1) add feature1 line to f1 - line 1 for a conflict
| * f7ce3bf add feature1 line to f2 - not for merging
| * 8ef7c70 add feature1 line to f1
|/
* 98df444 (origin/master, origin/HEAD) add file f2
* 08e8f59 add line 2
* e46130a initial commit

Cherry-pick command fails and we will need to solve the conflict manually

/repo1 (master)
$ git cherry-pick f8d4b9a
error: could not apply f8d4b9a... add feature1 line to f2 - line 1 for a conflict
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

Note that Git is telling you that you are still in CHERRY-PICKING mode, on master branch

/repo1 (master|CHERRY-PICKING)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

You are currently cherry-picking commit f8d4b9a.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   f1.txt

Now we open f1.txt on master branch, edit the lines we need and save. After resolving the conflict, we mark the corrected file with ‘git add ‘

/repo1 (master|CHERRY-PICKING)
$ git add f1.txt

And then we commit the resolved change in f1.txt

/repo1 (master|CHERRY-PICKING)
$ git commit -m "resolved cherry-picking conflict in f1"
[master 7cea11c] resolved cherry-picking conflict in f1
 1 file changed, 1 insertion(+), 1 deletion(-)

And this is our new commit log on master, with the feature commit cherry-picked

/repo1 (master)
$ git log --oneline --all --graph
* 7cea11c (HEAD -> master) resolved cherry-picking conflict in f1
* 9c759aa master changes to line 1 in f1
* ccbbcef add feature1 line to f1
| * f8d4b9a (feature1) add feature1 line to f2 - line 1 for a conflict
| * f7ce3bf add feature1 line to f2 - not for merging
| * 8ef7c70 add feature1 line to f1
|/
* 98df444 (origin/master, origin/HEAD) add file f2
* 08e8f59 add line 2
* e46130a initial commit