Find files that were conflicting or locally edited during git merge commit

Background: I’m working on a pre-commit tool. As a developer it can be quite frustrating to pull another developer’s branch and have the pre-commit hook complain loudly about files that I haven’t even touched.

What I’d like to be able to do in my implementation is in a merge-commit case only run the hooks on files that were either conflicting or manually edited by me locally during the merge conflict.

  • Pushing git submodules correctly
  • Magit : how to see pre-commit hooks before editing commit log?
  • Git error: RPC failed; result=55, HTTP code = 200
  • Terminal says 'No such file or directory' when open
  • I've accidently pushed to a git repo with the wrong user account. How can I undo it or change the user?
  • Patch Django Site Package From a Pull Request Using Pip
  • What I’ve tried so far:

    • git diff --staged – This is what the current solution does and isn’t correct because it contains all of the files including the ones that merged cleanly.
    • git diff MERGE_HEAD – This is pretty close, but if the branch I am merging in branched from master after I did, this contains all of the changes from master that I haven’t yet merged.
    • .git/MERGE_MSG contains the list of conflicting files. This seems like a good starting point but does not contain locally edited files.
    • After committing, git show --name-only gets me exactly what I want. But that’s too late (I’m implementing pre-commit after all :D)

  • bundle install from a new server errors due to git ssh key
  • Bower: ENOGIT Git is not installed or not in the PATH
  • Add new commit in the existing git tag
  • What's the difference between vimdiff and vimdiff2 in git?
  • How to untrack files (git and git GUI)
  • Stashing only un-staged changes in Git
  • 2 Solutions collect form web for “Find files that were conflicting or locally edited during git merge commit”

    I believe the solution is git diff -m. I found the doc on this very confusing, so here’s my summary. Given the command git diff -m child parent1 parent2 .... you’ll see a multi-parent diff that shows how to get from each parent to the child. parent1 represented in the first column of [ +-] and so on. The major roadblock here is that the child in your question has no referenceable name. git write-tree comes to the rescue here; it creates a name for the currently-staged files, and prints it out.

    Note that write-tree will fail if there are any unmerged files, which is probably what you want, but you’ll need to make sure your system does something intelligible in that case.

    $ CURRENTLY_ADDED=`git write-tree`
    diff --cc README
    index 2ef4a65,8e2e466..be3d46e
    --- a/README
    +++ b/README
    @@@ -1,10 -1,5 +1,10 @@@
     -deleted only in <theirs>
     +added only in <theirs>
    - deleted only in <ours>
    + added only in <ours>
    --deleted during merge
    ++added during merge

    When you git add to resolve a conflict, you erase the record of the conflict. So to preserve this information without having to reconstruct it, preserve the index file:

    cp .git/index .git/preserved-merge-index

    and then

    GIT_INDEX_FILE=.git/preserved-merge-index git ls-files --unmerged

    will show you the conflicts, and

    GIT_INDEX_FILE=.git/preserved-merge-index git diff-files --name-only

    will show you everything in your work tree that’s changed since it was recorded in the merge index.

    From comments, you also might be adding files directly in the merge. To catch those, after you’ve resolved all your merge conflicts you can

    GIT_INDEX_FILE=.git/preserved-merge-index git diff-index --name-only `git write-tree`
    Git Baby is a git and github fan, let's start git clone.