The
Branch B:
And commit history:
CodePudding user response:
This solution needs the merger to be informed and seems to not be feasible.
- Revert the commit on A.
- Do your commit on B, as you would have liked in the first place.
- Merge normally (or let the merge be done by that other person)
I'd think that merge should be able to handle that situation, with the result of A not containing the commit, but B containing the commit.
I know that branch A will be soon merged to B and I want to only
revert the commit on A and apply the commit on B.
That sounds exactly like what I suggest. Revert on A, commit on B. Merge normally, it will be auto-merged resulting in B keeping the change or it will require manual conflict resolution.
CodePudding user response:
There is no magic whereby changes can be removed, merged somewhere else and then appear, accepting this should help understanding the steps required to achieve the desired end state.
Consider the following simplified history, which matches the scenario described in the question:
$ git log --all --decorate --oneline --graph
* 9eb80d9 (b) Some change added to b only
| * c297cb5 (a) Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit
First, clean up
I made a commit on invalid branch A, which was supposed to be made on branch B
The following actions will clean up the current situation:
$ git switch a
$ git revert HEAD # Revert the mistake
[a 92f9287] Revert "Should be on b, but not a"
At this time the effects of 'Should be on b, but not a' are negated on a
and not present on b
.
Second, establish a common history
Avoiding merge problems is all about establishing a common commit history - here that means cherry-picking the problematic commit to b
and reverting it:
$ git switch b
$ git cherry-pick 9eb80d9 # Reapply the mistake
$ git revert HEAD # AND revert it
That results in:
$ git log --all --decorate --oneline --graph
* 8d7c582 (b) Revert "Should be on b, but not a" # Fixing Mistake
* ecf8f7c Should be on b, but not a # Fixing Mistake
* 9eb80d9 Some change added to b only
| * 3339ef1 (a) Revert "Should be on b, but not a" # Clean up
| * c297cb5 Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit
At this time the effects of 'Should be on b, but not a' are negated in both branches.
Third, make the change in the right place
So we have a clean slate, all that's necessary now is to reapply the commit to the correct branch:
$ git switch b
$ git revert HEAD
Resulting in:
$ git log --all --decorate --oneline --graph
* fb744c1 (b) Revert "Revert "Should be on b, but not a"" # Re-apply
* 8d7c582 Revert "Should be on b, but not a" # Fixing Mistake
* ecf8f7c Should be on b, but not a # Fixing Mistake
* 9eb80d9 Some change added to b only
| * 3339ef1 (a) Revert "Should be on b, but not a" # Clean Up
| * c297cb5 Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit
At this time the effects of 'Should be on b, but not a' are only on branch b
.
Note: The commit reapplying the change doesn't have to be a revert, could equally be a normal commit.
No merge problems now
Branch B will be at some point merged to A
That's no problem now:
$ git switch a
$ git merge b
Merge made by the 'recursive' strategy.
With the commits/reverts as described that will apply cleanly resulting in:
$ git log --all --decorate --oneline --graph
* bf1ff12 (a) Merge branch 'b' into a
|\
| * fb744c1 (b) Revert "Revert "Should be on b, but not a""
| * 8d7c582 Revert "Should be on b, but not a"
| * ecf8f7c Should be on b, but not a
| * 9eb80d9 Some change added to b only
* | 3339ef1 Revert "Should be on b, but not a"
* | c297cb5 Should be on b, but not a
|/
* 3c5caf4 (main) Initial commit
Now the effects of 'Should be on b, but not a' are on branch a
and b
.