【问题标题】:Git claims files have changed when contents are identical当内容相同时,Git 声明文件已更改
【发布时间】:2020-06-23 22:52:45
【问题描述】:

我正在尝试通过其他人的四次提交来快进我的分支。但是,Git 一直给我这个错误:

error: Your local changes to the following files would be overwritten by merge:
    path/to/file/A
    path/to/file/B
    etc.
Please commit your changes or stash them before you merge.
Aborting

根据How do I ignore an error on 'git pull' about my local changes would be overwritten by merge?,我尝试了git stash push --include-untracked,然后是git stash drop,但这只是导致了同样的错误。

按照Git showing identical files as changed 的答案中的指示,我尝试了rm .git/index; git reset,这确实缩短了 Git 显示为已更改的文件列表,但仍有一些文件存在。 git reset --hard 将“已更改”文件列表恢复为原始大小。

我也尝试过删除 .gitattributes(其中包含 text=auto 行),但文件仍显示为已更改。反正他们的行尾都是LF,所以我怀疑行尾设置会影响这些。

在绝望的时刻,我尝试了git rm -r -f .,它删除了除.git 目录之外的所有内容,但在尝试拉动时,我仍然收到有关这些文件的错误将是覆盖,即使文件被删除。当然,当我执行git reset; git status 时,我已恢复所有文件,并且同一组文件显示为正在更改。

我可以删除整个存储库并重新克隆它,但我想弄清楚发生了什么。是什么导致了这种行为?

【问题讨论】:

  • 这听起来像是 EOL 格式更改。 gut diff 显示什么?
  • 你重新克隆解决问题了吗?
  • @eftshift0 好吧,gut diff 显示 bash: gut: command not found,但 git diff 显示每一行都已删除,然后又添加回来。 “添加”部分中的一些空白行显示了似乎已添加空白的红色条,但 Meld 坚持认为没有区别。
  • 是的,我对gut 不好。当我注意到时已经过去了 5 分钟,所以无法编辑它。如果是这种情况,那肯定是 EOL 格式更改。
  • @ElpieKay 我尝试克隆到另一个目录并在最新提交时拉出分支,效果很好。如果有人有更多建议,我仍然拥有存储库的原始副本以进行故障排除并在此处发布以供其他人使用。

标签: git


【解决方案1】:

反正他们的行尾都是LF,所以我怀疑行尾设置会影响这些。

当然,请检查git config core.autocrlf 的输出。
将其设置为 false:git config --global core.autocrlf false。

然后:git add --renormalize -- :/. (since Git 2.16)

【讨论】:

  • 那行不通。 git config core.autocrlf 的输出是空白的(我相信这意味着它没有设置)并且尝试在 git config --global core.autocrlf false 和 git add --renormalize -- :/. 之后拉动仍然会给出 error: Your local changes to the following files would be overwritten by merge 消息。
  • 我的提示:core.autocrlf 是处理 EOL 格式的旧实现。你应该不使用它,而是使用基于.gitattributes的新实现(甚至告诉git不要弄乱文件的EOL)。 reddit.com/r/git/comments/cqgtgw/…
  • @eftshift0 是的,这就是我明确将其设置为 false 的原因。总是。
  • @MK32 即使在git reset --hard?
  • @VonC 是的,即使是在git reset --hard之后
【解决方案2】:

好的,所以在第三个用户在同一个分支上遇到同样的问题后,我做了更多的挖掘并找到了解决方案。

我们的存储库使用过滤器将 4 个空格的前导集更改为制表符。为了将过滤器应用于每个用户的配置,我编写了一个 Bash 脚本,每个人都应该在开始在存储库中工作之前运行该脚本。这个特定的用户没有运行脚本,所以他没有适当的过滤器。

当我重置存储库的本地版本时,Git 将过滤器应用于文件,这导致前导空格被转换为制表符,并且 Git 在文件中注册了更改。暂时删除过滤器让我可以快进到最新版本的分支。

我仍然不知道为什么 Meld(使用 git difftool 访问)显示没有差异,但是当我从服务器手动下载存储库并根据更改的文件检查这些文件时,Meld 显示了空白更改。

【讨论】:

  • 很好地抓住了那个过滤器。我不会想到那个可能的原因。
猜你喜欢
  • 2011-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-13
  • 2016-05-09
  • 2016-03-23
  • 1970-01-01
相关资源
最近更新 更多