Reputation: 23
Is there a way to determine what files were auto merged successfully by 'git merge' AFTER the user has resolved file collisions and performed a git add/commit? If any of the successfully auto merged files were updated by the user in the same commit it would be nice to know that too. I have a pre-receive hook that only needs to be run on files that were manually merged.
Upvotes: 1
Views: 2092
Reputation: 489083
OK, based on clarification comments, I'd say that there's no perfect answer, but you can get an approximation that's probably good enough by simply repeating the merge, with --no-commit
to prevent the merge from completing, then using git ls-files -u
to find which files are currently unmerged:
$ git checkout <first-commit-id>
[output indicates detached HEAD]
$ git merge --no-commit <second-id>
[output includes any merge issues]
$ git ls-files -u
The actual output of git ls-files
varies depending on the merge conflict. For instance, with a modify/modify merge conflict (in fileB
):
100644 7531cd0643738673e94e850c07a681aedd008bca 1 fileB
100644 85159a3450148691cd6eec96eb06263240990850 2 fileB
100644 bbf71554709c5a9ae8d253b8e15270534f40e3f7 3 fileB
but with a rename/delete conflict (fileB
renamed to fileE
in "main" branch, but deleted in "side" branch being merged-in):
100644 7531cd0643738673e94e850c07a681aedd008bca 2 fileE
(here there's no stage 1 or 3 variant in this particular case). Additional combinations are possible: see the git read-tree
documentation and pay special attention to the "3-way merge" section.
Once you have the output from git ls-files -u
(which is empty if everything merges cleanly as far as git can tell—this doesn't mean the merge is correct, it could even be total garbage if git is really wrong about the semantics—but it's what git can do automatically now, which is presumably the same as what git could do automatically then as well), abort the in-progress merge and restore the appropriate branch:
$ git merge --abort
$ git checkout <original-branch>
If (as "pre-receive hook" suggests) this is all being done in a --bare
repository, you'll need a temporary work-tree (or entire clone) in which to perform the merge, which I don't really have time to experiment with here.
The two SHA-1s in question, that you need to git checkout
, are simply the two parents of the merge. (Note that all this assumes a 2-parent merge: octopus merges are right out.)
If the person doing the merge had run with -s ours
or some -X
option, this won't repeat what they did and may give you a non-useful answer, which is why this is not perfect by any means. I suspect it's the best you can get fully automated, though.
(Also note that if you want some slight variations that might make sense, you might want to just use git read-tree -m
alone, rather than a full git merge
. This is just based on my "suspicion of intent" here. I also think that whatever you come up with may be of marginal utility at best, and you might be better off just having your users check things themselves before they push.)
Upvotes: 2