I've been reading about git merge -s ours
strategy for a few hours. All resources I've found state that it tricks Git into ignoring commits that happened before the "fake" merge that is made using -s ours
strategy and I can't understand why:
Suppose I have the following git history, with master
and feature
branches that have lots of diff between them:
(A)------(B)-------(C)------(D) <---[master] <---[HEAD]
\
\
(E)------(F)------(G) <---[feature]
Now I run git merge -s ours feature
, and the result is commit H
:
(A)------(B)-------(C)------(D)--(H) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G) <-- [feature]
Then I make more commits on both branches:
(A)------(B)-------(C)------(D)--(H)------(K)------(L) <---[master] <---[HEAD]
\ /
\ /
(E)------(F)--------------(G)------(I)------------(J) <-- [feature]
And then, while on master
I run git merge feature
Correct me if I'm wrong, at that point Git will:
G
as the merge-base
G
and L
G
and J
G
, say G'
and apply the above 2 diffs to commit G'
L
and J
the parents of G'
Here's what I don't understand: According to the docs the changes from commits E
and F
won't affect the merge, but the diff between G
and L
will still reflect the changes made in commits E
and F
because G
was "born" from them, so how is it possible that the changes in these commits will not affect the merge simply because ours
strategy was used ?
In a more extreme case, if these branches diverged more wildly and there are, say, 100 files in feature
branch (that were introduced before G
) and that are not in master
, then won't they still appear in the diff between G
and L
during the last merge ? **Edit: I can't see why they won't appear in the diff
No, the diff between G
and L
does not reflect the changes from E
and F
. If I
introduced a change, it will show up in the diff, but previous changes are not contained in the diff.
As you wrote: G
is detected as the merge base and everything else is computed from there.
Perhaps the following helps:
E
adds a file e
F
adds a file f
G
contains both files e
and f
.H
contains an identical tree to D
I
adds a file i
G
and I
only contains the change after G
, i.e. the new file i
. Since neither file e
nor f
were changed afterwards, they will not show up in the diff. As far as Git is concerned, those changes were already merged (but "resolved" as to not show up in the final result, only "our" tree is part of the result).From Git's point of view, changes before G
get reverted when merging with strategy ours
. You can confirm this by diffing the two commits: git diff G H
will show you exactly the inverse changes from E
and F
(or A..G
if you will).