2

I've been using "git merge-file" to help me port code from a different repository. This works great.

However, when a merge conflict happens, though "git merge-file" will properly report it, the file isn't marked as needing resolution in "git status". In the status, the file is just seen as modified (understandably, since the merge happened outside of git's usual flow).

This is a problem because sometimes when importing a large number of files, I'll miss the message highlighting the conflict.

Is there a way to manually tell git that the file needs resolution?

I tried "git update-index --unmerged somefile", but that didn't appear to work: the file isn't listed as conflicted.

  • 2
    @phd: I think (it's not entirely clear from the question) that he's not run `git merge` itself at all, so there are no undo index entries to recover (no `REUC`s for `git update-index --unresolve` to find). – torek Mar 10 '18 at 16:19
  • Indeed, I haven't used "git merge", only "git merge-file". The former interacts with git's index state properly, the latter doesn't at all. – John de Largentaye Mar 12 '18 at 21:00
  • Possible duplicate of [Is there a way to make Git mark a file as conflicted?](https://stackoverflow.com/questions/2780483/is-there-a-way-to-make-git-mark-a-file-as-conflicted) – Will Nov 29 '18 at 00:27

1 Answers1

2

You must use git update-index --index-info or git update-index --stdin.

In particular, you must create nonzero stage index entries: up to three of them for each file. As the documentation notes, you should also remove the corresponding stage-zero entry (though you may want to make sure that it matches either the HEAD commit version or the work-tree version first, so as to avoid clobbering carefully-staged variants such as those made by git add -p).

Git represents a "failure to merge" case by writing nonzero-stage entries to the index. The work-tree version of the file can contain literally anything as it is entirely irrelevant (to the updating of the index, that is; see comments below). The stage-1 entry is the base version of the file; the stage-2 entry is the --ours version; the stage-3 entry is the --theirs version. Note that one or more of these may be missing, i.e., some stage slots may be empty. For instance, if the base version is missing, the original conflict was an "add/add" conflict.

Running git mergetool, for instance, extracts the three versions from the higher numbered stage entries and then invokes your chosen merge tool on the three input files. The git status command reports an unmerged state for the files.

Note that the content of the three versions must exist in the repository. To write content to the repository database, use git hash-object -w. See the git hash-object documentation for details. The update-index command takes the hash ID of the in-repository blob object (plus the mode, stage number, and name, of course).

torek
  • 448,244
  • 59
  • 642
  • 775
  • "The work-tree version of the file can contain literally anything as it is entirely irrelevant." ... that's only true with merge tools set up to discard existing merge results. the kdiff3 setup does, the vimdiff one doesn't. – jthill Mar 10 '18 at 05:08
  • What on earth is vimdiff doing that it’s looking at the workdir and not using the high stage index entries? – Edward Thomson Mar 10 '18 at 05:52
  • @jthill: interesting - I have not actually *used* vimdiff (I just ran it once to see how it looked). Perhaps I should experiment more... – torek Mar 10 '18 at 16:22
  • @EdwardThomson it is looking at the index entries, it's just also taking the existing worktree content for exactly what it is, the results of any automerging you wanted done. – jthill Mar 10 '18 at 16:43
  • I see. I’ll have to play around with it a bit. – Edward Thomson Mar 10 '18 at 18:24