Mojo
Mojo

Reputation: 1202

Git Merge Overwriting My Local Branch File Without Signalling Merge Conflict

I have a situation today where Git merge did not work properly for one file. This is what I did:

  1. I have a local branch which I did my work on
  2. Then master branch was updated with some other dude's work
  3. I do git checkout master and then git pull (to pull down all this changes into my local master branch)
  4. I then switch back to my local branch and do git pull origin master to pull down all master branch changes into my local branch.
  5. Out of the say 15 files, a few were merge conflicts. But one file where there is a merge conflict difference between master and my local branch was not registered as a merge conflict. Git just overwrote my local branch version of the file with the latest version from master branch.

did i do something wrong or is this a bug in git?

Upvotes: 1

Views: 87

Answers (1)

Mark Adelsberger
Mark Adelsberger

Reputation: 45649

EDIT - a couple of the possible explanations below were written as though the merge in question was from your branch to master; not sure how I got that turned around in my thinking, but I'm updating them to reflect that you were merging from master to your branch.


As noted in comments, we really need more information to definitively say what happened. I'll try to keep an eye on this and update with a better answer if we get more detail, but for now I'd say there are a few likely scenarios:

1) Maybe your changes did not conflict with master changes according to the diff algorithm, and so the file was silently replaced with a copy that contains the changes from master. But if that's so, then the file also contains the changes made on your branch. That would be a normal merge result (though, depending on the changes, it is possible for them to be logically inconsistent even though they are not in conflict - i.e. did not modify the same "hunk" of the file).

If you saw some of the changes from master and concluded it was the master copy, without also making sure it didn't have your changes, then this is the most likely situation. But if you did verify that your changes are not present, then it's something else.

This rarely presents a problem, because usually it is the desired behavior; logically-inconsistent changes to the same file - but that do not conflict - turn out to be quite rare in well-designed code.

2) The commit graph might not be what you assume. For example, at some point - after you'd modified that one file - someone might have merged your branch to master. Then they might have changed that one file in a way that included undoing your changes. Their changes would then supersede yours.

o - M -- D -- E <--(master)
 \ /           \
  A -- B -- C - M2 <--(branch)

For example in this diagram, if you branched from o and made changes to the one file at A, then changed other files at B and C on branch; but someone merged A back to master, then made changes at D and E which (perhaps among other things) undid your changes from A; then when you merge back to your branch (C) from master (E) creating M2, A would be considered the merge base; so changes from either branch would silently override them.

There are numerous variations on this, but analysis of the git history (git log etc.) could show exactly what happened, if it was anything of this sort.

While this can be annoying if the left hand doesn't know what the right hand is doing, it is again the desired behavior of a merge, as you otherwise couldn't reliably revert an errant change.

3) There could be a .gitattributes file affecting how the one file is merged. You only need worry about the details if you in fact find a .gitattributes file and it contains a path that would match the one file. It's relatively uncommon to see this, so I doubt it's the problem, but it could be.

4) Originally I noted another possibility related to (3) - perhaps git thinks that file is binary. I'm including a little info about that for completeness, but based on what you describe it shouldn't be the problem.

The normal line-oriented "apply both patches" method of merging would not work on a binary file, so git won't attempt it. It will instead place one version of the file in the work tree (the "ours" version). But, it will still mark the file as conflicting - so if you're sure that the file was never marked conflicting (as opposed to having been possibly added when you were adding other conflict resolutions and so no longer marked conflicting) then this isn't the problem.


But again, those are all just guesses that could produce behavior reasonably close to what you described. It could be something else entirely, that we can't think of without more detailed information.

Upvotes: 1

Related Questions