When running git merge origin master
on the command-line I'm not getting the usual conflict markers <<<<<<
but instead conflicting files are being copied down to my local environment.
Could this have something to do with the folder-name being changed?
Example:
git fetch origin master && git merge origin master
CONFLICT (rename/add): Rename javascript/main.js->js/main.js in HEAD. js/main.js added in %commit-hash%
Adding as js/main.js~%commit-hash% instead
Then I have 2x files on my local: js/main.js
& js/main.js~%commit-hash%
How can I make git give me conflict markers to work with instead of a new file?
& Can anyone shed some light on why this happens?
- note:
%commit-hash%
is just a placeholder for the actual commit-hash for sake of example.
TL;DR
Try using
-X find-renames=<value>
to get different rename detection. Or, if that won't work or you don't like that method, extract all the files from the multiple stages stored in the index if necessary, and then usegit merge-file
to create the conflicts "by hand".Long
This is a high level conflict: a conflict that occurs due to multiple different files with changing names, instead of a conflict that occurs within one single file.
Git has told you exactly what the problem is:
So when comparing the current or
HEAD
commit to the common merge-base from which both you and they started, Git finds that you tookjavascript/main.js
and renamed that file tojs/main.js
.They, whoever they are, left file
javascript/main.js
injavascript/main.js
, but then created a new file calledjs/main.js
.Because there can only be one file named
js/main.js
, Git has to do something special. It can't put yourjs/main.js
(that you renamed fromjavascript/main.js
) intojs/main.js
and put their newly-created but differentjs/main.js
intojs/main.js
. So it has put theirjs/main.js
intojs/main.js~hash
.Maybe you can do this trivially, and maybe not.
First, you have to decide whether Git's analysis of the situation is correct. Did you rename
javascript/main.js
tojs/main.js
? And, what did they do: did they keep their originaljavascript/main.js
and add a new and differentjs/main.js
, or did they actually rename theirjavascript/main.js
and it's just that Git didn't realize this and thought they created a totally newjs/main.js
that was not related to the originaljavascript/main.js
?If the problem is that Git has mis-detected the two renames, you can try tweaking the
-X find-renames=<value>
setting (named-X rename-threshold=<value>
in older versions of Git). Making the number lower makes Git more willing to treat apparently-different files as "the same" file. Making the number higher makes Git less willing to treat such files as "the same", to the point where if you set it to 100%, the files' contents must match exactly.If all this is the case and this process goes well, you may get what you want and not need any further tricky bits. If not, well:
Doing it by hand
If Git is correct, and your
js/main.js
really is renamed while theirjs/main.js
really is new, it may be inadvisable to combine the files. However, you can do this, usinggit merge-file
, which works with ordinary files in the work-tree. First, you will need to get all three files into your work-tree:javascript/main.js
in the merge base commit (whatever its hash ID is).--ours
orHEAD
version, namedjs/main.js
in the current commit.--theirs
version, also namedjs/main.js
but in their commit.Two of these three versions are already available in your work-tree, using the two names Git has announced.
There should also be a copy of each file in your index: the merge base is there as a stage-1 entry, the
--ours
orHEAD
version is there as a stage-2 entry, and the--theirs
version is there as a stage-3 entry. This means that you can usegit show
orgit checkout-index
to get to each. (In fact, you can probably usegit checkout-idnex --stage=all
to get all of them as temporary files all at once, but I have not experimented with this.) Since the one you still need is the base version, you could use:for instance (assuming a Unix-style shell).
Once you have all three files in your work-tree, you can run:
to produce, in
<head-version>
, a conflict-marker-ized version of the file. Assuming the names you've shown so far, and writing the stage-1 file tojs/main.js.base
, that would be: