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.
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_MSGcontains the list of conflicting files. This seems like a good starting point but does not contain locally edited files.
- After committing,
git show --name-onlygets me exactly what I want. But that’s too late (I’m implementing pre-commit after all :D)
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` $ git diff -m $CURRENTLY_ADDED HEAD MERGE_HEAD 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
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
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`