如何确定 Git 合并是否正在进行

How to determine if Git merge is in process

是否有 Git 命令可用于确定合并是否正在进行(即未提交)?我知道我可以简单地检查 .git/MERGE_HEAD,但这是否适合 and/or 面向未来 命令行脚本?

你可以运行 git status

git 会告诉您存储库中发生了什么。

例如 * 冲突文件(未合并文件)

一个技巧是使用 Git 命令,如果正在进行合并,该命令将失败。然后您可以检查命令的 return 代码。您还需要确保该命令在成功时不会影响您的工作副本或索引。虽然有很多命令属于这一类,但似乎合适的一个是

git merge HEAD

如果合并正在进行,return 代码为 128,否则为 0。请注意,当合并未在进行中时,此命令将简单地打印 Already up-to-date 因为您只是在与自己合并。因此,为了编写脚本,您可以这样做(在 BASH)

git merge HEAD &> /dev/null
result=$?
if [ $result -ne 0 ]
then
    echo "Merge in progress."
else
    echo "Merge not in progress."
fi

请注意,即使使用 git merge--quiet 标志,进程内合并仍会导致此命令打印到错误流。这就是我将其输出重定向到 /dev/null.

的原因

您可以安全地检查 git 目录[1] 中是否存在 MERGE_HEAD 以确定是否有正在进行的合并。 MERGE_HEAD 文件包含要合并的提交 ID,这将是已提交合并的第 n 个父项。例如,如果我尝试合并位于 c085e0c:

的分支 br1
> git merge --no-ff --no-commit br1
Automatic merge went well; stopping before committing as requested

> cat .git/MERGE_HEAD
c085e0caa2598064bfde9cc6318bd2c73fee2371

如果您正在执行章鱼合并,那么您将在该文件中看到多个提交 ID(换行符分隔):

> git merge --no-ff --no-commit br2 br3
Fast-forwarding to: br2
Trying simple merge with br3
Automatic merge went well; stopping before committing as requested

> cat .git/MERGE_HEAD
69b0169b1cba60de86161b375f013c59ad9581d8
99dad0187351d61ae8e88d49c96d7383f9e8fa6d

使用MERGE_HEAD实际上是how git clients determine whether there's a merge in progress。有些人通过漏洞抽象提供了这种洞察力:

> git merge --abort
fatal: There is no merge to abort (MERGE_HEAD missing).

因此,检查 MERGE_HEAD 的存在是完全可以接受的,并且与软件中的任何东西一样是面向未来的 - 这意味着对 git-merge 的任何更改都必须与其他 [=37] 兼容=] 考虑到客户并将(希望如此!)优雅地过渡 and/or 提供向后兼容性。

[1] 与 .git 在您的工作目录下相比,您可以更相信 MERGE_HEAD 的存在。有人可以使用 --git-dir 标志或 GIT_DIR 环境变量。

另一种选择是测试是否存在 .git/MERGE_MSG 文件。

这是因为, 2.14.x/2.15(2017 年第 3 季度)之前,您最终可能会 不这样做.git/MERGE_HEAD,即使合并正在进行中。

commit 9d89b35, commit 8e6a6bb, commit 62dc42b (23 Aug 2017), and commit e2de82f (21 Aug 2017) by Michael J Gruber (mjg)
(由 Junio C Hamano -- gitster -- in commit 6e6ba65 合并,2017 年 8 月 27 日)

Killing "git merge --edit" before the editor returns control left the repository in a state with MERGE_MSG but without MERGE_HEAD, which incorrectly tells the subsequent "git commit" that there was a squash merge in progress.
This has been fixed.

Git 2.14.x/2.15 之后,情况将不再如此,测试 .git/MERGE_HEAD 就足够了。

由于 MERGE_HEAD 仅在合并期间可用并且也是面向未来的,我们可以简单地使用 git rev-list -1 MERGE_HEAD (方便地,管道命令)如果 [=10] 将以代码 128 退出=] 未找到。将 stdout 和 stderr 通过管道传输到 /dev/null 以进行更清晰的检查。或者更好,使用 git rev-parse -q --verify MERGE_HEAD.