I have two branches A/B:
a
in branch A
B
, and merge A
a
(until now, B
doesn't have commit a
but A
does)A
, revert commit a
, but re-commit a
with git cherry-pick a
(now A
has commit a'
)B
, merge A
to B
again (the commit a
or a'
is lost)I think finally, branch B
will have the commit a
or a'
, but it lost. What's going on here?
I have checked the git docs, but it just mentions three way merge without any detail.
From https://git-scm.com/docs/git-merge#_description:
Then "
git merge topic
" will replay the changes made on thetopic
branch since it diverged frommaster
(i.e.,E
) until its current commit (C
) on top ofmaster
, and record the result in a new commit along with the names of the two parent commits and a log message from the user describing the changes. Before the operation,ORIG_HEAD
is set to the tip of the current branch (C
).
If it is an actual replay , the commit a
should be on branch B
.
You have this history:
--a--a_rev1--a' <-- branch A
\ \
----M--a_rev2--M' <-- branch B
You are observing that the changes of a'
(which are identical to a
) are missing from branch B.
This is expected and not an error.
When Git merges changes, it only considers the two project states at tips that are merge, a'
on branch A and a_rev2
on branch B, and the merge base, which is a
. From the point of view of branch B (the "merge target"), only the changes between the merge base a
and the other branch tip, a'
are considered and only those changes are integrated into the "merge target". Since a_rev1
and a'
are changes that cancel each other out, there are actually no changes to integrate, therefore, the merge M'
does not introduce any changes compared to the ancestor a_rev2
.
You can also read the story like this:
On branch A, the developer first said "I need to revert a
, so let's make a_rev1
!" But then later, they said "No, wait, I do need a
, so let's cherry-pick it, a'
!" The effect is that we do not need any change.
On branch B, the developer said "We definitely need to revert a
. Let's make a_rev2
.
The branches are now merged. One side said, that no changes are needed, but the other said that some changes, a_rev2
, are needed, so that is what remains.