git reset --hard 后出现了未暂存的更改

407

执行了 git reset --hard 后,git status 会在 Changes not staged for commit: 部分列出文件。

我还尝试了 git reset .git checkout -- .git checkout-index -f -a,但都无济于事。

那么,如何才能摆脱这些未暂存的更改呢?

这似乎只影响 Visual Studio 项目文件。奇怪。请参见此粘贴: http://pastebin.com/eFZwPn9Z。这些文件的特殊之处在于,在 .gitattributes 中我有:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

另外,我的全局 .gitconfigautocrlf 被设置为 false。这是否有相关性呢?


你是在代码库的根目录下执行这些命令吗?注意 . 代表当前目录,而不是根目录。 - Alexander
1
我确实是从根仓库中进行了这些操作。 - Norswap
你的git版本是什么?你要么犯了一个愚蠢的错误,要么你的版本过旧并且存在漏洞。 - Shahbaz
这是git 1.7.4 msysgit。可能有错误,但命令似乎足够简单,我找不到错误。 - Norswap
同样的问题,我在一台机器上(Windows)添加了 .gitattributes,现在在另一台机器上(Linux),从主仓库pull之后,某些文件出现了修改,即那些具有 eol=crlf 的文件... - szx
显示剩余3条评论
22个回答

5

对于我来说,这些方法都没有起作用,唯一的解决方案就是彻底删除整个存储库并重新克隆。这包括隐藏、重置、添加然后重置、clrf设置、大小写敏感等。唉..


更新,事实证明我挂载的区分大小写的文件系统实际上并不区分大小写。在我修复了这个问题之后,可以使用上述技术来解决这个问题。 - John Hunt

4
请检查您的.gitattributes文件。
在我的情况下,我在其中有*.js text eol=lf,并且git选项core.autocrlf设置为true
这导致了这样一种情况:Git自动转换了我的文件行尾,并防止我进行修复,即使使用git reset --hard HEAD也无济于事。
我通过在.gitattributes文件中注释掉*.js text eol=lf来解决它,然后再取消注释。
看起来似乎只是Git的魔力。

1
这就是我的经历,升级我的项目向我的项目引入了 *.bat text eol=crlf - Leo
我在使用 gradlew.bat 时遇到了同样的问题,这是否意味着在 Windows 上 eol=crlf 不起作用? - TWiStErRob

4
我相信在 Windows 版本的 Git 中存在一个问题,即 Git 在 checkout 操作时随机写入错误的换行符,唯一的解决办法是先 checkout 到其他分支并强制 Git 忽略更改,然后再 checkout 到你实际想要工作的分支。
git checkout master -f
git checkout <your branch>

请注意,这将丢弃您可能有意进行的任何更改,因此仅在检出后立即遇到此问题时才执行此操作。

编辑:我第一次可能真的很幸运。事实证明,在切换分支后,我又被咬了一次。结果发现,git报告的文件在更改分支后也随之更改。(显然是因为git没有正确地应用CRLF行结束符)

我升级到了最新的Windows版git,并希望问题会消失。


1

尝试简单地运行 git restore .

这是 git 给出的提示,它可以正常工作。


1
我遇到了同样的问题。我执行了git reset --hard HEAD,但每次执行git status时,仍然会看到一些文件被修改。
我的解决方案相对简单。 我只是关闭了我的IDE(这里是Xcode)和关闭了我的命令行(这里是我的Mac OS上的终端),然后再试一次,它就可以工作了。
然而,我从未能找到问题的根源。

在我的情况下,是IDE(Codium)总是更新文件.classpath,然后再次出现为修改。 - dr0i

1
我也遇到了类似的问题,涉及到.gitattributes和GitHub的LFS。虽然这不完全是OP的情况,但我认为这提供了一个机会来说明.gitattributes文件的作用以及为什么它会导致“幻影”差异形成未暂存更改的情况。
在我的情况下,一个文件从一开始就已经在我的存储库中。在最近的提交中,我添加了一个新的git-lfs跟踪规则,使用的模式事后看来有点太宽泛,并且匹配了这个古老的文件。我知道我不想改变这个文件;我知道我没有改变这个文件,但现在它在我的未暂存更改中,无论我如何检出或强制重置该文件,都无法修复它。为什么?
GitHub LFS扩展主要通过利用git提供的钩子来工作,这些钩子可以通过.gitattributes文件访问。通常,.gitattributes中的条目指定如何处理匹配的文件。在OP的情况下,它涉及到规范化行尾; 在我的情况下,它是关于是否让LFS处理文件存储。无论哪种情况,当计算git diff时,git实际上看到的文件与您检查文件时看到的文件不匹配。因此,如果您通过与其匹配的.gitattributes模式更改文件的处理方式,则即使文件没有真正更改,它也会显示为未暂存的更改状态报告中。
所有这些都说了,我对这个问题的“答案”是,如果您想要更改.gitattributes文件,您应该添加更改并继续进行。如果不是,请修改.gitattributes以更好地表示您想要执行的操作。

参考资料

  1. GitHub LFS Specification - 这是一个非常好的描述,它说明了如何利用cleansmudge函数调用来替换git对象中的文件为带有哈希值的简单文本文件。

  2. gitattributes Documentation - 所有关于可自定义如何处理你的文档的细节都在这里。


0
如其他答案所指出的那样,问题是由于行尾自动更正造成的。我在*.svg文件中遇到了这个问题。我在我的项目中使用svg文件作为图标。
为解决此问题,我让git知道应将svg文件视为二进制而不是文本,方法是将以下行添加到.gitattributes文件中:
*.svg binary

0

类似的问题,虽然我确信只是表面上的。无论如何,这可能会对某些人有所帮助:我在SourceTree中所做的(供参考):将未提交的文件存储,然后进行硬重置。


0
在类似的情况下。由于多年来与许多程序员的折磨,他们能够将不同编码的行尾(.asp、.js、.css...不是本质)塞入一个文件中。一段时间以前拒绝了.gitattributes。仓库设置为autorclf = truesafecrlf = warn
最后一个问题出现在从具有不同行尾的存档同步时。从存档中复制后,在git状态中有许多更改的文件,并带有以下注释: The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ... 如何在Git中规范工作树行结尾的提示有所帮助 git add -u

0

环境:Visual Studio 2019 + git + Azure DevOps。

行为

在尝试硬重置后遇到了这种情况,但我的问题不是由于行结尾引起的。

执行多个命令时,git会挂起;换句话说,它永远不会回到命令提示符。它会显示已处理给定命令中的文件,但它不会完成所有命令的“阶段”。

以git clone为例:

enter image description here

解决方案

创建新的个人访问令牌(PAT)

这是一个与我的现有PAT相关的安全/凭据问题,但我找不到任何日志记录告诉我它失败了。


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