自动对可执行文件应用“git update-index --chmod=+x”

87

我经常将Bash脚本添加到我的Git仓库中,这些脚本在git add之前在Linux文件系统中具有可执行权限。但是,在将添加的文件推送到远程仓库并在另一个位置拉取后,这些文件的权限变为非可执行权限。似乎有两种方法可以解决这个问题:

  1. chmod u+x $script 
    git commit -am "fixing the script permissions... again..."
    
  2. git update-index --chmod=+x $script
    

有没有一种方法能让Git在git add期间查看脚本的文件权限、认识到"嘿,这是一个可执行文件!"并直接添加可执行权限到仓库中,而不必每次都修复文件权限?


两个位置都在运行Linux,因此不存在“filemode=false”的问题。我认为这是Git的正常行为——我只是在寻找某种跳过手动修复步骤的方法。 - Byron Hawkins
githooks man页有指针。 - jthill
啊,没问题 :-) 在我的两台机器上都设置了filemode=true,所以我不明白为什么Git要放弃x位。这两台机器都在Intel的普通Ubuntu 12.04上运行。其中一台机器的文件系统是NFS,另一台机器则是VirtualBox中的共享文件夹,如果有区别的话。希望会有人过来给我指点迷津。 - Byron Hawkins
3
很快,随着git 2.9/2.10(2016年第3季度)的发布,一个简单的git add --chmod=+x就足够了!请参见下面的我的答案 - VonC
5
如果这可以成为.gitattributes规范的一部分,那将很棒。比如说... *.sh text eol=lf chmod=+x - Anthony Mastrean
显示剩余5条评论
7个回答

47

git 2.9.X/2.10 (Q3 2016)版本为git add带来了chmod功能!

参见提交记录 4e55ed3(由Edward Thomson(ethomson)于2016年5月31日提交)。
协助者:Johannes Schindelin (dscho).
(合并者为Junio C Hamano -- gitster --,于提交记录 c8b080a,于2016年7月6日)

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

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

虽然可以通过管道命令 (git update-index --add --chmod=+x foo) 实现,但使用git-add命令让用户能够用他们已经熟悉的命令来设置文件为可执行状态

你可以在 "How to create file execute mode permissions in Git on Windows?" (Feb. 2011) 中看到这个新功能的来源。


24

有几种方法可以实现这一点。

  1. Git别名
  2. Bash别名
  3. 甚至可以将Bash和Git别名结合起来使用

  1. Git别名

    您始终可以在Git别名中使用Bash。

    • 打开您的Git配置文件:

      vim ~/.gitconfig

    • 添加一个别名部分(如果不存在):

      [alias]
          addscr = !sh -c 'if [[ ${0: -3} == ".sh" ]]; then git update-index --chmod=+x $0; git add $0'
      
  2. Bash别名

    • 编辑你的bash配置文件:

      vim ~/.bashrc

    • 在文件结尾处添加以下内容:

      function gitadd(){
          if [[ ${1: -3} == ".sh" ]]
              then git update-index --chmod=+x $1
          fi
          git add $1
       }
       alias gitadd='gitadd'
      
  3. 将git和bash别名结合起来

    • 编辑你的bash配置文件:

      vim ~/.bashrc

    • 在文件末尾添加以下内容:

      function checkShellFile(){
          return ${1: -3} == ".sh"
      }
      alias gitadd='checkShellFile ? git addsrcipt "$1" : && git add "$1"'
      
    • 编辑你的git配置文件:

      vim ~/.gitconfig

    • 如果不存在,就在其中添加一个别名部分:

      [alias]
          addscript = !sh -c 'git update-index --chmod=+x $0 && git add $0'
      

以上内容均未经过测试


1
不查资料:是否可以按存储库为基础进行此操作?对于构建代理,我想事先知道所有检出都保证了正确的权限... :) - helmesjo
这是否意味着从那时起,您必须使用别名addscr,即git addscr而不是git add - Steve Gon

9
这是一个脚本,用于自动将git update-index --chmod+x应用于可执行文件:
for f in $(find . -name '*.sh' -o -regex './s?bin/[^/]+' -o -regex './usr/sbin/[^/]+' -o -regex './usr/lib/[^/]+'); do
     (cd "$(dirname $f)" && git update-index --chmod=+x "$(basename $f)")
done

9
一个没有花哨的bash脚本解决方案:
  1. 在你的.git/config文件中设置fileMode = true(或者像其他人指出的那样运行git config core.filemode true)。
  2. 更改文件权限的可执行位并提交此更改。(如你所示,chmod u+x $script)。你只需要这样做一次。
  3. 推送到远程。
下一次从那里拉取时,git将设置提交的可执行位。我也遇到了类似的问题,这个解决了。 fileMode = true告诉git跟踪它能够跟踪的有关权限的唯一内容:可执行位。这意味着可执行位的更改将被git视为工作树中的更改,并且这些更改将与下一次提交一起存储在仓库中。
一旦你提交了期望的可执行位,你还可以将你的fileMode重置为false,这样下一次当你不想提交它们时,git就不会再打扰你了。

2
我认为这不能在git add命令上完成,但你可能可以在运行git commit命令之后,在提交实际创建之前运行脚本。请查看pre-commit hook。

http://git-scm.com/book/en/Customizing-Git-Git-Hooks

基本上只需在您的.git/hooks/文件夹中创建一个名为pre-commit的文件即可。 (您的hooks文件夹中应该已经有示例,将它们重命名以去掉末尾的“.sample”以激活其中一个。)
注意:确保您的脚本首先运行git stash -q,以便您可以在实际暂存版本的文件上工作。

https://github.com/pre-commit/pre-commit-hooks/blob/main/pre_commit_hooks/check_shebang_scripts_are_executable.py - Eric Roller

0

如果您使用的是Windows/Powershell,只需相应更改路径和筛选条件:

Get-ChildItem -Path . -Filter '*.py' -Recurse | Select-Object { git -update-index --chmod=+x $_.Name }

0

我刚刚通过Tortoise Git文件夹更新添加了内容。右键单击所有文件并将执行权限复选框更新为true,然后提交/推送消息。Git命令行add/commit也可以使用。


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