为什么我的Git pre-commit钩子默认不可执行?

94
10个回答

124

我的情境是Web开发Node.js。我需要添加husky功能,但遇到了错误,可能是磁盘访问问题。这对我的情况有所帮助:

chmod ug+x .husky/*
chmod ug+x .git/hooks/*

2
是的,只有这个对我起作用了。 - Arslan Shahab
"What is Husky?""Husky是一个工具,它允许我们轻松地管理Git钩子并在这些阶段运行我们想要的脚本。" - Peter Mortensen
3
需要解释一下。例如,这个想法/主旨是什么?它为什么有效?为什么需要group?这个“husky”东西是什么(例如,我的存储库中只有“.git”和“.vscode”这样的点文件夹)?这种更改会带来什么安全隐患?背景是什么——一些Web开发?Node.js?请通过编辑(更改)你的答案来回应,而不是在评论中回应(不要使用“Edit:”,“Update:”或类似的词语——答案应该看起来像今天写的)。 - Peter Mortensen

55

默认情况下,文件不可执行;必须将其设置为可执行。

git init 中的示例文件都是可执行的;如果将其复制或重命名为非示例文件,则会保留原始文件的x标志。

新文件将使用当前默认值创建。在您的情况下,可以通过 umask 查看这些默认值:

$ umask
0022

默认情况下,新文件不会是u+x,除非明确设置为这样。


我在 Mac OS X Lion 上运行 git v1.7.6。我已经运行了 git init 来重新初始化存储库,但仍然不起作用。我使用 TextMate 编辑了文件,这可能是问题所在,但仍无法解释为什么 git init 不能正确执行 chmod u+x - Josh Smith
如果没有其他的发现,我发现我的Linux系统正在运行一个相对较旧的git版本。 - Dave Newton
我的意思是,当我在任何新的Git存储库中使用此类钩子时,这将变得非常烦人。 - Josh Smith
@JeanPaul 如果你重新阅读,你会发现“umask”示例是为了展示示例默认值,这些默认值是新文件的默认值。 - Dave Newton
1
好的,但为什么要谈论umask,如果umask与问题无关呢?只有在umask中设置了用户可执行位(例如0133)时,问题才会发生,但我想知道是谁设置了这样的umask,我们从您的解释中无法理解。 - Jean Paul
显示剩余7条评论

31

我必须对我的预提交钩子执行chmod +x才能让它工作。

问题在于首先它是不可执行的。
这将更容易通过Git 2.15.x/2.16 (2018年第一季度)实现。

请参见commit f805a00 (2017年10月6日),作者为Damien Marié (mdamien)
(由Junio C Hamano -- gitster --合并于commit 130b512, 2017年11月6日)

当存在一个钩子但文件未设置为可执行时,Git会忽略该钩子。
目前这是静默的,可能会令人困惑

此提交添加了此警告以改善情况:

hint: The 'pre-commit' hook was ignored because it's not set as executable.
hint: You can disable this warning with `git config advice.ignoredHook false`

为了允许通过可执行标志启用/禁用钩子的旧用例,引入了一个新设置:advice.ignoredHook

15
在项目目录的根目录下运行命令 chmod +x .git/hooks/pre-commit,在我的 macOS 10.13.3 上能够成功运行。 - Jagdeep Singh
@JagdeepSingh 这确实是一个好主意。提示可以更明确一些。 - VonC

8

运行此命令 chmod ug+x .husky/pre-commit 可以解决在 WSL Windows (Ubuntu) 上的问题。 - Shamim Hossain

5
我只需运行以下命令即可解决它。
chmod ug+x .husky/*

我在Windows中初始化了husky。之后,在WSL中发生了问题,这可能是因为在Windows中初始化时没有考虑Linux的文件权限而导致的问题。


3

我的症状一样,但是原因完全不同:

除了通过 chmod +x .git/hooks/pre-commit 设置正确的权限位之外,请确保您的文件系统以允许这些更改的方式被挂载。例如,如果您在 Linux 下使用 ntfs-3g 挂载的 Windows 磁盘上工作,这可能会成为一个问题。

您可以通过更改 /etc/fstabsystemd的相关内容来解决此问题。


1

补充一下,这是一个函数,用于初始化Git仓库并自动将钩子设置为可执行;应该将其放置在.bashrc或您启动终端时源文件中。下面是详细信息 :)

ginit () {
    git init
    gitpath=`git rev-parse --show-superproject-working-tree --show-toplevel | head -1`
    chmod u+x "$gitpath"/.git/hooks/*
    for submodule in "$gitpath"/.git/modules/*; do
        chmod u+x "$submodule"/hooks/*
    done
}

我和你一样,对同样的事情感到烦恼。每次初始化存储库时,我不想记得必须使所有钩子可执行。此外,当您使用子模块时,它们的钩子不在.git/hooks中,而是在.git/modules/子模块名称/hooks中,这些也应该被设置为可执行文件。

1
我在手动创建"pre-commit"时遇到了同样的问题。使用chmod的方法可能有效,但这只是一个权宜之计,问题可能会在其他机器上出现。
我通过以下命令正确重新创建了"pre-commit",问题得到了解决:
npx husky add .husky/pre-commit "npm run lint"

这是最好的答案。使用husky add而不是手动创建文件。 - undefined

1
我通过运行以下命令解决了这个问题。
chmod ug+x .husky/*

0

原始的模板钩子文件必须是可执行的。

在我的情况下,这是一个缺少可执行位的自定义钩子:

$ git config init.templateDir
~/.git_template
$ stat -c "%A" ~/.git_template/hooks/pre-commit 
-rw-r--r--
$ chmod u+x ~/.git_template/hooks/pre-commit

现在,在执行git initgit clone命令时创建的pre-commit钩子已正确设置为可执行文件:
$ git init hook-exec
$ stat -c "%A" hook-exec/.git/hooks/pre-commit 
-rwxrwxr-x

请查看https://git-scm.com/docs/git-init#_template_directory


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接