【问题标题】:How would I write a pre-merge hook in Git?我将如何在 Git 中编写预合并挂钩?
【发布时间】:2013-10-06 19:37:29
【问题描述】:

问题说明了一切。有没有办法在合并之前执行操作?我猜有一种方法可以使用pre-commit 钩子,但我不太确定。

【问题讨论】:

  • 即使这个问题已经超过 5 年了——同时有什么解决方案吗?例如,我希望人们能够根据需要提交到他们自己的私有分支中,但不要将具有糟糕指标的代码合并到开发或主分支中......
  • 注意:Git 2.24 (Q4 2019) 实际上包含了一个 pre-merge-commit 钩子。见my answer below

标签: git merge githooks


【解决方案1】:

您可以尝试使用prepare-commit-msg 挂钩。第二个参数将是merge“如果提交是合并或.git/MERGE_MSG 文件存在”。非零退出状态将中止提交。

我认为这不适用于快进合并,因为不会有提交消息。

关于钩子的更多信息:https://www.kernel.org/pub/software/scm/git/docs/githooks.html#_prepare_commit_msg

【讨论】:

  • 这似乎不会在您执行 git 合并时触发。要查看此内容:将 exit 1 放在 prepare-commit-msg 的顶部并执行合并提交。
  • 是快进合并吗?如果合并没有触发提交消息,那将无济于事。
  • 即使与提交(消息)的实际合并也不会触发。我已经尝试过上面描述的测试...很高兴被证明是错误的示例,但请进行测试。
  • 现在还可以吗?我一直在尝试触发一个钩子,该钩子会在有人进行合并之前触发。我认为不可能,只是想确认一下。
  • 在与 git 2.18 的非快进合并中为我工作。 printf -- '%s\n%s\n' '#!/bin/sh' 'echo nope && exit 1' > prepare-commit-msg
【解决方案2】:

另一个不错的解决方法是添加一个 shell 脚本,随意调用它, 然后将这些行添加到脚本中:

git() {
    if [ "$1" == "merge" ]; then
        echo "seems to work like a charme"
    fi
    command git "$@"
}

git "$@"

然后制作一个

alias git="./my-pre-merge-script.sh"

那你就可以走了。您刚刚添加了自己的预合并钩子。 我知道,您无法访问 git 将传递给真正的 pre-merge 钩子的任何参数,但您现在可以准备文件或任何您想要准备合并的东西;我个人对这种方法非常满意:我花了 2 到 3 天的时间来寻找一些用于 pre-merge 的东西,然后我不得不使用 pre-commit-msg,但我发现它对我的需求不够准确。这解决了我所有的问题。希望这对将来的任何人都有帮助。

【讨论】:

  • -1。这不仅丑陋,而且根本不健壮。 merge 并不总是git 的第一个参数:考虑类似git -c foo=bar merge foobar
  • 这确实是一个丑陋的黑客。但是,感谢您提示合并不必是 $1,但是,您仍然可以从参数列表中解析“合并”!对合并前的钩子有更好的解决方案吗?
  • 这可能是可能的,但它肯定相当复杂。如果有人有一个名为merge 的分支怎么办?如果有人与git pull 而不是git merge 合并,甚至与自定义git 脚本合并怎么办?您的脚本需要了解 git 以确定用户何时实际合并。
  • 我实际上正在编写一个巨大的脚本,涉及 git 钩子。我需要我自己的 pre-git 钩子,它实际上像你刚才说的那样关心 git pull。另外,我需要为诸如 git merge --abort 或 git commit --amend 之类的东西添加特殊情况处理......用户可以做的事情有无穷无尽的可能性......但有时,人们可能会对我在上面提供的解决方案,用于私人/爱好项目,不适用于公司的生产项目。因此,我认为立即否决它有点苛刻,尤其是当你无法提供更好的选择时。
  • 此外,任何想到将分支称为“合并”的人都应该找到一个新的爱好恕我直言。
【解决方案3】:

使用 Git 2.24(2019 年第四季度),无需脚本包装器或准备消息挂钩。

引入了一个新的“pre-merge-commit”钩子。

请参阅commit bc40ce4commit 6098817commit a1f3dd7(2019 年 8 月 7 日)Michael J Gruber (mjg)
请参阅 Josh Steadmon (steadmon)commit f78f6c7(2019 年 8 月 7 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit f76bd8c,2019 年 9 月 18 日)

git-merge:荣誉pre-merge-commit钩子

git-merge 在进行自动合并时不遵守预提​​交挂钩 提交,出于兼容性原因,这将保留。

引入一个 pre-merge-commit 钩子,用于自动合并 提交就像 pre-commit 被称为非自动合并提交 (或任何其他提交)。

documentation 现在包括:

合并前提交

这个钩子由git-merge调用。
它不带任何参数,在成功执行合并后且在获取建议的提交日志消息以进行提交之前调用。
从该脚本以非零状态退出会导致git merge 命令在创建提交之前中止

默认的“pre-merge-commit”钩子在启用时会运行“pre-commit”钩子(如果后者已启用)。

如果该命令不会调出编辑器来修改提交消息,则使用环境变量 GIT_EDITOR=: 调用此挂钩。

如果无法自动执行合并,则需要解决冲突并单独提交结果(参见git-merge)。
此时,不会执行此挂钩,但如果启用了 'pre-commit' 挂钩,则会执行。

【讨论】:

  • 很好!!比我的 hacky 包装器好得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 2012-01-25
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 2018-07-17
  • 2021-04-14
相关资源
最近更新 更多