如何在Git的未暂存更改中删除文件,提示为“旧模式100755新模式100644”?

983
由于某种原因,当我最初从git存储库中进行拉取时,我的工作副本中出现了大量文件,这些文件没有可辨别的更改,但仍然出现在我的"未暂存的更改"区域中。
我在Windows XP上使用Git Gui,当我查看文件以查看发生了什么变化时,我只看到:
old mode 100755  
new mode 100644  

有人知道这是什么意思吗?

我该如何将这些文件从我的未暂存更改列表中移除?(必须要浏览几百个文件,才能挑选出最近编辑并想要提交的文件,非常烦人)。


有关core.filemode的全部细节,请参见我的答案。请注意,每个Git存储库都应该有自己的core.filemode设置,在Git创建该存储库时由Git设置;该设置应该是该存储库的正确设置。如果由于某种原因它是错误的,您可以更改它。 - torek
19个回答

1711
那看起来像是Unix文件权限模式(755=rwxr-xr-x644=rw-r--r--)-旧模式包括+x(可执行)标志,新模式没有。这个msysgit问题的回复建议将core.filemode设置为false以摆脱该问题。
git config core.filemode false

174
这意味着Git认为它可以正确地设置检出文件的可执行位,但尝试这样做时它无法正常工作(或者至少无法读取)。然后,当它读回这些文件的状态时,看起来可执行位被有意地取消了。将core.filemode设置为false告诉Git忽略文件系统上任何可执行位的更改,因此它不会将其视为更改。如果您确实需要暂存可执行位更改,则必须手动执行git update-index --chmod=(+|-)x <path> - CB Bailey
10
如果像我一样,对文件的模式变化很重要,你可以将core.filemode设为false,提交实际的代码变化,然后将core.filemode设置为true,Git会保留文件的变化。 - Michael T. Smith
9
我有相同的问题,但是是因为我通过SSH git命令行和在Windows上映射的驱动器中使用Git Extensions访问了相同的git仓库!解决方案相同,在"config" [core]文件中添加以下内容:filemode = false。 - Ian Vaughan
9
你可以使用 git config --global ... 命令在全局配置文件中设置选项。 - Amber
4
您可以使用 git config -l --show-origin 命令查看每个配置项的来源。 - Khouri Giordano
显示剩余14条评论

123
设置core.filemode为false是有效的,但请确保~/.gitconfig中的设置没有被.git/config中的设置覆盖。
要确定core.filemode设置的来源,请从存储库的根文件夹(或根文件夹下的任何文件夹)运行以下命令(适用于任何操作系统): git config --show-origin --show-scope --get-all core.filemode

3
曾经经历过,已经完成了。可惜在自己解决问题之后才看到了你的评论。不过还是点个赞! - David Schmitt
1
如果其他用户正在克隆此项目并且使用的是Windows操作系统,最好直接将更改应用于“~/.gitconfig”文件! - Ian Vaughan
如果您想在Windows Powershell上进行检查,请使用以下命令:git config --list --show-origin | sls filemode。如果您在Linux上,则需要使用以下命令:git config --list --show-origin | grep filemode。这将向您展示需要进行调整的位置。 - Frank Fu
core.filemode 设置应该在每个 .git/config 中设置。每当 Git 创建一个新的仓库时,无论是 git clone 还是 git init,它都会根据您的操作系统和文件系统自动创建。它不应该出错,但如果出现问题,那么就需要在特定的仓库中进行设置修复。 - torek

83

当仓库在Windows和Linux/Unix机器之间克隆时,通常会出现此问题。

