DEV Community

Cover image for Mastering Git Cherry-Pick: Advanced Guide with Real-World Examples
Dennis Lemm
Dennis Lemm

Posted on

Mastering Git Cherry-Pick: Advanced Guide with Real-World Examples

What I love about being a web developer is that you never know what challenges the day might bring. Today, I encountered a problem that was fairly new to me. On a large project with many developers working on the same codebase, we needed to ship a specific feature. But we hadn't released in two weeks, and many changes were queued for deployment to production, though they hadn't been fully tested yet. So, what could we do? Enter git cherry-pick for the rescue.

The git cherry-pick command provides a precise solution, allowing developers to extract and apply only the necessary commits without merging untested changes. In this article, we'll explore git cherry-pick in detail, covering its applications, best practices, advanced strategies, and key parameters with practical examples for advanced users.


TL;DR

The git cherry-pick command allows developers to selectively apply specific commits from one branch to another without merging all changes. This guide covers:

  • How to use git cherry-pick: Step-by-step examples on applying individual commits, resolving conflicts, and managing multiple commits.
  • Key parameters: Using --no-commit, -x, and handling conflicts with --continue, --abort, and --skip.
  • Related Git commands: Comparisons with git merge, git rebase, git revert, and git reset.
  • Best practices: Ideal use cases for hotfixes and selective commits, along with situations where cherry-picking should be avoided.

For developers dealing with large-scale projects or urgent fixes, it cherry-pick is a powerful tool for keeping your workflow clean and efficient.


What Is Git Cherry-Pick? A Deep Dive

The git cherry-pick command lets you select and apply changes from a specific commit in one branch to another. Unlike git merge or git rebase, git cherry-pick applies only targeted commits, helping maintain a clean and focused repository history.

Like in my situation where I had made some changes that needs to be shipped but team mates made a lot of changes to the develop branch as well. So we needed one feature, but we didn't want to incorporate unrelated changes from the other teams. Instead of shipping the whole branch, we created a hot fix branch and used git cherry-pick to extract just the needed commits.


Real-Life Application of Git Cherry-Pick

Let's walk through what we did to ship the feature to production - a practical example to understand how git cherry-pick works:

Scenario

As mentioned above, imagine you're developing a new feature that got merged into the main branch that is waiting to be deployed to production. Other teams are developing into this branch as well. For example improvements for other parts of the code base. Due to some delays in the testing workflow you got stuck but you need to deploy this one feature or perhaps a critical bug fix.

Steps to Cherry-Pick

1) Switch to the branch with the commit
First, switch to, in this case, main branch to locate the commit you need:

git checkout main
Enter fullscreen mode Exit fullscreen mode

2) List recent commits to identify the one you need
Run the following command to see a log of recent commits:

git log --oneline
Enter fullscreen mode Exit fullscreen mode

3) Switch back to the target branch
After identifying the relevant commit hash, switch back to your hot-fix-branch:

git checkout hot-fix
Enter fullscreen mode Exit fullscreen mode

4) Apply the commit using cherry-pick
Use git cherry-pick followed by the commit hash to bring in just that needed change:

git cherry-pick <commit-hash>
Enter fullscreen mode Exit fullscreen mode

Explanation: This applies only the specified commit to your current branch without pulling in other changes from main. Git applies the diff from that specific commit, preserving the commit history only for that change.


Handling More Complex Projects

In larger projects, where multiple developers contribute to different branches simultaneously, cherry-picking becomes particularly useful for handling emergency fixes. 

Cherry-Picking Across Forked Repositories

When working with forked repositories, you may find yourself cherry-picking changes from the upstream repository into your fork. This allows you to pull in specific commits from the parent project while avoiding conflicts with your own local work.

For example, you might cherry-pick a security patch from the upstream repo:

git fetch upstream
git cherry-pick <commit-hash>
Enter fullscreen mode Exit fullscreen mode

Explanation: This command fetches the latest changes from the upstream repository and applies only the selected commit to your local branch. It's especially useful when contributing to open-source projects where you need to stay updated with upstream changes without merging everything.


How to Find the Right Commits with Git Log

A critical part of using git cherry-pick effectively is identifying the correct commits. Here are some tips for filtering and selecting relevant changes:

View Recent Commits

To list recent commits, you can use this command to view commits from the past two weeks:

git log --since="2 weeks ago"
Enter fullscreen mode Exit fullscreen mode

You can adjust the --since parameter to narrow or expand the timeframe.

