我希望在git commit一个.sh文件后,当我在另一个服务器检出该文件时,它是可执行的。
有没有办法在不手动在检出文件的服务器上运行chmod u+x命令的情况下实现这一点?
我希望在git commit一个.sh文件后,当我在另一个服务器检出该文件时,它是可执行的。
有没有办法在不手动在检出文件的服务器上运行chmod u+x命令的情况下实现这一点?
update-index
子命令设置或删除任何被追踪文件的“可执行”标记。git update-index --chmod=+x path/to/file
要删除它,请使用:
git update-index --chmod=-x path/to/file
底层原理
虽然看起来像是普通的 Unix 文件权限系统,但实际上不是这样的。Git 在其内部存储中为每个文件维护了一个特殊的“模式”:
100644
表示普通文件100755
表示可执行文件你可以使用 ls-file
子命令,并带上 --stage
选项来可视化它:
$ git ls-files --stage
100644 aee89ef43dc3b0ec6a7c6228f742377692b50484 0 .gitignore
100755 0ac339497485f7cc80d988561807906b2fd56172 0 my_executable_script.sh
默认情况下,当您将文件添加到存储库时,Git 将尝试遵守其文件系统属性并相应地设置正确的文件模式。您可以通过将core.fileMode
选项设置为 false 来禁用此功能:
git config core.fileMode false
故障排除
如果在某个时刻Git文件模式未设置,但文件具有正确的文件系统标志,请尝试删除模式并重新设置:
git update-index --chmod=-x path/to/file
git update-index --chmod=+x path/to/file
奖金
从Git 2.9开始,您可以在一个命令中暂存文件并设置标志:
git add --chmod=+x path/to/file
安特万的回答是正确的,这应该是一条评论,但评论没有足够的空间并且不允许格式化。 :-) 我只想补充一点,在Git中,文件权限仅以644或755(拼写为100644
和100755
; 100
部分表示“常规文件”)记录:
diff --git a/path b/path
new file mode 100644
前者——644——表示该文件不应该被执行,而后者表示它应该被执行。如何在您的文件系统中实际转换成文件模式有些依赖于操作系统。在类Unix系统中,这些位通过您的umask
设置传递,通常为022
,以从“组”和“其他”中删除写入权限,或者为002
,仅从“其他”中删除写入权限。如果您特别关注隐私并希望从“组”和“其他”中移除读取、写入和执行权限,则可能还是077
。
1Git的极早期版本保存了组权限,因此某些存储库中有带有664
模式的树条目。 现代的Git不再这样做,但由于任何对象的任何部分都永远不能更改,因此这些旧权限位仍然存在于旧树对象中。
只存储0644或0755的更改是在提交e44794706eeb57f2中进行的,该提交在Git v0.99之前,并于2005年4月16日发布。
e44794706eeb57f2ee38ed1604821aa38b8ad9d2
之前的版本,即早于Git版本0.99。 - torek在Linux上,不要忘记
set sudo chmod +x /path/to/file
在本地进行git更新时,否则git将始终将索引返回到本地机器默认设置的644!
在Windows Powershell中,您可以使用以下命令:
icacls .\path\to\file /grant Everyone:F
icacls .\path\to\file /grant Everyone:F
。 - H0R5Eicacls build.sh /grant *S-1-1-0:F
代替,请参见https://learn.microsoft.com/en-us/windows/security/identity-protection/access-control/special-identities查找其他组SID。 - yyny要将代码库中所有文件设置为可执行状态:
git ls-files --stage |grep 100644 | cut -f2 | xargs -d '\n' git update-index --chmod=+x
git ls-files --stage | grep 100755 | cut -f2 | xargs -d '\n' git update-index --chmod=-x
如果您想将所有的.sh
脚本设置为可执行文件,也许以下方法适合您:
git ls-files --stage | grep ".sh$" | cut -f2 | xargs -d '\n' git update-index --chmod=+x
100644
或 100755
的文件 ; ) - milahu