ChatGPT解决这个技术问题 Extra ChatGPT

如何让 Git 忽略文件模式 (chmod) 更改?

我有一个项目,我必须在开发时将带有 chmod 的文件模式更改为 777,但不应在主仓库中更改。

Git 选择 chmod -R 777 . 并将所有文件标记为已更改。有没有办法让 Git 忽略对文件所做的模式更改?

在 Windows 上使用 git + 在 Ubuntu 上使用 git 时,这很有帮助
对于只想忽略特定调用 git diff 的权限更改并因此不想更改其 Git 配置文件的任何人:您可以根据 Zed's 答案 here 使用 git diff -G.

T
Trevor Boyd Smith

尝试:

git config core.fileMode false

git-config(1)

core.fileMode 告诉 Git 工作树中文件的可执行位是否要被接受。某些文件系统在签出标记为可执行文件的文件时会丢失可执行位,或者签出带有可执行位的不可执行文件。 git-clone(1) 或 git-init(1) 探测文件系统以查看它是否正确处理可执行位,并且此变量会根据需要自动设置。但是,存储库可能位于正确处理文件模式的文件系统上,并且此变量在创建时设置为 true,但稍后可能会从丢失文件模式的另一个环境访问(例如,通过 CIFS 挂载导出 ext4,访问 Cygwin使用 Git for Windows 或 Eclipse 创建存储库)。在这种情况下,可能需要将此变量设置为 false。请参阅 git-update-index(1)。默认值为 true(当配置文件中未指定 core.filemode 时)。

-c 标志可用于为一次性命令设置此选项:

git -c core.fileMode=false diff

键入 -c core.fileMode=false 可能很麻烦,因此您可以为所有 git 存储库或仅为一个 git 存储库设置此标志:

# this will set your the flag for your user for all git repos (modifies `$HOME/.gitconfig`)
git config --global core.fileMode false

# this will set the flag for one git repo (modifies `$current_git_repo/.git/config`)
git config core.fileMode false

此外,如 Git global core.fileMode false overridden locally on clone 中所述,git clonegit init 在 repo 配置中将 core.fileMode 显式设置为 true

警告

core.fileMode 不是最佳做法,应谨慎使用。此设置仅涵盖模式的可执行位,而不涵盖读/写位。在许多情况下,您认为需要此设置是因为您执行了 chmod -R 777 之类的操作,使您的所有文件都可执行。但在大多数项目中,出于安全原因,大多数文件不需要也不应该是可执行文件

解决这种情况的正确方法是分别处理文件夹和文件权限,例如:

find . -type d -exec chmod a+rwx {} \; # Make folders traversable and read/write
find . -type f -exec chmod a+rw {} \;  # Make files read/write

如果您这样做,您将永远不需要使用 core.fileMode,除非在非常罕见的环境中。


如果您执行 git config --global core.filemode false,您只需为所有 repos 执行一次。
在我修复了应该是 fileMode 而不是 filemode 的情况之前,这对我不起作用
@tishma:Git 配置部分和变量名是 case insensitive according to the documentation, see the CONFIGURATION FILE section,所以如果上面的方法对你不起作用,那是因为不同的原因。
@donquixote:git config 命令将设置写入正确的配置文件(.git/config 仅用于当前存储库,或者 ~/.gitconfig 如果与 --global 一起使用)。
@zx1986:没关系。来自 git config:“变量名不区分大小写,...”
A
Afriza N. Arief

撤消工作树中的模式更改:

git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -d'\n' chmod +x
git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -d'\n' chmod -x

或者在 mingw-git

git diff --summary | grep  'mode change 100755 => 100644' | cut -d' ' -f7- | xargs -e'\n' chmod +x
git diff --summary | grep  'mode change 100644 => 100755' | cut -d' ' -f7- | xargs -e'\n' chmod -x

或者在 BSD/macOS 中

