Search code examples
gitgit-merge-conflict

How to bail out of a merge from a git merge driver


We got ourselves into a situation where a git merge driver was misconfigured into a degenerate state (basically, not running code). This put the git working tree into a degenerate state because the conflicted file was just whatever it was before (that is, basically taking one side of the merge).

What's the simplest, stupidest way to tell git merge to bail out of the merge from within the merge driver because the merge driver cannot function? I'm really hoping the answer is a high exit code ( >> 1).


Solution

  • A git merge --quit will have better chance of working when a merge driver is running:

    With Git 2.42 (Q3 2023), when the external merge driver is killed by a signal, its output should not be trusted as a resolution with conflicts that is proposed by the driver, but the code did.

    Well done to the OP Joshua, who asked on the Git mailing list about this!

    See commit 34d765e (23 Jun 2023), and commit 2b7b788 (22 Jun 2023) by Junio C Hamano (gitster).
    (Merged by Junio C Hamano -- gitster -- in commit 3ea43bb, 29 Jun 2023)

    ll-merge: killing the external merge driver aborts the merge

    Reviewed-by: Elijah Newren

    When an external merge driver dies with a signal, we should not expect that the result left on the filesystem is in any useful state.
    However, because the current code uses the return value from run_command() and declares any positive value as a sign that the driver successfully left conflicts in the result, and because the return value from run_command() for a subprocess that died upon a signal is positive, we end up treating whatever garbage left on the filesystem as the result the merge driver wanted to leave us.

    run_command() returns larger than 128 (WTERMSIG(status) + 128, to be exact) when it notices that the subprocess died with a signal, so detect such a case and return LL_MERGE_ERROR from ll_ext_merge().

    gitattributes now includes in its man page:

    When the driver crashes (e.g. killed by SEGV), it is expected to exit with non-zero status that are higher than 128, and in such a case, the merge results in a failure (which is different from producing a conflict).