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

Posted

技术标签:

【中文标题】如何让 Git 忽略文件模式 (chmod) 更改?【英文标题】:How do I make Git ignore file mode (chmod) changes? 【发布时间】:2010-12-07 12:37:27 【问题描述】:

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

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

【问题讨论】:

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

试试:

git config core.fileMode false

来自git-config(1):

core.fileMode
    Tells Git if the executable bit of files in the working tree
    is to be honored.

    Some filesystems lose the executable bit when a file that is
    marked as executable is checked out, or checks out a
    non-executable file with executable bit on. git-clone(1)
    or git-init(1) probe the filesystem to see if it handles the 
    executable bit correctly and this variable is automatically
    set as necessary.

    A repository, however, may be on a filesystem that handles
    the filemode correctly, and this variable is set to true when
    created, but later may be made accessible from another
    environment that loses the filemode (e.g. exporting ext4
    via CIFS mount, visiting a Cygwin created repository with Git
    for Windows or Eclipse). In such a case it may be necessary
    to set this variable to false. See git-update-index(1).

    The default is true (when core.filemode is not specified
    in the config file).

-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 clonegit init 在回购配置中显式设置 core.fileModetrue,如 Git global core.fileMode false overridden locally on clone 中所述

警告

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,您只需为所有存储库执行一次。 这对我不起作用,直到我修复了它应该是 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:“变量名不区分大小写,...”【参考方案2】:

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

【讨论】:

这与top answer 有何不同?【参考方案3】:

简单的解决方案:

在项目文件夹中点击这个简单命令它不会删除您原来的更改) ...它只会删除更改在您更改项目文件夹权限

时已完成

命令如下:

git config core.fileMode false

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

你什么时候会检查你没有做过的改变? 您在使用 git diff filename

时发现如下
old mode 100644
new mode 100755

【讨论】:

【参考方案4】:

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

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

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

git nfm status

【讨论】:

【参考方案5】:

这对我有用:

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

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

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

【讨论】:

这会改变文件的权限,但不会让git忽略文件的文件权限。 嗯,你是对的,这并不能解决 git ignore 的问题。【参考方案6】:

如果你已经使用过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 的步骤。【参考方案7】:

如果您想为所有存储库设置此选项,请使用 --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 的警告更新这个答案!在我发现之前,一切都感觉很疯狂,之后又变得非常合理。【参考方案8】:

你可以全局配置:

git config --global core.filemode false

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

移除你的本地配置,使全局配置生效:

git config --unset core.filemode

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

git config core.filemode false

【讨论】:

如果主要答案对您没有帮助 - 试试这个。如果您想在不修改的情况下检查本地配置,请检查 git config -l(列出当前配置 - 本地和全局) 删除本地配置是全局对我不起作用的原因。谢谢!【参考方案9】:

如果

git config --global core.filemode false

不适合你,手动操作:

cd into yourLovelyProject folder

cd 到 .git 文件夹:

cd .git

编辑配置文件:

nano config

把真改成假

[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 我们应该将文件模式设置回 true 吗? git init 将文件模式返回 TRUE!【参考方案10】:

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

【讨论】:

如果该行不在配置文件中,这将不起作用。如果你想为子模块更改它,试试这个:git submodule foreach git config core.fileMode false【参考方案11】:

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

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

【讨论】:

在 OS X Lion 上,省略 xargs 中的 -d'\n' 部分,因为这是非法参数(并且不需要)。 你可以忽略任何关于“chmod:missing operand after `+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【参考方案12】:

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

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

【讨论】:

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

以上是关于如何让 Git 忽略文件模式 (chmod) 更改?的主要内容,如果未能解决你的问题,请参考以下文章

sh 如何让Git忽略文件模式(chmod)的变化?

Mercurial:忽略文件权限/模式(chmod)更改

让 git 忽略重命名 [重复]

Git忽略文件更改但只有一次?

git如何忽略文件

如何在 Git diff 和 merge 期间忽略某些特定文件和文件夹