Git 预提交挂钩未在 Windows 上运行
Posted
技术标签:
【中文标题】Git 预提交挂钩未在 Windows 上运行【英文标题】:Git pre-commit hook is not running on Windows 【发布时间】:2014-01-03 18:41:09 【问题描述】:我刚刚开始研究 Git 挂钩,但我似乎无法让它们运行。
我设置了一个本地存储库,所以我的项目文件夹中现在有一个“.git”目录。我在名为“pre-commit.cmd”的 C:/path/to/my/project/.git/hooks 目录中添加了一个“.cmd”文件。这是这个文件的内容:
echo "HOOK RUNNING"
echo. 2>C:/path/to/my/project/.git/hooks/EmptyFile.txt
这应该回显文本“HOOK RUNNING”并在该目录中创建一个空文本文件。但是,如果我通过我的 IDE (NetBeans) 提交更改或使用 Git Bash 提交,它们似乎都没有运行我的预提交挂钩,因为没有创建文件。
我的理解是,要让钩子运行,您所要做的就是添加一个带有钩子名称的可执行文件(正如我所做的那样)。我做错了吗?
注意:这是在 Windows 7 PC 上。
【问题讨论】:
相关(部分答案的主题):Why is my Git pre-commit hook not executable by default? 【参考方案1】:将你的钩子命名为pre-commit
(不带任何文件扩展名)。
并在第一行添加#!/bin/sh
或#!/bin/bash
。
【讨论】:
感谢您的建议。刚刚尝试过,现在当我尝试提交时出现错误:“错误:无法生成 .git/hooks/pre-commit:没有这样的文件或目录”。 已编辑以添加第二条建议(在 ***.com/questions/5697210/… 中找到)。如果不是这样,我也无能为力了,我对 windows shell 问题不是很熟悉 就是这样!你的第二个建议使它起作用。不知道为什么它不能只是一个普通的 Windows '.bat' 或 '.cmd' 文件...... 试试chmod +x pre-commit
我必须使用 #!/bin/bash
而不是 #!/bin/sh
才能在 Windows 下运行它。【参考方案2】:
您可能没有运行pre-commit
文件的权限
在终端中运行:
chmod +x .git/hooks/pre-commit
感谢@vaughan 提出这个想法
【讨论】:
也是一个钩子无法运行的正当理由:D,在我的情况下是真的,谢谢 这让我发疯并解决了我的问题。谢谢! @DaneMacaulay 你能告诉我在哪里写这个吗? 确实,我的回答不清楚,你需要在终端运行,我编辑了我的答案 在运行该命令之前,您需要进入项目所在的目录【参考方案3】:TL;DR
默认情况下,Git 挂钩 work 在 Git for Windows 上,假设 Git 挂钩 脚本很简单。
Git 和 Windows 的背景
请注意:Git 是为 shell interpretation 制作的;因此,在 Windows 命令提示符或 Windows 制造的 PowerShell 上使用 Git 钩子本来就有缺陷,并且无法预期完整的 interoperability。
在 Windows 上使用 Git 挂钩是可能的,但它有很多缺点。
Git for Windows 使用了一个 shell 模拟器,使 Bash 和 shell 命令成为可能。这意味着当 Git 激活 Git 挂钩时,Windows 版本将使用 shell 模拟器运行命令。反过来,这会将这些 shell 命令转换为 Windows 操作系统可以理解的命令。这意味着,简单的 shell 脚本可以立即运行。例如,Git 钩子 pre-commit
附带一个 Git 存储库的初始化,无需任何修改即可运行。
默认行为示例
使用命令git init
初始化一个Git仓库
使用命令 cd .git\hooks
导航到 Git hooks 目录
此目录包含所有 Git 挂钩脚本。创建一个名为pre-commit
的文件。注意:
文件名很重要
将内容替换为以下shell脚本
#!/bin/sh
echo "Hello, World!"
导航回项目的根目录并使用命令echo "something" > text.txt
创建一个名为test.txt
的文件
使用命令 git add test.txt
暂存文件以提交
提交更改并使用命令git commit -m "test commit"
观察预提交挂钩激活
验证输出如下所示
git commit -m "test commit"
Hello, World!
[master f00ccea] test commit
不良行为示例
当使用非常高级的 shell 脚本在 Git 挂钩中执行操作时,Windows shell 解释并不总是叠加。例如,当使用 NPM 的 Husky Git 挂钩插件以及 Prettier 格式化程序时,命令不会映射 1-1。这意味着您的预提交 Git 挂钩将在 Windows 上失败。
回复user1578653's question
Git 钩子是一个可执行脚本;但是,您使用的是命令提示符脚本 (.cmd
) 而不是 shell 脚本 (.sh
)。如果您想要在 Windows 操作系统上描述的这种行为,则创建名为 pre-commit
的文件并将其放置在 .git\hooks
目录中(相对于您正在处理的项目)。然后将以下内容放入该文件中。
.git\hooks\pre-commit
#!/bin/sh
echo "HOOK RUNNING"
thisCausesError 2> .git/hooks/EmptyFile.txt
您会注意到 Git 挂钩起作用并将单词 HOOK RUNNING
输出到控制台,thisCauseError
将向标准错误打印一条错误消息,该错误消息将打印到文件 EmptyFile.txt
。
【讨论】:
【参考方案4】:就我而言,我将core.hooksPath
设置为错误的目录。
用git config --global core.hooksPath '~/.githooks'
重置它解决了这个问题:)
【讨论】:
我为 Cygwin 启用了钩子,方法是将它们放入子目录./hooks
并使用 cd .git; ln -sf ../hooks hooks
使它们对 git 可见。因此,git 钩子在 Cygwin 的 git 中执行,但不是在 Emacs M-x shell-command
或其他使用 cmdproxy
或 cmd
的地方,包括 git gui
。找到这个答案后,使用git config core.hookspath hooks
解决了这个问题,它独立于 git 是从 cmd 还是 Cygwin 的 bash 中调用的。
非常感谢..我有error: cannot spawn .git/hooks/pre-commit: no such file or directory
这个解决方案对我有用..
它对我有用。【参考方案5】:
对我来说,我尝试运行 .bat
文件。
我发现反斜杠需要转义:
例如:
#!/bin/bash
C:\\somefolder\\somefile.bat
【讨论】:
【参考方案6】:在我的情况下,我做了npm install
并意外删除了 .git 文件夹,npm install pre-commit --save
起作用了。
【讨论】:
【参考方案7】:对我来说,以前的解决方案都不起作用。我将预提交文件从挂钩移动到其他位置,有效地从挂钩中删除了文件。
这对我有用:D
【讨论】:
是的,删除 hooks 目录中的 pre-commit 文件是可行的 这只是意味着你把 git 钩子拿出来了,并没有修复钩子。【参考方案8】:如果对任何人有帮助:
我收到以下错误:
错误:无法生成 .git/hooks/pre-commit:没有错误
事实证明,在我的预提交文件中,我在最后一个退出命令之后没有“换行符”:
#!/bin/sh
# From gist at https://gist.github.com/chadmaughan/5889802
# Stash any unstaged changes
git stash -q --keep-index
# Run the tests with the Gradle wrapper
./gradlew test --daemon
# Store the last exit code in a variable
RESULT=$?
# Unstash the unstashed changes
git stash pop -q
# Return the './gradlew test' exit code
exit $RESULT
# << must have a newline after the above command >>
我在 Windows 上运行 Gradle 项目,并在 Cmder shell 和 cmd 中运行 Gradle 命令。
【讨论】:
非常不幸的是,许多系统会默默地(自动地)删除文件末尾的“换行符”,即使它不是空行(例如:Arduino IDE)。同时,许多编译器无法处理文件末尾缺少的换行符。一种解决方法是在文件末尾添加某种注释。【参考方案9】:我尝试了其他答案中建议的解决方案,但对解决此问题没有帮助:
无法生成 .git/hooks/pre-commit:没有这样的文件或目录
对我有用的解决方案是将文件 .git/pre-commit.sample
重命名为 .git/pre-commit
并插入脚本以使用 Prettier 格式化更改的文件。我手动创建的名为“pre-commit”的文件一定有一些问题(编码或结束行符号仍不清楚)。
【讨论】:
以上是关于Git 预提交挂钩未在 Windows 上运行的主要内容,如果未能解决你的问题,请参考以下文章
text Git预提交挂钩(.git / hooks / pre-commit)以防止意外提交调试代码(在源注释中添加NOCOMMIT)