1

Like most, I am using git on a multi-project development with many developers and many changes being propagated to the main branches daily. Many times, when I merge a parent branch into a feature (or bug fix) branch, I get conflicts on several files I did not touch or even look at!

Background

Branch setup:

git checkout master
git checkout -b myFeatureBranch

Let's say two or more days go by. My feature code is now ready for review. Note: I am using master here only for clarity, in reality, it is another uniquely named release branch. Many other developer merge THEIR bug fixes and feature branches into master (after their code reviews are approved!). These changes may have impacted one or more of the files I changed in my feature branch. Thus, I need to merge master into my branch to get all the latest code.

My Question

I did not find an answer to this specific question. I looked at this question which also pointed to this question. Following that information there, if I need to merge master into my feature branch, then following that logic, I would do:

git checkout myFeatureBranch
git merge -X theirs master

I believe (from man page) that:

This option forces conflicting hunks to be auto-resolved cleanly by 
favoring `their` version.

But this isn't really what anyone wants is it?

If the file is untouched by me in my branch, then yes this is exactly what I want; however, if I modified a file (and committed to my branch), then I want the normal merge (and conflict resolution) process to be done. I don't want to favor theirs in this case. Does the above do that? If not, is there a single merge command to do so?

JoeG
  • 6,138
  • 7
  • 52
  • 97
  • For a conflict don't both copies have to have been edited, if only one has changes from a common ancestor there shouldn't be a conflict, is that what you are experiencing? – jrtapsell Sep 13 '17 at 12:00
  • "I get conflicts on several files I did not touch or even look at" - this means that the files are somehow touched anyway. If files are actually not modified they would not conflict. – max630 Sep 13 '17 at 12:45
  • [This answer](https://stackoverflow.com/a/18262173/2303202) should help to find out what was the local change in the files you did not intend to change. – max630 Sep 13 '17 at 12:47
  • Folks, I do a "git status" before merges. NONE of the files I get conflicts on show up. We use gradle for our builds. Today's merge had a conflict on gradle.properties. I did NOT touch, alter, or look at that file in my branch. I have git setup for fast-forward and recursive merges. Maybe something in my setup is messed up, but the files marked as conflicts have not been touched in any way by me in my branch. Other developers that pushed to the parent - sure. That is why I was merging the parent in the first place. – JoeG Sep 13 '17 at 13:02
  • Nothing cannot conflict with anything, there must be some changes. Actually, you can just run `git diff -- ` just after the failed merge to see what has conflicted there. – max630 Sep 13 '17 at 13:31
  • This is not happening only to me. Today is far from the first time. This happens frequently to each of the 11 developers I have checked with. I have not checked with the rest. This has happened too many times to count for me over the past year, just finally got tired of it, so thought I would ask. – JoeG Sep 13 '17 at 13:54
  • 1
    You're misinterpreting what `git status` is telling you. What `git status` does is run two `git diff`s: one from `HEAD` to the index, and one from the index to the work-tree. Before starting a merge, *both* of these diffs should be empty. By itself, that tells you nothing about what changed since the crucial *merge base* commit. I think one of the main problems here is that what `git merge` actually does is mysterious to many users... – torek Sep 13 '17 at 15:00

1 Answers1

0

There cannot be a conflict on a file that hasn't been modified on both sides. You can be as insistent as you like in your comments that it's happening, but it isn't.

Your first statement in trying to "prove" that it is happening is that the files don't show up in git status; that only means that there aren't any uncommitted changes to the file. What you really ought to do is have a clean working tree when merging, so that git status wouldn't report any files.

But the issue for a merge conflict isn't whether there are uncommitted changes such that status would report it; it's whether there are changes since the merge base. If you want to see what changes will be considered in a file during a proposed merge from master to my_branch, you can do

git diff `git merge-base master my_branch` my_branch -- path/to/some/file

Now the changes could be something introduced by tooling. Some situations you might have line ending settings that cause unwanted changes. Whatever. And once you know what it is, you can look at how to make it stop happening.

But the command that says "if I haven't changed a file, take the changes from theirs" is git merge plain and simple. You do not get conflicts on unmodified files.

Mark Adelsberger
  • 32,904
  • 2
  • 24
  • 41
  • I add and commit the files I have changed. You stated what "git status" returns differently than I did. I said that the conflict files did not show as modified. In fact, the conflict file are NOT part of any of my commits, nor do they or any other files show up on a "git status". However, after I merge the parent, I often get conflicts. If this happened only once or twice, sure operator error - by I have several years of this going on and not to only me. Are we setup incorrectly - well that might well be possible - hence my original question – JoeG Sep 18 '17 at 20:03
  • Not sure what you're trying to get at about your perceived difference in what I said about status, but again status output isn't really relevant here. (Except that, if you're saying the files *are* listed in some way that makes you think they *aren't* modified... if they're listed *at all* they are in some way modified.) But it doesn't matter; you need to get past the status thing, because that's not what tells you the file's history. If there's a conflict, it is part of a commit. Until you get past insisting it's not true, there's no more anyone can help. – Mark Adelsberger Sep 19 '17 at 12:37
  • On our repository, I just ran a 'find . -name "*.java" | wc -l'. This returned 7651 files. I don't know many of these files nor have I ever even opened them in an editor. Yet when I merge the parent branch down to my branch, I will often get 3-5 files that I have never heard of (that other developers have modified and pushed to the parent branch) show up as conflicts in my merge. It seems like you are insisting this does not happen, this might just be miscommunication, but of the behavior I regularly observe, I am in no doubt. – JoeG Sep 19 '17 at 14:22
  • Well, let me be clear then: I am insisting that if there is a conflict, the file has changed on both sides of the merge. That is the definition of conflict and the algorithm used by git is mathematically incapable of doing otherwise. I've offered commands you can use to try to find out why these files are changing when you think they're not. I suggest you use them, but if you'd rather insist it's just magic that can't be explained, that's your call. – Mark Adelsberger Sep 19 '17 at 14:59