git git中文件和目录被修改后如何恢复权限?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2517339/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 08:07:54  来源:igfitidea点击:

How to restore the permissions of files and directories within git if they have been modified?

gitfilefile-permissions

提问by Dale Forester

I have a git checkout. All the file permissions are different than what git thinks they should be therefore they all show up as modified.

我有一个 git 结帐。所有文件权限都与 git 认为的不同,因此它们都显示为已修改。

Without touching the content of the files (just want to modify the permissions) how do I set all the files permissions to what git thinks they should be?

在不触及文件内容的情况下(只想修改权限)如何将所有文件权限设置为 git 认为它们应该是什么?

回答by muhqu

Git keeps track of filepermission and exposes permission changes when creating patches using git diff -p. So all we need is:

Git 会跟踪文件权限并在使用git diff -p. 所以我们只需要:

  1. create a reverse patch
  2. include only the permission changes
  3. apply the patch to our working copy
  1. 创建反向补丁
  2. 仅包括权限更改
  3. 将补丁应用到我们的工作副本

As a one-liner:

作为单线:

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

you can also add it as an alias to your git config...

您还可以将其作为别名添加到您的 git 配置中...

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

...and you can invoke it via:

...您可以通过以下方式调用它:

git permission-reset

Note, if you shell is bash, make sure to use 'instead of "quotes around the !git, otherwise it gets substituted with the last gitcommand you ran.

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

Thx to @Mixologic for pointing out that by simply using -Ron git diff, the cumbersome sedcommand is no longer required.

感谢@Mixologic 指出通过简单地使用-Ron git diffsed不再需要繁琐的命令。

回答by Tim Henigan

Try git config core.fileMode false

尝试 git config core.fileMode false

From the git configman page:

git config手册页:

core.fileMode

If false, the executable bit differences between the index and the working copy are ignored; useful on broken filesystems like FAT. See git-update-index(1).

The default is true, except git-clone(1) or git-init(1) will probe and set core.fileMode false if appropriate when the repository is created.

core.fileMode

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

默认为 true,除了 git-clone(1) 或 git-init(1) 将在创建存储库时探测并设置 core.fileMode 为 false。

回答by kroger

Git doesn't store file permissions other than executable scripts. Consider using something like git-cache-metato save file ownership and permissions.

除了可执行脚本之外,Git 不存储文件权限。考虑使用git-cache-meta 之类的东西来保存文件所有权和权限。

Git can only store two types of modes: 755 (executable) and 644 (not executable). If your file was 444 git would store it has 644.

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

回答by zainengineer

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

will work in most cases but if you have external diff tools like meld installed you have to add --no-ext-diff

在大多数情况下都可以使用,但是如果您安装了像 meld 这样的外部差异工具,则必须添加 --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

was needed in my situation

在我的情况下需要

回答by alijandro

I use git from cygwin on Windows, the git applysolution doesn't work for me. Here is my solution, run chmodon every file to reset its permissions.

我在 Windows 上使用来自 cygwin 的 git,该git apply解决方案对我不起作用。这是我的解决方案,chmod在每个文件上运行以重置其权限。

#!/bin/bash
IFS=$'\n'
for c in `git diff -p |sed -n '/diff --git/{N;s/diff --git//g;s/\n/ /g;s# a/.* b/##g;s/old mode //g;s/\(.*\) 100\(.*\)/chmod  /g;p}'`
do
        eval $c
done
unset IFS

回答by Doug

You could also try a pre/post checkout hook might do the trick.

您也可以尝试使用 pre/post checkout hook 来解​​决问题。

See: Customizing Git - Git Hooks

请参阅:自定义 Git - Git Hooks

回答by Pat Notz

The easiest thing to do is to just change the permissions back. As @kroger noted git only tracks executable bits. So you probably just need to run chmod -x filenameto fix it (or +xif that's what's needed.

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

回答by ivan_pozdeev

git diff -pused in muhqu's answermay not show all discrepancies.

git diff -pmuhqu 的回答中使用可能不会显示所有差异。

  • saw this in Cygwin for files I didn't own
  • mode changes are ignored completely if core.filemodeis false(which is the default for MSysGit)
  • 在 Cygwin 中看到了我不拥有的文件
  • 如果core.filemodefalse(这是 MSysGit 的默认设置),则完全忽略模式更改

This code reads the metadata directly instead:

此代码直接读取元数据:

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

A non-production-grade one-liner (replaces masks entirely):

非生产级单衬(完全替代口罩):

etckeeper init -d /mydir

(Credit for "$'\0'" goes to http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html)

(“$'\0'”的学分转到http://transnum.blogspot.ru/2008/11/bashs-read-built-in-supports-0-as.html

回答by MoreIT

The etckeepertoolcan handle permissions and with:

etckeeper工具可以处理权限并具有:

##代码##

You can use it for other dirs than /etc.

您可以将它用于除/etc.

Install by using your package manager or get sources from above link.

使用您的包管理器安装或从上面的链接获取源。