If I fixed a bug in a file in branch branch_a
, which should be applied to all branches. Is there a way to apply the change to all branches without having to checkout the branches individually.
git commit -m 'commit msg' # on branch a
git checkout branch_b
git cherry-pick branch_a
git checkout branch_c
git cherry-pick branch_a
What i would like to have is a git commit --to-all-branches
which tries to propagate the changes to all branches if possible.
Edit
To clarify a bit my situation, I write code to for computational problems. Often I end up in the situation where it is unclear which approach is the best solve a given problem. So i create a branch. These branches tend to diverge and are more like forks. However to keep all the files in place I just use one git repository with multiple branches. In the situation of a bug relevant for all branches/forks I was looking for away to update all branches automatically.
No—or strictly speaking, "yes, but it's just as much work any other way". New commits are always added to "the current branch", even if that's a "detached HEAD". (Below, I'll show a way of doing this with the "detached HEAD" state, although if you're adding commits to existing branch-tips, that's more work than just checking them out.)
Assuming you have something like this:
and you have some fix
X
that must be applied on top ofC
,F
, andG
to give:(note that all 3
Xn
commits are different commits as they have different parents), then you must add "patch X" to commitC
, and then add "patch X" to commitF
, and then add "patch X" to commitG
.Note that there is no guarantee that, e.g., the change from
C
toX1
exactly matches the change fromF
toX2
here, either. You may construct any of the threeXn
commits first, in the usual way. Then (as in your question) you just move to the other branches andgit cherry-pick
to create (and possibly resolve conflicts in) the otherX
-es. But you need to be "on" those branches to add commits to them, so:Repeat for all branches to which the patch must be copied (and, if necessary, modified to fit that branch).
There are alternatives to doing this. For instance, suppose branch
br1
is actually OK, and what you've discovered is that commitE
is broken and needs to be fixed, affecting commitsF
andG
. Suppose further that either no one else has commitsF
andG
—or, you're willing to force those who do have those two commits, to do a bunch of work to recover from what you are about to do. In that case, you can check out commitD
and make a new commit,E'
, that comes off ofD
. Let's draw the starting point, leaving outA
throughC
. We'llgit checkout D
(by its SHA-1, or—equivalently with this graph—by usingbr2~2
to name it) to get a "detached HEAD" there:Now:
Once the commit finishes, we have this (still with the "detached
HEAD
):Now we can copy commit
F
toF'
:giving:
We're now ready to make
br2
refer to commitF'
:giving:
(This is the "or strictly speaking" part I wrote above: you can add commits to a repository, then move branch labels around so that they label the new commit chains, rather than their old ones. All added commits move
HEAD
: it's just that ifHEAD
is a reference to a branch, they also move the branch one step forward as you work. HavingHEAD
refer to a branch is the "normal" way of working, but you can fake it after-the-fact in "detached HEAD" mode withgit branch -f
. In this case, I'm doing that to build the newbr2
without using a branch name, then moving the branch name to the new chain of commits once it's ready.)Now we need to copy
G
toG'
, attachingG'
toE'
. Here are the steps:(this is what we did for copying
F
toF'
, more or less) giving:Once you're all done, you should probably
git checkout somebranch
to get back "on a branch", and away from this "detached HEAD" state.As noted in comments, needing to apply a patch as wide-spread-ly (is that a word?) as this suggests that maybe there's something wrong with the whole process. (But this is what fixing a "day zero bug" looks like when you have a bunch of different products that all share the code-base with the day-zero bug.)
This doesn't exist, because each merge can potentially result in separate conflicts that require user intervention. You would need to write a script to do what you want.