只需告诉 Git 忽略文件模式更改即可。以下是几种方法:

  1. 仅为当前仓库设置:

 git config core.filemode false
  • 全局配置:

     git config --global core.filemode false
    
  • 在 ~/.gitconfig 中添加:

  •  [core]
          filemode = false
    

    只需选择其中一个。


    4
    全局配置无法生效,因为(我猜)git使用这些选项创建了一个仓库(我在Linux上创建了一个仓库)。 - IC_
    这些更改需要何时应用? - KansaiRobot

    54

    我在多次从旧硬盘复制带有工作文件的git仓库时遇到了这个问题。问题源于所有者和权限从旧驱动器/机器变更为新驱动器/机器。长话短说,运行以下命令来解决问题(感谢这个超级用户的回答):

    sudo chmod -R -x . # remove the executable bit from all files
    

    先前的命令会实际解决git diff报告的差异,但会取消您列出目录的权限,因此ls ./将失败并显示ls: .: Permission denied。要解决这个问题:

    sudo chmod -R +X . # add the executable bit only for directories
    

    不好的消息是,如果您有任何想要保留可执行文件的文件,例如.sh脚本,您需要还原这些文件。您可以为每个文件使用以下命令来执行此操作:

    坏的消息是,如果您有任何要保持可执行状态的文件(例如 .sh 脚本),那么您将需要将它们还原回去。您可以使用以下命令对每个文件进行操作:

    chmod +x ./build.sh # where build.sh is the file you want to make executable again
    

    3
    谢谢,你帮了我很多!还应该检查一下 git config core.filemode 是否设置为 true,否则权限更改将不会被检测到。每次更改后,我还需要刷新 git 索引以使更改生效。 - pat-s
    我遇到这个问题的原因正如在这里描述的一样:当我换了新电脑后,我把所有的项目都转移到了另一个硬盘上。谢谢。 - philburns
    +1,这将恢复目录和文件到它们之前的状态,而不是像顶部答案建议的那样忽略问题。 - undefined

    17

    3
    它是做什么的? - Goddard
    这太棒了!它可以找到所有权限被更改的文件并还原更改的权限,而不影响其他任何东西。谢谢! - Hans Deragon
    是的,这个方法非常有效。如果有任何标记为“D”(已删除)的文件,您需要先处理它们,然后再应用此解决方案。 - George Pligoropoulos

    12

    这对我有用:

    git ls-files -m | xargs -L 1 chmod 644
    

    1
    你能解释一下这个代码的作用吗?谢谢。 - philburns
    1
    这将包括已删除的文件,因此一旦遇到已删除的文件就会失败。 - riley

    8

    git config core.filemode false 设置为接受的答案确实可行,但会带来一些后果。将 core.filemode 设置为 false 告诉 git 忽略文件系统上任何可执行位的更改,因此它不会将其视为变更。如果您在将来的某个时间需要为此存储库暂存可执行位更改,则必须手动执行或将 core.filemode 设置回 true。

    如果所有修改后的文件都应具有模式 100755,则可选择较小的替代方案,例如执行以下操作:

    chmod 100755 $(git ls-files --modified)
    

    这只是简单地更改模式,没有其他含义或影响。

    (在我的情况下,因为 OneDrive 在我的 MacOS 文件系统上进行同步导致了这个问题;如果不更改 core.filemode,那么将来可能会再次出现模式更改的情况;对我而言,如果它再次出现,我想知道,而更改 core.filemode 将隐藏它,这不是我想要的)


    5

    这个解决方案将把git文件权限从100755更改为100644,并将更改推送回bitbucket远程仓库。

    1. 查看您的Repo文件权限:git ls-files --stage

    2. 如果是100755,而你想要100644

      那么运行这个命令: git ls-files --stage | sed 's/\t/ /g' | cut -d' ' -f4 | xargs git update-index --chmod=-x

    3. 现在再次检查您的Repo文件权限:git ls-files --stage

    4. 现在提交您的更改:

      git status
      git commit -m "恢复适当的文件权限"
      git push
      

    3

    当你拉取代码时,如果所有文件在远程仓库中都是可执行的,这种情况就会出现。重新让这些文件可执行就能恢复正常了。

    chmod +x <yourfile> //For one file
    chmod +x folder/* // For files in a folder
    

    您可能需要执行以下操作:

    chmod -x <file> // Removes execute bit
    

    相反,对于未设置为可执行文件并因上述操作而更改的文件,有更好的方法来解决此问题。但这只是一个非常快速和简单的临时解决方案。


    是的,但这会创建一个需要稍后提交的更改,对吗? - KansaiRobot

    3

    看起来您更改了某个目录的权限。我执行了以下步骤来恢复它。

    $  git diff > backup-diff.txt                ### in case you have some other code changes 
    
    $  git checkout .
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接