为什么不“git reset HEAD”撤消我未提交的,未分级的更改?

时间:2014-01-23 11:27:21

标签: git

我以前能够通过执行“放弃”功能撤消SourceTree的更改,该功能在引擎盖下生成此命令:

git -c diff.mnemonicprefix=false -c core.quotepath=false reset -q HEAD -- myproj.csproj 
git -c diff.mnemonicprefix=false -c core.quotepath=false checkout HEAD -- myproj.csproj

突然间这不起作用。我做丢弃,没有错误发生,重新审视视图,但文件仍然“修改”。然后我尝试在命令行中执行相同的操作,结果如下:

c:\myproject> git reset HEAD

Unstaged changes after reset:
M       myproj.csproj

为什么它仍然列为未分级更改?

我已经确认该文件确实可写(没有进程持有锁)

更新

git checkout也无效:

C:\myproject>git checkout myproj.csproj

C:\myproject>git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   myproj.csproj
#
no changes added to commit (use "git add" and/or "git commit -a")

更新2 还尝试过:

  • git checkout --
  • git checkout -- .
  • git checkout HEAD

,没有一个能解决我的问题

更新3 - 更近一步:

当我结账时,.csproj确实恢复到了正确的版本,签出的版本使用了不同的换行编码。虽然登记版本有CR-LF(0D-0A)用于换行,但签出只有LF(0A)。因此git认为文件在每一行都是不同的。为什么这样?

更新4:添加了SourceTree发布的第二行git-commands。我没有注意到第一次,这就是我认为git reset HEAD会做任何事情的原因。这并没有改变基础问题仍然与CR / LF相关的事实(我认为)

摘要 我从来没有找到问题的解决方案,但我通过签入文件“解决”了它。我的原始问题没有包含SourceTree确实发出正确命令来回滚我想要的信息,因此大多数答案都解决了这个问题。 真正的问题仍然不清楚,但我的主要理论是它与CR / LF有关。

6 个答案:

答案 0 :(得分:9)

如果您需要删除本地更改,请运行以下命令

git checkout -- file_name

git reset HEAD不会删除本地更改。

答案 1 :(得分:7)

我怀疑你的存储库中有CRLF行结尾保存的文件,然后在配置发生变化的某个地方,以便git开始规范化行尾字符(core.autocrlf设置为true,或者添加或更改了.gitAttributes文件。当我遇到这个问题时,结果发现包含* text=auto的.gitAttributes文件已被添加到我的仓库中。

(EOL规范化意味着无论您在工作副本中使用什么,git都会在其数据库中将行尾字符写为LF。)

Git不会自动检查您的文件,看看它们在启用后是否需要EOL规范化。你必须明确告诉它检查你的所有文件,否则你最终会遇到这种情况:你的存储库中的文件仍然有CRLF行结尾,git只会注意到它应该触及每个文件时将它们规范化。因此,下次您对文件进行一些更改时,git会将该文件写入其数据库,并使用LF行结尾。

当git通过读取操作触摸文件时,会出现问题。假设您对具有CRLF行结尾的文件进行了更改,然后尝试放弃更改。 Git将从其数据库中读取干净的副本,看它是否有CRLF行结尾,然后将该文件标记为已修改。该文件实际上并未被修改,但是git说它想要将EOL字符的更改写入其数据库。每次您尝试放弃更改,检出该文件,甚至进行硬重置时都会发生这种情况。这就是为什么似乎不可能撤消这些修改。

您应该让git规范化所有文本文件的行结尾,因此这个问题不会继续弹出(有关如何执行此操作的说明,请参阅https://stackoverflow.com/a/4683783/1369)。如果可能,您甚至可能希望修改历史记录,以便在.gitAttributes设置更改的同时对行结尾进行规范化。

如果您无法修改历史记录,则可能会遇到需要检查仍具有CRLF行结尾的旧版本文件的情况。您可能会遇到一些您无法丢弃且不想提交的已修改文件列表。在这种情况下,您可以使用此解决方法来实际上使git忘记它想要修改这些文件:

  1. 查看旧版本
  2. 关闭行尾标准化
  3. git reset
  4. 重新启用行尾标准化

答案 2 :(得分:1)

答案 3 :(得分:1)

我遇到了类似的事情。我的设置是在Web服务器上使用git来下载最新的代码。由于未知原因,它遇到了这个问题。

# git reset HEAD —hard

重置后的非分段更改:

 'File Name'

我在这里尝试了所有建议的事情。没有修好它。

我在这种情况下通过

解决了这个问题
git add 'File Name'

然后,

git reset --hard HEAD

这为我解决了这个问题。

答案 4 :(得分:0)

“为什么它仍然被列为未分级的变更?”

因为裸git reset HEAD对您的工作树没有任何作用。它只会将HEAD指针重置为您命名的提交(在这种情况下为无操作,因为您将HEAD命名),并重置索引以匹配新的HEAD(在这种情况下,这也是相同的 - 所以网络效果基本上只是丢弃你所做的任何git addgit rm等命令。

答案 5 :(得分:0)

我只是陷入了这种情况,唯一能解决问题的是:

git log

在repo中找到第一个提交并获取哈希(在我的例子中以fdb14f开头)

注意:这只能起作用,因为有问题的仓库是在Linux服务器上,而我的Windows机箱上有一个远程仓库“origin”,其中包含修复CRLF问题的最新提交

git reset --hard fdb14f
git pull origin master

在尝试各种不同的事情之后,这最终让我能够解决这个问题。我在最近的提交中修复了CRLF问题,但是我试过的其他内容都不允许我绕过这些文件。