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:
A-B-C <-- br1
\
D F <-- br2
\ /
E
\
G <-- br3
and you have some fix X
that must be applied on top of C
, F
, and G
to give:
A-B-C-X1 <-- br1
\
D F-X2 <-- br2
\ /
E
\
G-X3 <-- br3
(note that all 3 Xn
commits are different commits as they have different parents), then you must add "patch X" to commit C
, and then add "patch X" to commit F
, and then add "patch X" to commit G
.
Note that there is no guarantee that, e.g., the change from C
to X1
exactly matches the change from F
to X2
here, either. You may construct any of the three Xn
commits first, in the usual way. Then (as in your question) you just move to the other branches and git cherry-pick
to create (and possibly resolve conflicts in) the other X
-es. But you need to be "on" those branches to add commits to them, so:
$ git checkout br1
... make fix, "git add", "git commit" to create X1
$ git checkout br2
Switched to branch 'br2'.
$ git cherry-pick br1 # take diff of `C`-vs-`X1`, apply to `F` to make `X2`
... etc
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 commit E
is broken and needs to be fixed, affecting commits F
and G
. Suppose further that either no one else has commits F
and G
—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 commit D
and make a new commit, E'
, that comes off of D
. Let's draw the starting point, leaving out A
through C
. We'll git checkout D
(by its SHA-1, or—equivalently with this graph—by using br2~2
to name it) to get a "detached HEAD" there:
D <-- HEAD
|
| F <-- br2
\ /
E
\
G <-- br3
Now:
$ git cherry-pick -n br2^ # make a copy of E but don't commit yet
# edit to fix it
$ git commit # make new commit E' that's fixed
Once the commit finishes, we have this (still with the "detached HEAD
):
E' <-- HEAD
/
|
|
D
|
| F <-- br2
\ /
E
\
G <-- br3
Now we can copy commit F
to F'
:
$ git cherry-pick br2
giving:
F' <-- HEAD
/
E'
/
|
|
D
|
| F <-- br2
\ /
E
\
G <-- br3
We're now ready to make br2
refer to commit F'
:
$ git branch -f br2 HEAD
giving:
F' <-- HEAD, br2
/
E'
/
|
|
D
|
| F [abandoned]
\ /
E
\
G <-- br3
(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 if HEAD
is a reference to a branch, they also move the branch one step forward as you work. Having HEAD
refer to a branch is the "normal" way of working, but you can fake it after-the-fact in "detached HEAD" mode with git branch -f
. In this case, I'm doing that to build the new br2
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
to G'
, attaching G'
to E'
. Here are the steps:
$ git checkout br2^ # get back on E' as a detached HEAD
[git says stuff here about moving the detached HEAD]
$ git cherry-pick br3 # copy commit G
$ git branch -f br3 HEAD # and move br3 label here
(this is what we did for copying F
to F'
, more or less) giving:
F' <-- br2
/
E'
/ \
| G' <-- HEAD, br3
|
D
|
| F [abandoned]
\ /
E
\
G [abandoned]
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.)