git am some_patch 是否以原子方式应用?

Does git am some_patch apply in an atomic way?

我已经编写了一个自动代码来通过 git python 库应用 git 补丁。但是我想知道是否有可能 已应用补丁,但有些会出错。

    try:
        repo.git.execute(["git", "am", "patch")
    except Exception as e:
        for stat in status:
            stat.update({"status": "failure"})
        repo.git.execute(["git", "am", "--abort"])
        return status

您必须在此处更准确地定义 的 "atomic" 的含义。不过,特别是:

[What] I want to know is [whether] there [is] a possibility that some of the patches are applied and some give error

git am <em>path</em>肯定有可能失败,git am文档描述了什么发生在那种情况下。如果邮箱格式的补丁包含,比如说,七个部分,并且前三个应用干净但第四个有合并冲突或其他故障,前三个确实会被应用而第四个确实尚未应用。如果失败的原因是合并冲突,索引和工作树将处于部分合并状态。如果补丁根本没有应用,索引和工作树将匹配应用第三次提交产生的​​状态。无论哪种方式,git am 都将退出非零值。 (在这一点上,您可以使用 git am --abort 将所有内容恢复到开始之前的状态,应用 no 补丁,或者手动修复问题然后 运行 git am --continue 继续进程。)

gitpython documentation 提到如果基础 Git 命令退出非零,则引发 git.exc.GitCommandError。因此,您会在此处捕获异常。

旁注:except Exception 在 Python 中通常过于宽泛。您通常应该在这里捕获您期望的特定异常,在这种情况下可能是 git.exc.GitCommandError(因为 git am 存在并且 运行,但报告失败) 和 git.exc.GitError(因为 一般出错,例如未安装 Git 二进制文件,或 Git 声称这不是位于以下位置的存储库全部,等等)。

确保对涉及 git am --abort:

的原子过程使用 Git 2.34

当“git am --abort"(man) 未能正确中止时,它仍然以 0 的退出状态退出,已用 Git 2.34(2021 年第四季度)。

commit c5ead19, commit 42b5e09, commit ea7dc01 (10 Sep 2021) by Elijah Newren (newren)
(由 Junio C Hamano -- gitster -- in commit 6c84b00 合并,2021 年 9 月 23 日)

am: fix incorrect exit status on am fail to abort

Signed-off-by: Elijah Newren

所以在你的 python 函数中:

        repo.git.execute(["git", "am", "--abort"])
        return status

这会在 Git 2.34 之前返回“始终为真”,即使 am 中止失败也是如此。