Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git strategy to backport bugfixes into older branches (cherry-pick vs. merge)

Tags:

We work as follows in our team:

  • we have only a master branch in our GitHub repo, it's not stable - thinks get pushed there each day; for stable releases we use tags (for development, we use private forks on GitHub)
  • we release a new minor version every 3 weeks, which contains bugfixes and new features (say 1.2.4, 1.2.5, 1.2.6...)
  • we also have to maintain each minor old version for a limited amount of time (few months), so when someone uses 1.2.4 while the newest version is 1.2.7, and they find a bug, they can request us to fix the bug on the branch they use. Then we release a patch version, 1.2.4A.
  • patches are rather exceptional. We usually do no more than 1-2 patches for the minor release. For most of the releases we don't do patches.

The question is, what's the best strategy to fix the bug on master and the old branch at the same time?

I can think of the two main strategies:

  1. Fix the bug on master, then checkout v1.2.4, then cherry-pick the appropriate commit (suppose the bugfix is one commit which always holds) and tag the resulting commit as v1.2.4A.

  2. Checkout v1.2.4, fix the bug and commit, tag the commit as v1.2.4A, and to incorporate it to master, do a merge.

I'm rather in favor of the first version (cherry-picking), but I would like to hear the other's comments about pros and cons.

Of course, things can get complicated when the commits in the middle introduce some major changes that can result in the fact that one can't create a commit which will work in both 1.2.4 and in master (for instance when some function name changed or more complicated things). But the more common situation is that the fix can be ported without problems.

Advantages of cherry-picking from master:

  • I think the history is more "eatable" with cherry-picking. Consider this:

    | <- bugfix done on master
    |
    |
    | <- v1.2.7
    ...
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |  - <- v.1.2.4A (cherry-picked from master)
    | / 
    | <- v1.2.4
    

    vs this:

    | <- bugfix merged to master
    |\ 
    | \
    |  |
    |  |   <- v1.2.7
    ...
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  |
    |  - <- v.1.2.4A (direct bugfix)
    | / 
    | <- v1.2.4
    

    Think of having dozens of commits in between. Consider having multiple patches applied like this in parallel. Half of the screen will be polluted.

  • Let's say I fixed an issue on v1.2.4, but in a few days someone asks me for a patch on v1.2.3. Cherry-pick is the most sensible way to do it.

Are there any advantages of merging in our case that I overlooked? I can understand it preserves the connection between the two commits better than cherry-picking, but we keep a documentation of releases and all of this is also tracked there.

like image 278
jakub.g Avatar asked Nov 07 '12 17:11

jakub.g


People also ask

What is the difference between cherry pick and merge?

With the cherry-pick command, Git lets you incorporate selected individual commits from any branch into your current Git HEAD branch. When performing a git merge or git rebase , all the commits from a branch are combined. The cherry-pick command allows you to select individual commits for integration.

Should you cherry pick Git?

git cherry-pick is a useful tool but not always a best practice. Cherry picking can cause duplicate commits and many scenarios where cherry picking would work, traditional merges are preferred instead. With that said git cherry-pick is a handy tool for a few scenarios...

How do you cherry pick a merged pull request?

You can cherry-pick merge requests from the same project, or forks of the same project, from the GitLab user interface: In the merge request's secondary menu, select Commits to display the commit details page. Select the Options dropdown and select Cherry-pick to show the cherry-pick modal.


1 Answers

In open source projects that I've worked on, the consensus seems to be that fixes should land on master first, be tested there, and only then be back-ported to older releases. You can see this in how the Linux kernel does stable releases, for example: Developers submit patches for mainline but nominate them for inclusion in stable as well.

When cherry-picking in this situation, you probably want to use the -x flag:

When recording the commit, append a line that says "(cherry picked from commit ...)" to the original commit message in order to indicate which commit this change was cherry-picked from. This is done only for cherry picks without conflicts. ... [If] you are cherry-picking between two publicly visible branches (e.g. backporting a fix to a maintenance branch for an older release from a development branch), adding this information can be useful.

like image 111
Jamey Sharp Avatar answered Sep 18 '22 03:09

Jamey Sharp