46

So, I have a maintenance branch and a master branch in my project. If I make a commit in the maintenance branch and want to merge it forward to the master branch, that's easy:

git checkout master; git merge maintenance

But if I want to go the other way around, i.e. apply a commit made to master back to my maintenance branch, how do I do that? Is this considered cherry-picking? Will it cause problems or conflicts if I merge the maintenance branch forward again?

Christian Oudard
  • 48,140
  • 25
  • 66
  • 69
  • As others have already stated, cherry-picking is probably the best option. I just wanted to add that conflicts during cherry-picking can often be resolved by examining the "dependencies" of the commit you are cherry-picking, and that I have built [a tool called `git-deps`](https://github.com/aspiers/git-deps) to detect and visualize those dependencies. If you visit the home page you will see two YouTube videos: the first gives a general introduction to the tool, and the second demonstrates how it can be used to avoid conflicts when cherry-picking. – Adam Spiers Feb 25 '15 at 19:31

5 Answers5

47

This is exactly the use case for git-cherry-pick

git checkout maintenance
git cherry-pick <commit from master>
mwalling
  • 1,745
  • 1
  • 19
  • 26
  • 1
    When cherry-picking between two public branches it's useful to use the -x switch that appends "(cherry picked from commit …​)" line to cherry picks without conflicts. https://git-scm.com/docs/git-cherry-pick#git-cherry-pick--x – user3601487 Jun 06 '18 at 21:31
  • To be fair to my self from 13 years ago, `-x` was the default until [v1.4.3](https://github.com/git/git/commit/abd6970acad5d758f48c13f7420367ae8216038e), and I don't remember the distros being super eager to rev the packaged version. – mwalling Sep 01 '22 at 13:53
24

Alternate solution to using "git cherry-pick" (as recommended in other responses) would be to create a separate [topic] branch for the fix off maintenance branch, and merge this branch first into maintenance branch, then into master branch (trunk).

This workflow is (somewhat) described in Resolving conflicts/dependencies between topic branches early blog post by Junio C Hamano, git maintainer.

Cherry-picking results in duplicated commit, which down the line may cause problems when merging or rebasing. Topic-branch based workflow keeps only one copy of the fix.

Jakub Narębski
  • 309,089
  • 65
  • 217
  • 230
  • I like how the linked post explains adding multiple commits that may conflict. Merge feature A with Bug fix B together, prior to merging either of them into the Master or Maintenance branch. This way you can make sure that conflicts between A and B are resolved, so that if you pull either A or B first, then you can easily pull in the merge of A+B afterwards and know it is pre-merged for you. See [diagram 3 in linked document](http://gitster.livejournal.com/27297.html). – 700 Software Jul 05 '16 at 18:25
  • Interesting! Could you add the commit history in ASCII art to clarify your answer? Also, why does the merge order of the topic branch matter (first into the maintenance branch, then into the main branch)? And why doesn’t the merge of the topic branch into the main branch create a conflict, since the topic branch was branched off the maintenance branch which is by definition long-lived, i.e. never supposed to be merged back into the main branch (to me it would be like merging the branch `3.6` back into the branch `main` in the [GitHub repository of CPython](https://github.com/python/cpython)). – Géry Ogam Oct 11 '21 at 09:35
1

For complex commits that cannot be applied using git cherry-pick you can try

git checkout -b merge-branch master
git rebase --onto=`git merge-base master maintenance` HEAD~1 && git rebase master

Explained: http://blog.boombatower.com/automatically-backport-commits-using-git.

boombatower
  • 651
  • 4
  • 6
0

Yes, it is considered cherry-picking and no, generally it should not introduce problems. If commit doesn't apply cleanly when backporting you may face exactly same conflict when cherry-picking it back.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
0

As a general rule, I use merge to move changes "up" the tree (from maintenance to master) and rebase to move them "down" the tree (from master to maintenance). This is so the order of commits in the master branch is maintained.

Rebase essentially rolls back all your changes on the current branch to the fork (or last rebase), copies over newer changes and then re-applies your changes.

If you don't want to get all changes from the master, then you will probably need to cherry pick the ones you want.

Brenton Alker
  • 8,947
  • 3
  • 36
  • 37
  • 3
    I wondered about *rebase* too. But presuming a _maintenance_ branch exists specifically to _not_ have all the current changes then that isn't what you want. It seems best to me to rebase a development branch, but cherry-pick a bug fix made in master (or any upstream development branch) back to maintenance. – Alex Stoddard Sep 17 '09 at 17:42