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

git, git-merge

Solution

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.

Problem

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: 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`. 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.

Original source