1

I have two local branches, say A and B. I run the following commands

  1. git checkout A
  2. git merge -X theirs B - "comment"

if i run again the command
git merge B --> it throws the message "Already up to date"

if i run the follow command git diff A..B --> it returns differences in 4 files

So I "smash" the content of branch A with the content of branch B if i run again the merge command on branch A it returns that everything is up to date but if i run the "diff" between the two branches it return differences in four files.

What is happening ?

Thanks in advance.
Best regards

tt0686
  • 1,681
  • 5
  • 27
  • 52

1 Answers1

2

Things to know:

  • Git traffics in commits.

  • Every commit has at least one parent, and "reaches" other commits by means of its chain of parents.

  • A branch is a name for one commit.

  • Merging creates a commit and moves the branch name of the current branch.

  • The phrase "up to date" means that one branch doesn't reach any commits that the other branch doesn't reach.

So let's say we start with this situation (arrow point backwards in time, each commit pointing at its parent):

A <-- B <-- C <-- D (branch1)
 ↖︎
   <-- X <-- Y <-- Z (branch2)

Now I checkout branch1 and say git merge branch2. I get this:

A <-- B <-- C <-- D <-- M (branch1)
 ↖︎                    ↙︎
   <-- X <-- Y <-- Z (branch2)

So now, on the one hand, there is no point trying to merge branch2 into branch1 again; branch1 already reaches all the same commits that branch2 reaches. Hence, "up to date". But commit M and commit Z are not identical to one another either.


Perhaps your confusion is because you think

git merge -X theirs B

does something special with regard to a merge. It doesn't. This is still a perfectly ordinary merge. The only thing it does specially is in case there happen to be any merge conflicts; the theirs provides a hint about how to resolve those conflicts without asking for human help.

matt
  • 485,702
  • 82
  • 818
  • 1,064
  • 1
    An important note about `-X` [highlighted on the manual page](https://git-scm.com/docs/git-merge#_merge_strategies) is that it doesn't select a merge *strategy*, it selects an *option for the selected strategy*. So on its own, `-X theirs` uses the "recursive" strategy with the "theirs" option, which as you say controls how conflicts are resolved. Their is also an "ours" *strategy* (`-s ours`), which marks everything as merged without pulling in any changes from the other branch (there's no "theirs" strategy, though). – IMSoP Oct 12 '21 at 14:39
  • Yes, I purposely omitted the `ours` strategy. It isn't really relevant, because it wouldn't make `M` identical to `Z` either. – matt Oct 12 '21 at 14:41
  • It could be used to create a tree where M and Z were the same, I think, by making the merge on branch2 and then swapping the pointers around. Something like `git switch branch2; git merge -s ours branch1; git branch temp; git reset --hard HEAD^; git switch branch1; git reset --hard temp; git branch -d temp` At the end, branch1 would have the content of branch2 (commit Z), but an extra parent of commit D. – IMSoP Oct 12 '21 at 14:45
  • Thanks for the fast answer , i open one of the files that the diff says it is different and there are really different , how can i "smash" the version of A with the version in B ?what i want to do is to "smash" all the content in branch A with the content in branch B, like a "replace" ? Thanks in advance – tt0686 Oct 12 '21 at 14:57
  • Ok but that is _not what you asked_. I have tried to answer the question you asked. If you have a different "how to" question, perhaps you could ask it as a new question. Though I think an earlier comment does answer that. – matt Oct 12 '21 at 14:58
  • Or if you don't care about the loss of history, don't merge; just replace one branch with the other. – matt Oct 12 '21 at 15:04