如何恢复文件权限什么git“认为”文件应该是?

我有一个git结帐。 所有的文件权限都不同于git认为他们应该是,因此他们都显示为修改。

如果没有触及文件的内容(只是想修改权限),我如何设置所有的文件权限,以什么git认为他们应该是?

使用git diff -p创build补丁时,Git会跟踪filepermission并显示权限更改。 所以我们需要的是:

  1. 创build一个反向补丁
  2. 只包括权限更改
  3. 将补丁应用到我们的工作副本

作为一个单行:

 git diff -p -R --no-color \ | grep -E "^(diff|(old|new) mode)" --color=never \ | git apply 

你也可以添加它作为你的gitconfiguration的别名…

 git config --global --add alias.permission-reset '!git diff -p -R --no-color | grep -E "^(diff|(old|new) mode)" --color=never | git apply' 

…你可以通过以下方式调用它:

 git permission-reset 

注意,如果你的shell是bash ,请确保在!git周围使用'而不是"引号,否则它会被你运行的最后一个git命令replace。

Thx to @Mixologic指出,通过在git diff上简单地使用-R ,不再需要繁琐的sed命令。

尝试git config core.filemode false

git config手册页:

core.fileMode

如果为false,则索引和工作副本之间的可执行位差异将被忽略; 有用的破碎的文件系统,如FAT。 请参阅git-update-index(1) 。

默认值是true,除非git-clone(1)或者git-init(1)会在创build仓库时探测和设置core.fileMode为false。

Git不存储可执行脚本以外的文件权限。 考虑使用像git-cache-meta这样的东西来保存文件的所有权和权限。

Git只能存储两种模式:755(可执行文件)和644(不可执行文件)。 如果你的文件是444 git会存储它有644。

 git diff -p \ | grep -E '^(diff|old mode|new mode)' \ | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \ | git apply 

将在大多数情况下工作,但如果你有像meld安装的外部diff工具,你必须添加–no-ext-diff

 git diff --no-ext-diff -p \ | grep -E '^(diff|old mode|new mode)' \ | sed -e 's/^old/NEW/;s/^new/old/;s/^NEW/new/' \ | git apply 

在我的情况下是需要的

最简单的做法是只更改权限。 正如@ kroger指出,git只跟踪可执行的位。 所以你可能只需要运行chmod -x filename来修复它(或者+x如果需要的话)。

你也可以尝试一个前/后结帐钩可能会伎俩。

请参阅: 自定义Git – Git钩子

在muhqu的答案中使用的git diff -p可能不会显示所有的差异。

  • 在Cygwin中查看了我没有的文件
  • 如果core.filemodefalse (这是MSysGit的默认值),模式更改将被完全忽略

这段代码直接读取元数据:

 (set -o errexit pipefail nounset; git ls-tree HEAD -z | while read -r -d $'\0' mask type blob path do if [ "$type" != "blob" ]; then continue; fi; case "$mask" in #do not touch other bits 100644) chmod ax "$path";; 100755) chmod a+x "$path";; *) echo "invalid: $mask $type $blob\t$path" >&2; false;; esac done) 

非生产级单线(完全取代口罩):

 git ls-tree HEAD | perl -ne '/^10(0\d{3}) blob \S+\t(.+)$/ && { system "chmod",$1,$2 || die }' 

(信用“$'\ 0'”去http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html

etckeeper工具可以处理权限和:

 etckeeper init -d /mydir 

你可以用它来比其他的dir比/etc etc。

通过使用你的包pipe理器安装或从上面的链接获得来源。