Reputation: 1634
TL;DR : From a purely theoretical perspective, is it possible for Git to report conflicts on a file during the merging (not rebasing) of a branch into master if that file has never been modified at all on the branch (which was created directly from master) ?
When I merge my dev branches back into master, I am often presented with conflicts on files that for the life of me I cannot remember to have ever modified - or even opened. So I am trying to understand if - given how Git works, which I don't know well enough - this is actually possible in specific circumstances, or if instead this is impossible so I should focus on something apparently modifying some files in my working tree without me noticing (f.ex. something like Save Actions in Eclipse, automatic formatting, line ending handling etc.).
I am only talking about file conflicts, not tree conflicts nor anything else that might involve file deletions or renamings or movings.
Here is an example of my very simple typical workflow, using EGit with Eclipse (always up to date):
1) I create a dev branch from master; I tick the "Configure upstream for push and pull" checkbox, and in the "When pulling" listbox I select "Merge" (the other entries are "Rebase", "Rebase preserving merge commits", "Rebase interactively").
Nobody else will be committing to that branch, local and remote, at all. Only me and only from one computer.
2) I checkout that dev branch and for some days I commit my changes to it everyday. Every single commit is done using "Commit and Push" instead of just "Commit", because I want all my commits to always be on the remote branch too.
On some occasions the Push part of my "Commit and Push" results in a "Rejected - Not fast-forward". In those cases doing a "Pull" and then repeating the Push solves, and some colleagues say that it's normal to have to do a Pull first to avoid that the Push results in "Not fast-forward". This is not the problem though.
3) The time comes to merge my dev branch back into master. I pull, switch back to master, pull, select Merge, choose my local dev branch, under "Merge options" I select "Squash", under "Fast forward options" I leave the default "If a fast-forward, only update the branch pointer" (the other options are "If a fast-forward, create a merge commit" and "If not a fast-forward, fail").
Then I click Merge and I get "Result: conflicting", I go to solve those conflicts and in some cases neither the conflicting code shown in red under "Mine" (master) nor the corresponding code shown in red under "Theirs" (my dev branch) is something I wrote. I never modified that file in any part, ever, and yet it has conflicting changes when merging this branch - on which this file has never been changed - into master.
So my question is, from a purely theoretical perspective, do possible situations exist where Git is supposed to report conflicts on a file during the merging of a branch into master although that file has never been modified at all on the branch ? And if yes, does my workflow described above qualify as one of such situations ?
It's not a duplicate of this because that's about using rebase.
Upvotes: 0
Views: 1440
Reputation: 45659
Update - realized I forgot to get back to directly answering the question...
First things first: If you are having to pull before you can push, then someone else is making commits on a branch you've modified and are pushing. Going by your descriptions I can't be 100% sure - I'd need to know specific commands and config settings - but I would bet that means you're mistaken that nobody else is committing to your branch.
I mention this because you're asking if git could theoretically do something because your observations say it may be happening... but those observations are not self-consistent and so cannot be exactly correct.
Could a merge occur when the branch has no changes?
Not under the conditions you described. ... Well, ok, you said "theoretically", so I'll grant that if you're for some reason using an alternate merge tool that's coded to be malicious, I couldn't prove this is impossible. But given my above comments, I'd say I don't believe that's what's going on here.
Say you have
R -- x1 ... xN -- A <--(master)
\
o1 ... oN -- B <--(branch)
and you're about to do a merge of branch
into master
. If there is a conflict on file foo
, then by definition this means that
(A) there is a change p1
that was applied to foo
somewhere between x1
and A
,
(B) there is a change p2
that was applied to foo
somewhere between o1
and B
, and
(C) p1
and p2
are deemed to "overlap"
Now there could be lots of ways for p2
to hide behind that ...
in the diagram. For example, maybe someone created branch2
from branch
, made some changes, and merged branch2
back into branch
. But the merge back to branch
would still be "someone else committing changes to branch
in that scenario (and the appearance of the merge commit would be an example of when you'd have to pull before you could push).
So how to tell what's really happening?
If git reports a conflict, you can get some idea what it's thinking by looking at the conflict markers. If it's just a matter of changes you didn't remember, perhaps they would look familiar? But it sounds like that's not the situation.
(The following commands assume the merge is still unfinished; if the merge has been committed then you'd use something like master^..branch
; the point is the part before the ..
has to refer to the master
commit prior to the merge.)
So you could see what commits have impacted the file (but aren't in master
) with something like
git log master..branch -- path/to/conflicted/file
If that doesn't clear it up, another step would be to try
git blame master..branch -- path/to/conflicted/file
(You could include -L
options to zero in on the lines identified on the branch
side of the conflict markers if you want; see the git blame
documentation.)
This should tell you who, when, and in what commit.
Upvotes: 1