为了在提交时自动使.sh
个文件可执行,我做了一个干净的过滤器,并对其结果感到困惑。
首先,我跑了git config filter.executable.clean 'chmod +x %f'
。这会将以下节添加到我的测试存储库的.git/config
文件中:
[filter "executable"]
clean = chmod +x %f
接下来,我创建了一个.gitattributes
文件:
*.sh filter=executable
让我们看看这是怎么回事。当然,新创建的.sh
文件不可执行:
$ touch foo.sh
$ ls -l foo.sh
-rw-r--r-- foo.sh
如果我们add
我们的清洁过滤器应该运行。但是这导致我们工作目录中的可执行文件,我们的暂存区域中的非可执行文件以及脏工作副本!
$ git add foo.sh
$ ls -l foo.sh # As expected
-rwxr-xr-x foo.sh
$ git ls-files -s foo.sh # Confusing
100644 foo.sh
$ git status # Confusing
Changes to be committed:
new file: foo.sh
Changes not staged for commit:
modified: foo.sh
再次运行git add
会导致暂存区域中的可执行文件和干净的工作副本:
$ git add foo.sh
$ git ls-files -s foo.sh
10755 foo.sh
$ git status
Changes to be committed:
new file: foo.sh
这里发生了什么?
答案 0 :(得分:0)
Git的过滤器必须take their input from STDIN and send their output to STDOUT:
结账时,当指定
smudge
命令时,命令从其标准输入中提供blob对象,其标准输出用于更新工作树文件。同样,clean
命令用于在签入时转换worktree文件的内容。
上面显示的过滤器不会以这种方式运行。它忽略STDIN并且它不向STDOUT发送任何输出,因此不会使用第一个git add
命令捕获其效果。暂存文件不可执行。
但是,过滤器会运行。这具有在工作副本中的文件上添加执行位的副作用。 git status
发现该文件的权限已更改。
第二个git add
捕获可执行位,但不是直接因为我们的过滤器。它只是简化它在工作副本中看到的权限更改。
我不知道有任何方法可以通过STDIN和STDOUT修改文件的权限。在干净和污迹过滤器中修改文件权限可能非常困难。