user2577365
user2577365

Reputation: 23

How to get list of git auto merge files

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

Answers (1)

torek
torek

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

Related Questions