loading...

git deep dive part 7: Cherry-pick

kenakamu profile image Kenichiro Nakamura ・3 min read

In the previous article, I explain how to rebase. In this article, I explain how git cherry-pick works.

What is cherry pick

Merge and rebase takes entire changes from another branch into current branch. But I sometime need to pick up only a commit from another branch, not everything. In this case I can use cherry pick.

In this article, I just pickup the change in commit 367c2d0 into master.
Alt Text

Prepare the branch chain

Run the following command to make sure it becomes same as the diagram above.

git switch dev
git reset --hard 867d90c
git switch master
git reset --hard c36490a

Once all command completed, check the log.

gitDeepDive> git log --oneline --graph --all
* c36490a (HEAD -> master) update docs
| * 867d90c (dev) update hello.txt
| * 367c2d0 Update news
|/
* 2adbcac (test) Add doc folder and files
* 16f1fa8 commit hello.txt

Cherry pick a commit

It's super simple. Run the following command from master branch.

git cherry-pick 367c2d0

Depending on changes we may encounter conflict. This time, I see following conflict.

Auto-merging docs/news.txt
CONFLICT (content): Merge conflict in docs/news.txt
error: could not apply 367c2d0... Update news
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'

Resolve the conflict as usual with git mergetool.
Alt Text

So far, I issue --continue, but this time, let's see the status to understand current situation. It shows the current status and news.txt is ready to commit which I just resolved the conflict. I see .orig files which holds original contents. I don't need them so I just ignore it.

gitDeepDive> git status
On branch master
You are currently cherry-picking commit 367c2d0.
  (all conflicts fixed: run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Changes to be committed:
        modified:   docs/news.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        docs/news.txt.orig
        hello.txt.orig

Let's commit manually without using git cherry-pick --continue.

 git commit -m "cherry-pick 367c2d0"

Now I cannot run git cherry-pick --continue anymore.

gitDeepDive> git cherry-pick --continue
error: no cherry-pick or revert in progress
fatal: cherry-pick failed

But I still have untracked files.

gitDeepDive> git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        docs/news.txt.orig
        hello.txt.orig

Let's clean up untracked files with git clean

git clean -xf

Everything clean up now. Let's see the current log.

gitDeepDive> git log --oneline --graph --all
* 8618d72 (HEAD -> master) cherry-pick 367c2d0
* c36490a update docs
| * 867d90c (dev) update hello.txt
| * 367c2d0 Update news
|/
* 2adbcac (test) Add doc folder and files
* 16f1fa8 commit hello.txt

Alt Text

Summary

Cherry-pick is quite useful when I want to take just a part of branch commit tree. I will explain revert in the next article.

Go to next article

Discussion

pic
Editor guide