跳过Git提交钩子

我正在看一个Git钩子,它在Python代码中查找print语句。如果找到打印语句,它会阻止Git提交。

我想覆盖这个钩子,有人告诉我有一个命令可以这样做。我还没能找到它。有什么想法吗?

467957 次浏览

可能(来自#0手册页):

git commit --no-verify -m "commit message"^^^^^^^^^^^-n--no-verify

此选项绕过pre-提交和提交-msg挂钩。另请参阅githooks(5)

正如Blaise所评论的,-n对于某些命令可以有不同的角色。
例如,git push -n实际上是一个干推。
只有git push --no-verify会跳过钩子。


注意:Git 2.14. x/2.15改进了--no-verify行为:

参见提交680ee55(2017年8月14日)by凯文·威尔福德(Kevin Willford)
(合并于提交c3e034f中的Junio C Hamano----#0----,2017年8月23日)

commit:如果没有pre-commit钩子,则跳过丢弃索引

"git commit"用于丢弃索引并重新从文件系统读取以防万一pre-commit钩子在中间更新了它;这当我们知道我们不运行pre-commit钩子时,已经优化了。


DaviLima指出在评论git cherry-pick确实没有支持--no-验证。
因此,如果一个Cherry-Picch触发了一个pre-提交钩子,您可能会像这篇博客文章一样,必须以某种方式注释/禁用该钩子,以便您的git Cherry-Pick继续进行。

在合并冲突解决后,在git rebase --continue的情况下需要相同的过程。


在Git 2.36(2022年第二季度)中,run_commit_hook()的调用者可以了解它是因为钩子成功还是因为没有任何钩子而获得“成功”。

请参阅提交a8cc594(与提交4369e3a1一起修复),提交9f6e63b(2022年3月7日)由阿尔法约尔比亚尔马森(#0)
(2022年3月16日提交7431379合并为Junio C Hamano----#0----

hooks:修复一个模糊的TOCTOU“我们刚刚运行了一个钩子吗?”比赛

签字人:埃瓦尔·阿恩菲约尔·比亚尔马森

修复680ee55中添加的代码中的从检查时间到使用时间TOCTOU竞争(“commit:如果没有预提交挂钩,则跳过丢弃索引”,2017-08-14,Git v2.15.0-rc0-批次#3中列出的合并)。

如果我们运行“pre-commit”钩子并修改了索引,但hook_exists()稍后返回false(例如,因为钩子本身消失了,目录变得不可读等),则会发生这种模糊的竞争条件。
那么我们不会在应该的时候调用discard_cache()

竞争条件本身可能并不重要,用户在实践中不太可能遇到它。
此问题在680ee55讨论了时已在列表中注明,但尚未修复。

让我们也将其更改为推送到签出挂钩。
现在,不是检查钩子是否存在,而是执行推送到结帐或推送到部署,我们将始终尝试推送到结帐。
如果钩子不存在,我们将依靠推送来部署。
与之前相同的行为,没有TOCTOU比赛。
请参阅0855331(“receive-pack:支持push-to-check out挂钩”,2014-12-01,Git v2.4.0-rc0--合并)以了解先前行为的介绍。

这使得hook_exists()在两个重要的地方使用。
refs.c中的“引用事务”检查,见6754159(“refs:实现引用事务钩子”,2020-06-19,Git v2.28.0-rc0-合并批次66618a5中列出),和“准备-提交-msg”钩子,见66618a5(“sequencer:运行'准备-提交-msg'钩子”,2018-01-24,Git v2.17.0-rc0-合并批次#2中列出)。

在这两种情况下,我们都通过不为钩子准备数据来节省CPU时间,如果我们没有钩子,我们就什么也不做。
所以在这些情况下使用这个"invoked_hook"模式没有意义。

"reference-transaction"和"prepare-commit-msg"钩子也不活泼。
在这些情况下,如果我们使用添加的新钩子进行比赛,我们将跳过钩子运行,而在这里修复的TOCTOU比赛中,我们错误地跳过了所需的后钩子逻辑。

man githooks

预提交
这个钩子由git提交调用,可以使用--no-验证选项绕过。它不接受任何参数,并在获得提议的提交日志消息之前调用并进行提交。以非零状态退出此脚本会导致git#36825;要退出

commentno verify没有任何进一步的问题:

git commit -m "Some comments" --no-verify

--no-verify可以工作,但在我的情况下,我不想一直把参数放在终端上。所以我选择了一些更激进的东西。

如果你想全局禁用git hooks,你可以尝试运行:

git config --global core.hooksPath /dev/null

但是,如果你想让它像以前一样,只需在终端中运行以下命令:

git config --global --unset core.hooksPath

如果您不希望它是全局的,只需删除参数:--global

我用Git 2.16.3测试了它。

出于某种原因,--no-verify不适合我使用这个特定的钩子:prepare-commit-msg

如果您也遇到此问题,请尝试:

SKIP=prepare-commit-msg git commit

例如,-n无法验证在“git合并-继续”之后不适用于提交。

这是另一个更粗糙的想法。

  1. 只有文件中的注释行.git/hooks/pre-commit和符号'#'。
  2. 运行单个或多个命令
  3. 取消评论
  4. 利润。

您还可以从项目目录中临时卸载预提交。我使用GUI应用程序进行合并,因此无法使用-n标志,并且注释掉行也不起作用。

pre-commit uninstall

并在完成后重新安装

pre-commit install