git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x
git diff --summary | grep --color 'mode change 100755 => 100644' | cut -d' ' -f7- | tr '\n' '\0' | xargs -0 chmod -x

在 OS X Lion 上,省略 xargs 中的 -d'\n' 部分,因为这是一个非法参数(并且不需要)。
您可以忽略任何有关“chmod:‘+x’后缺少操作数”的错误
这是最新的吗?我在 mingw 中得到“chmod:参数太少”
@Pascal @pimlottc -d 将分隔符指定为换行符而不是任何空格。 BSD xargs 没有该选项,但您可以通过 tr '\n' '\0' 管道输出,然后使用 -0 arg 到 xargs 以使用 NUL 作为分隔符。
太棒了,tr 的事情奏效了!这是 OSX 的完整命令:git diff --summary | grep --color 'mode change 100644 => 100755' | cut -d' ' -f7-|tr '\n' '\0'|xargs -0 chmod -x
A
Arslan Ali

如果要为所有存储库设置此选项,请使用 --global 选项。

git config --global core.filemode false

如果这不起作用,您可能正在使用较新版本的 git,因此请尝试 --add 选项。

git config --add --global core.filemode false

如果你在没有 --global 选项的情况下运行它并且你的工作目录不是一个 repo,你会得到

error: could not lock config file .git/config: No such file or directory

看起来以后的 GIT 使用 --add,如 git config --add --global core.filemode false
如果 repo 的本地配置已经具有 filemode=true 则更改全局配置将无济于事,因为本地配置将覆盖全局配置。将不得不更改机器的每个 repo 的本地配置一次
请:用 syedrakib 的警告更新这个答案!在我发现它之前,一切都感觉很疯狂,之后又变得完全合理。
S
Sinan Eldem

如果

git config --global core.filemode false

对您不起作用,请手动执行:

cd into yourLovelyProject folder

cd 进入 .git 文件夹:

cd .git

编辑配置文件:

nano config

将 true 更改为 false

[core]
        repositoryformatversion = 0
        filemode = true

->

[core]
        repositoryformatversion = 0
        filemode = false

保存,退出,进入上层文件夹:

cd ..

重新初始化 git

git init

你完成了!


无需编辑 .git/config,只需在项目的根目录中添加一个简单的 git config core.fileMode false 即可。如果您编辑配置文件,最好完全删除该指令,以便获取全局指令。
-1 如果 git config --global 不起作用,则意味着您没有在系统级别执行此操作的权限,删除 global 选项与手动编辑 .git/config 完全相同
@CharlesB 不正确 - 答案提供了一种解决方法,将选项直接放在项目中,使其特定于项目。这不适用于您将来制作/结帐的其他 git 项目,但适用于您正在处理的项目。 (让我们确保我们消除了 ~/.gitconfig~/project/.git/config 的歧义)
运行 git init 后,我们应该将 filemode 设置回 true 吗?
git init 将文件模式返回 TRUE!
C
Community

添加到 Greg Hewgill answer(使用 core.fileMode 配置变量):

您可以使用 git update-index--chmod=(-|+)x 选项(“git add”的低级版本)来更改索引中的执行权限,如果您使用“git commit”(而不是“git commit -一个”)。


这应该已被编辑到 Greg Hewgill 的答案中,而不是作为单独的答案添加,从而创建一个具有单一明确表示的最高答案。
@Greg:需要有足够的分数来编辑不是自己的答案;我想我当时没有足够的编辑权限。
@Jakub 我认为你现在有足够的声誉:) 这个命令对于示例文件会是什么样子?
T
Tyler Liu

您可以全局配置它:

git config --global core.filemode false

如果上述方法对您不起作用,原因可能是您的本地配置覆盖了全局配置。

删除本地配置,使全局配置生效:

git config --unset core.filemode

或者,您可以将本地配置更改为正确的值:

git config core.filemode false