Filter by Author

To search for commits made by a specific author:

git log --author="Author Name"
Enter fullscreen mode Exit fullscreen mode

This helped me a lot, because I know that only my changes had to be cherry-picked to the hot-fix-branch.

Cherry-Picking Multiple Commits

Once you've identified the commits, you also can cherry-pick multiple commits at once:

git cherry-pick <commit-hash1> <commit-hash2>
Enter fullscreen mode Exit fullscreen mode

This command applies multiple targeted changes to your branch.

Cherry-Picking a Range of Commits

To cherry-pick a range of commits by specifying their hashes:

git cherry-pick <commit-hash1>^..<commit-hash3>
Enter fullscreen mode Exit fullscreen mode

This will apply all commits between commit-hash1 and commit-hash3.


Advanced Git Cherry-Pick Parameters

git cherry-pick offers several advanced options to tailor its behavior to your needs:

  • -n or --no-commit: Applies the changes without committing them. This lets you make further modifications or combine multiple cherry-picked commits before committing.
git cherry-pick -n <commit-hash>
Enter fullscreen mode Exit fullscreen mode
  • -x: Adds a reference to the original commit in the new commit message, which is helpful for tracking the lineage of changes across branches.
git cherry-pick -x <commit-hash>
Enter fullscreen mode Exit fullscreen mode
  • --continue: If you encounter a conflict and resolve it manually, use this command to continue the cherry-pick operation after resolving the conflicts.
git cherry-pick --continue
Enter fullscreen mode Exit fullscreen mode
  • --abort: Cancels the cherry-pick operation and discards any changes applied so far, which is especially useful if the conflicts become too difficult to resolve.
git cherry-pick --abort
Enter fullscreen mode Exit fullscreen mode
  • --skip: If a conflict arises and you want to skip the conflicting commit, use this option to bypass the commit and continue the cherry-pick process.
git cherry-pick --skip
Enter fullscreen mode Exit fullscreen mode

Related Git Commands and When to Use Them

While git cherry-pick is great for selective commit application, it's important to understand how it compares to other Git commands:

  • git merge: Use this to combine branches entirely. It's better for large-scale integrations but brings in all changes from one branch into another.
  • git rebase: Allows you to rewrite the commit history by applying changes on top of another branch. This is useful when you want to maintain a linear history.
  • git revert: Unlike git cherry-pick, this undoes a specific commit by creating a new commit that reverses the changes.
  • git reset: Resets your branch to a previous state. Use this if you need to discard commits altogether, which differs from cherry-picking's selective nature.

Practical Considerations for Cherry-Picking

Handling Conflicts:
Conflicts often arise if both branches modify the same line of code differently. When this happens, Git halts the cherry-pick process and prompts you to resolve the conflict. Once you've resolved it, continue with:

git cherry-pick --continue
Enter fullscreen mode Exit fullscreen mode

If the conflicts are too complex to resolve, you can cancel the entire operation using:

git cherry-pick --abort
Enter fullscreen mode Exit fullscreen mode

When Not to Cherry-Pick:
Cherry-picking should be used carefully. Overuse can lead to a fragmented commit history, especially if multiple developers cherry-pick the same commits into different branches. In some cases, git merge or git rebase may offer a cleaner solution for integrating changes across branches.


Best Scenarios for Cherry-Pick Usage

Ideal Use Cases:
Applying hotfixes across multiple branches when only specific changes are required.
Extracting particular commits from a feature branch without merging the entire set of changes.

When to Avoid Cherry-Picking:
For large-scale integrations, git merge or git rebase often provide a more consistent approach.
When branches have diverged significantly, cherry-picking can lead to complex conflicts and inconsistencies.


Leveraging Git Cherry-Pick in Collaborative Environments

In team environments, communication is key when cherry-picking commits. Ensure team members are aware of which commits have been cherry-picked and why. If multiple branches need the same fix, consider creating a shared branch for merging, which reduces redundancy and ensures consistency across the team's work.


Conclusion

git cherry-pick is a powerful tool for selectively applying changes without merging entire branches. When used carefully, it keeps workflows streamlined and project histories clean. However, be mindful of when and how you use it to avoid introducing unnecessary complexity.

Have you used git cherry-pick in your projects? I'd love to hear about your experience! What challenges or successes have you encountered when using it? Additionally, if you're interested in more articles on advanced Git commands, let me know-perhaps a series is in order!

Top comments (0)