出于某种原因,当我最初从存储库中提取我的一个 git 项目时,我的工作副本中有大量文件没有对它们进行可识别的更改,但仍然出现在我的 unstaged changes
区域中。
我在 Windows xp 上使用 Git Gui,当我去查看文件以查看发生了什么变化时。我所看到的是:
old mode 100755
new mode 100644
有谁知道这意味着什么?
如何将这些文件从我的未暂存更改列表中取出? (非常烦人必须浏览 100 个文件,只是为了挑选出我最近编辑并想要提交的文件)。
core.filemode
的完整详细信息,请参阅 my answer here。请注意,每个 Git 存储库都应该有自己的 core.filemode
设置,由 Git 在 Git 创建该存储库时设置;该设置应该是该存储库的正确设置。如果由于某种原因出错,您可以更改它。
对我来说,这看起来像是 unix 文件权限模式(755
=rwxr-xr-x
, 644
=rw-r--r--
) - 旧模式包含 +x(可执行)标志,新模式不包含。
This msysgit issue's replies 建议将 core.filemode 设置为 false 以解决此问题:
git config core.filemode false
将 core.filemode
设置为 false 确实有效,但请确保 ~/.gitconfig
中的设置不会被 .git/config
中的设置覆盖。
~/.gitconfig
文件!
git config --list --show-origin | sls filemode
或在 Linux git config --list --show-origin | grep filemode
上。这将显示您需要在哪里进行调整。
core.filemode
设置应该在每个 .git/config
中设置。它会在 Git 在 git clone
或 git init
期间根据您的操作系统和文件系统的工作方式创建新存储库时自动创建。它不应该是错误的,但如果是,那就是修复设置的地方:在一个特定的存储库中。
这通常在 Windows 和 Linux/Unix 机器之间克隆 repo 时发生。
只需告诉 git 忽略文件模式更改。这里有几种方法可以做到这一点:
仅针对当前 repo 配置: git config core.filemode false 全局配置: git config --global core.filemode false 添加 ~/.gitconfig: [core] filemode = false
只需选择其中之一。
在从旧硬盘复制带有工作文件的 git repo 几次时,我遇到了这个问题。问题源于所有者和权限从旧驱动器/机器更改为新驱动器/机器的事实。总而言之,运行以下命令来理顺事情(thanks to this superuser answer):
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
脚本,则需要恢复这些文件。您可以对每个文件使用以下命令执行此操作:
chmod +x ./build.sh # where build.sh is the file you want to make executable again
git config core.filemode
是否设置为 true
,否则不会检测到权限更改。我还需要在每次更改后刷新 git 索引以获取它。
这对我有用:
git ls-files -m | xargs -L 1 chmod 644
我遇到了同样的问题。这救了我的命:
这会将所有权限恢复为差异,因此您将一无所有,但您对文件所做的更改。
https://gist.github.com/jtdp/5443498
git diff -p -R --no-color \
| grep -E "^(diff|(old|new) mode)" --color=never \
| git apply
https://stackoverflow.com/a/4408378/450383 中的更多详细信息
您似乎更改了目录的某些权限。我做了以下步骤来恢复它。
$ git diff > backup-diff.txt ### in case you have some other code changes
$ git checkout .
设置 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
会将它隐藏起来,我不想要)
此解决方案会将 git 文件权限从 100755 更改为 100644,并将更改推送回 bitbucket 远程仓库。
看看你的 repo 的文件权限: git ls-files --stage 如果 100755 并且你想要 100644
然后运行这个命令: git ls-files --stage | sed 's/\t/ /g' |剪切-d''-f4 | xargs git update-index --chmod=-x
现在再次检查您的 repo 的文件权限: git ls-files --stage 现在提交您的更改:
状态
git commit -m "恢复了正确的文件权限"
git 推送
您可以尝试 git reset --hard HEAD 将 repo 重置为预期的默认状态。
git reset --hard HEAD
非常适合我。谢谢
当您拉取并且所有文件在远程存储库中都是可执行的时,就会发生这种情况。再次使它们可执行将使一切恢复正常。
chmod +x <yourfile> //For one file
chmod +x folder/* // For files in a folder
您可能需要这样做:
chmod -x <file> // Removes execute bit
相反,对于未设置为可执行文件并且由于上述操作而更改的文件。有一种更好的方法可以做到这一点,但这只是一个非常快速和肮脏的修复。
您可以使用以下命令将文件模式更改回来。 git add --chmod=+x -- filename
然后提交到分支。
这就像 bkm 发现的一样,但它也考虑了所有已删除的文件,并且在仍然应用更改时只发出警告。
这可以很好地从以前的提交中恢复文件模式设置。
git diff -p --no-ext-diff --no-color --diff-filter=d | grep -E "^(diff|old mode|new mode)" | sed -e "s/^old/NEW/;s/^new/old/;s/^NEW/new/" | git apply
我只有一个权限已更改的麻烦文件。要单独回滚,我只是使用 rm <file>
手动删除它,然后进行结帐以提取新副本。
幸运的是我还没有上演它。
如果我有,我可以在运行 git checkout -- <file>
之前运行 git reset -- <file>
我在将我的分支与 master 进行比较时遇到了这个问题。当我期望我的分支与 master 相同时,Git 返回了一个“模式”错误。我通过删除文件然后再次合并主文件来修复。
首先我运行了差异:
git checkout my-branch
git diff master
这返回:
diff --git a/bin/script.sh b/bin/script.sh
old mode 100755
new mode 100644
然后我运行以下修复:
rm bin/script.sh
git merge -X theirs master
在此之后,git diff
没有返回 my-branch 和 master 之间的差异。
theirs
是什么?
如果有任何已删除的文件,上述许多解决方案都会中断。
这将列出仅被修改的文件,而不是被删除的文件,并将它们全部更改为 755
git diff-files --name-only --diff-filter=d | xargs -L 1 chmod 755
git update-index --chmod=(+|-)x <path>
。git config --global ...
在全局配置文件中设置选项。git config -l --show-origin
查看每个设置的来源。