Search code examples
gitconflictrebase

Git rebase conflict with nothing to merge?


What does it mean when a git rebase finds a conflict, but there is no apparent problem in the file? The file in question has no conflict markers, and git mergetool says "nothing to merge".

The options I have are reset or add:

# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#   both modified:      filename.js

How do I find out what this is about and which path to take?

git ls-files -s filename.js gives 3 rows:

100644 d2c915b1d632b8ef8fbcf056824fb7fac7824ab9 1   filename.js
100644 9010798f1d19ac712196b1fc9b0870fd332b1275 2   filename.js
100644 b3ab7ec50812c73a3ec97bf0985f3226ec13cbc8 3   filename.js

According to the fine manual, this command tells us the mode bits, the object name, and the stage number. The mode bits are the same. So what are 1, 2, and 3, and why are they "both modified", but not showing conflict markers?


Solution

  • The versions in the index marked 1, 2, and 3 have the following meaning:

    1. The file as it was in a common ancestor of the two commits you're merging.
    2. The file as it was in HEAD, i.e. your current commit when you did the merge.
    3. The file as it is in the commit that you're trying to merge into HEAD.

    My source for this information is the git manual's useful section on resolving conflicts.

    The both modified output in git status indicates, of course, that the file was changed in different ways by the two commits that you're merging since their common ancestor.

    It is rather mysterious to me why you don't see conflict markers in the file, however - that the blobs have different object names (hashes) in the output of git ls-files -s indicates that byte-by-byte they certainly do have different content. If you are happy with the file as it is in your working copy, you can just do git add filename.js and then git rebase --continue. However, in any case you may want to find out what those difference were. To do that, I would try the following:

    git diff :2:filename.js filename.js
    

    ... which will show the differences between the version in HEAD and your current working copy. Similarly, you can try:

    git diff :3:filename.js filename.js
    

    ... to see the difference between the version in that was being merged and your working copy.