如何在Windows上使用Git创建文件执行权限?

634

我在Windows上使用Git,并希望通过一次提交将可执行的shell脚本推送到git仓库中。

通常我需要执行两个步骤(git commit)。

$ vi install.sh
$ git add install.sh  
$ git commit -am "add new file for installation" # first commit
[master f2e92da] add support for install.sh
 1 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 install.sh
$ git update-index --chmod=+x install.sh
$ git commit -am "update file permission"        # second commit
[master 317ba0c] update file permission
  0 files changed
  mode change 100644 => 100755 install.sh

如何将这两个步骤合并为一个步骤?git配置?Windows命令?

参考资料:请查看Git file permissions on Windows中的问题,了解第二次提交。


37
在git 2.9.x/2.10(2016年第三季度)版本中,git add --chmod=+x 是可以实现的。请参阅我的答案,感谢 Edward Thomson - VonC
9
值得将所选答案更新为 git add --chmod=+x 版本。 - mikemaccana
7个回答

929

您无需分两个提交来完成这个操作,可以在一个提交中添加文件并将其标记为可执行:

C:\Temp\TestRepo>touch foo.sh

C:\Temp\TestRepo>git add foo.sh

C:\Temp\TestRepo>git ls-files --stage
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       foo.sh

如您所述,添加后的模式是 0644(即不可执行)。但是,在提交之前,我们可以将其标记为可执行:

C:\Temp\TestRepo>git update-index --chmod=+x foo.sh

C:\Temp\TestRepo>git ls-files --stage
100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       foo.sh

现在这个文件的模式是0755(可执行)。

C:\Temp\TestRepo>git commit -m"Executable!"
[master (root-commit) 1f7a57a] Executable!
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 foo.sh

现在我们只有一个提交,其中包含一个可执行文件。


4
请注意,根据 https://dev59.com/C2Ei5IYBdhLWcg3wD4ku#38285462 的规定,自2016年以来,通过 chmod +x <filename> 在本地标记为可执行文件将导致提交的文件也可以执行。 - stwr667
1
有助于在WSL中提交。 - Weekend

299

事实上,如果git-add有一个 --mode 标志会很好。

其实在 git 2.9.x/2.10 (Q3 2016) 中已经允许这样做了(感谢 Edward Thomson):

git add --chmod=+x -- afile
git commit -m"Executable!"

这使得整个过程更快,并且即使core.filemode设置为false也可以正常工作。

请参见提交4e55ed3(2016年5月31日),由Edward Thomson (ethomson)提供帮助的有Johannes Schindelin (dscho(由Junio C Hamano -- gitster --提交c8b080a中合并)

add:添加--chmod=+x / --chmod=-x选项

对于在repository中使用core.filemode为false的路径,将无法检测到可执行位(因此不会设置),尽管用户仍可能希望将文件添加为可执行文件以与其他具有core.filemode功能的用户兼容。
例如,Windows用户添加shell脚本可能希望将它们添加为可执行文件以与非Windows上的用户兼容。

虽然可以使用plumbing命令(git update-index --add --chmod=+x foo)来做到这一点,但教授git-add命令允许用户使用已经熟悉的命令设置文件为可执行文件


3
请确保不要使用GitHub桌面版进行提交,因为它无法识别更改,也无法提交。 - Akaisteph7
@Akaisteph7 很好的观点。我总是自己使用命令行。 - VonC

76
如果文件已经设置了+x 标志,git update-index --chmod=+x 将不起作用,并且 git 认为没有任何可提交的内容,即使标志未保存到存储库中。

您必须首先删除标志,运行 git 命令,然后再将标志放回原处:

chmod -x <file>
git update-index --chmod=+x <file>
chmod +x <file>

然后 Git 发现了更改并允许您提交更改。


提交者所需的 Git 配置(来源:Nabi 的答案):

git config core.filemode false

克隆器所需的git配置:

git config --global core.autocrlf input

3
...太糟糕了!情况还是这样吗? - MrR
我已经这样做了,git看到了变化,我提交并推送到仓库,但当我在其他地方使用该文件时,出现了权限被拒绝的错误...你有什么想法吗?我从仓库下载文件并检查权限,它没有可执行权限... - mrRobot
@mrRobot 检查 git configcore.filemode 应该为 false。如果不是,则运行 git config core.filemode false(参考 Nabi’s answer)。 - Bohemian
@Bohemian,啊,出了点问题。我之前将core.filemode设置为true,然后按照你上面的建议进行操作,结果提交到仓库时带有+x权限。但问题是,AWS beanstalk在克隆该仓库供其使用时,并没有包含+x权限...你有什么想法吗? - mrRobot
1
@Bohemian,也许这个命令可以帮到我:git config --global core.autocrlf input - mrRobot
显示剩余2条评论

28

我在cmd.exe中没有touchchmod命令, 并且git update-index --chmod=+x foo.sh对我不起作用。

最后,我通过设置skip-worktree位来解决了这个问题:

git update-index --skip-worktree --chmod=+x foo.sh

1
需要注意的是,update-index --skip-worktree 命令会告诉 Git 始终忽略 对该文件的未来更改!https://compiledsuccessfully.dev/git-skip-worktree/ - Stefan Zhelyazkov

27

注意首先你必须确保在git配置文件中filemode设置为false,否则使用以下命令:

首先确保在git配置文件中filemode设置为false,或者使用以下命令:

git config core.filemode false

然后你可以使用这个命令设置 0777 权限:

git update-index --chmod=+x foo.sh

8

让我成功运行这个程序的步骤如下:

  1. 不要使用GitHub桌面版来提交代码,因为它无法识别更改,所以无法提交
  2. 在终端中输入 git add --chmod=+x foo.sh
  3. 然后输入 git commit -m"Executable!"

0

根据其他答案,您可能会发现将以下别名添加到您的.gitconfig文件中很有用。

[alias]stage = add
  stagex = add --chmod=+x
  unstage = restore --staged
  setmodx = update-index --chmod=+x

stagex 添加可执行权限位的文件。 setmodx 为已经暂存或提交的文件打开可执行权限。其他别名用于展示这两个命令的作用。


从技术上讲,这不是一个答案,而是“现有答案的额外有用信息”,但遗憾的是Stack Overflow不允许在评论中使用多行代码片段。 - Garret Wilson

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