如果主要答案对您没有帮助 - 试试这个。如果您想检查本地配置而不修改它,请检查 git config -l(列出当前配置 - 本地和全局)
删除本地配置是 global 对我不起作用的原因。谢谢!
K
Kishor Vitekar

如果您已经使用过 chmod 命令然后检查文件的差异,它显示以前的文件模式和当前的文件模式,例如:

新模式:755

旧模式:644

使用以下命令设置所有文件的旧模式

sudo chmod 644 .

现在使用命令或手动在配置文件中将 core.fileMode 设置为 false。

git config core.fileMode false

然后应用 chmod 命令更改所有文件的权限,例如

sudo chmod 755 .

并再次将 core.fileMode 设置为 true。

git config core.fileMode true

对于最佳实践,不要始终保持 core.fileMode 为 false。


您是说整个项目(在开发、暂存和生产中)应该是 755 吗?
@Daniel Feb:不。仅更改必要文件的模式。
For best practises don't Keep core.fileMode false always 你是什么意思,你应该解释一下。
For best practises don't Keep core.fileMode false always. 某些文件系统(例如 FAT)不支持文件权限,因此操作系统会报告一个默认值(无论如何在我的系统上都是 766)。在这种情况下,core.filemode 在本地配置中是绝对必要的,除非您想通过不必要和无意的权限更改来膨胀提交历史记录
另外,你为什么还要费心把烫发改回来呢?如果设置 core.filemode=false 则 git 将忽略执行位更改,无需更改本地权限。除非您已经向索引添加了权限更改,否则您会错过关闭 core.filemode 后需要执行 git add 的步骤。
T
Tomasz Gandor

通过定义以下别名(在 ~/.gitconfig 中),您可以轻松地暂时禁用每个 git 命令的 fileMode:

[alias]
nfm = "!f(){ git -c core.fileMode=false $@; };f"

当此别名作为 git 命令的前缀时,文件模式更改将不会与原本会显示它们的命令一起显示。例如:

git nfm status

为什么不只是一个预提交钩子而不是一个可忘记的参数?
R
Rey0bs

如果您想在配置文件中递归地将文件模式设置为 false(包括子模块):find -name config | xargs sed -i -e 's/filemode = true/filemode = false/'


如果该行不在配置文件中,这将不起作用。如果您想为子模块更改它,请尝试以下操作:git submodule foreach git config core.fileMode false
0
0xC0000022L

简单的解决方案:

在项目文件夹中点击此简单命令(它不会删除您的原始更改)...它只会删除在您更改项目文件夹权限时所做的更改

命令如下:

git config core.fileMode false

为什么要修改所有不必要的文件:因为您已使用推荐更改了项目文件夹权限 sudo chmod -R 777 ./yourProjectFolder

你什么时候会检查你没有做过的改变?您在使用 git diff 文件名时发现如下

old mode 100644
new mode 100755

M
Martin Volek

这对我有用:

find . -type f -exec chmod a-x {} \;

或反向,具体取决于您的操作系统

find . -type f -exec chmod a+x {} \;

这会改变文件的权限,但不会让 git 忽略文件的文件权限。
好吧,你是对的,这并不能解决 git ignore 的事情。
佚名

这可能有效:git config core.fileMode false


这与 top answer 有何不同?
D
Daniel Reis

您不需要更改配置文件。

赶紧跑:

git diff -G.

B
Badr Bechtioui

如果您设置:sudo chmod 777 -R

你可以运行:git config core.fileMode false

你可以看到:https://www.w3docs.com/snippets/git/how-to-make-git-ignore-file-mode-changes.html


y
yadeem

我被这个问题困扰了好几天,在阅读了@Daniel Reis 的答案后最终解决了这个问题。但我需要强调一点:

git diff -G.

尾随点不是句子的结尾,而是匹配所有内容的正则表达式。你必须包括这个点!!!

这是一个无法评论的新帐户。我必须打开一个新的答案。

再次,非常感谢丹尼尔!