Reputation: 285
Here is an example that explains the scenario that I'm facing - I have a feature branch Branch-A. It has got a commit SHA-1000.This is followed by multiple new commits.Now I create a new branch called Branch-B from Branch-A.
The commit SHA-1000 is reverted in Branch-A and In Branch-B new changes had been introduced.
Finally when the Branch-B is merged back with Branch-A, the code of SHA-1000 will not be there in the resultant code but I want it back.
I understand that I can always revert the commit with which I had removed the commit SHA-1000. But it not possible for me to anticipate such a scenario and keep tract of changes. So how is these kind of scenarios handled in software development ?
Upvotes: 0
Views: 224
Reputation: 488193
git merge
works by comparing the merge base to the two tip commits—that is, running two separate git diff
operations—and combining the changes.These are all you need to know to solve your problem.
1If you build a complex graph and make some bad decisions, sometimes there is more than one best common commit, in which case the merge base is the result of merging the merge bases, unless you choose -s resolve
as a merge strategy.
I have a feature branch Branch-A. It has got a commit SHA-1000.This is followed by multiple new commits.Now I create a new branch called Branch-B from Branch-A.
The commit SHA-1000 is reverted in Branch-A and In Branch-B new changes had been introduced.
Let's draw this:
...--o--∆--*--∇--o <-- branch-A
\
F--o--o--o <-- branch-B
where ∆
represents your "SHA-1000" commit.
... When the Branch-B is merged back with Branch-A, the code of SHA-1000 will not be there in the resultant code but I want it back.
This happens because the git diff
from commit *
to the tip of branch-A
says to include the change from ∇
(i.e., revert the "then-bad" commit) while the change from *
to the tip of branch-B
says nothing about those lines of those files.
I understand that I can always revert the commit with which I had removed the commit SHA-1000 [after merging]. But [I don't want to have to remember to do that].
What you need, then, is to update the merge base. If the merge base were commit ∇
or later, you could cherry-pick commit ∆
into your branch-B
:
...--o--∆--*--∇--o <-- branch-A
\
o--o--o--o--∆' <-- branch-B
Alas, no existing commit can be changed: commit F
, the first commit that's exclusively on branch-B
, always points to commit *
. So you have two options:
You can rebase branch-B
. Doing so means *copying every commit that's currently exclusively on branch-B
, starting with F
, to some new-and-improved commit. The "improvement" will be that the updated branch-B
begins at commit ∇
. This actually damages branch-B
, so you'd probably want to put commit ∆'
—the cherry-pick of commit ∆
—in right away. This might also have other drawbacks, e.g., picking up too many intermediate commits.
You can merge branch-A
, or any commit at or after commit ∇
, into branch-B
.
This has the advantage of not having to "rewrite history", with all that that entails. It otherwise has the same disadvantages: you might pick up too much work. But it's still a good option. Here's what that might look like:
...--o--∆--*-----------∇--o <-- branch-A
\ \
F--o--o--o--M--∆' <-- branch-B
You'd simply run:
git switch branch-B
git merge <hash of ∇>
[fix any conflicts if needed and commit]
git cherry-pick <hash of ∆>
Now the future merge base of the tip commits of branch-A
and branch-B
is commit ∇
. The diff from ∇
to tip-of-branch-A commit does not do anything to the lines affected by ∆
, while the diff from ∇
to the tip-of-branch-B commit puts back commit ∆
via the cherry-pick.
(You can rebase or merge further down the line on branch-A
if you like. Commit ∇
is necessary; any additional commits are optional.)
Again, that's all there is to know. You either rebase or merge so that the future merge base starts where you need it to. If that can't work because it brings in "too much" from branch-A
, you're stuck with having to remember to un-revert later, or reverting parts of branch-A
on branch-B
and then repeating this process in the other direction so that branch-A
will not lose its work.
The mechanics of doing this are a pain. The theory is simple though.
Upvotes: 1