git checkout -- <files> 命令不会丢弃更改?

24

我有一些更改在我的工作目录中,我正在尝试放弃(重置为文件的当前索引版本),但是git checkout -- <file>不会放弃更改。 我尝试手动删除文件 (rm -r files) 然后运行git checkout -- .,但是这会再次显示文件已修改。

$ git checkout -- .
$ 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:   files/Hulk.png
#   modified:   files/Hulk_2.png
#
no changes added to commit (use "git add" and/or "git commit -a")

运行git diff会显示文件已经被修改...

diff --git a/files/Hulk.png b/files/Hulk.png
index 1c256cb..1d37fe0 100644
Binary files a/files/Hulk.png and b/files/Hulk.png differ
diff --git a/files/Hulk_2.png b/files/Hulk_2.png
index 1c256cb..0717199 100644
Binary files a/files/Hulk_2.png and b/files/Hulk_2.png differ

注意:有些人建议运行 git checkout .,但是这将会达到与 git checkout -- . 相同的结果。在 git checkout 命令中,-- 只是一种用于区分树对象/提交点和文件/路径的符号。

操作系统:OSX 10.6 Git 版本:1.7.10.2


git reset --hard 有效吗? - vergenzt
@vergenzt,不行...我发现了问题。我正在使用一个似乎有多个文件名称相同但大小写不同的存储库。由于我在一个不区分大小写的OSX工作站上工作,这些文件看起来已经改变了,但实际上并没有。这就是为什么我不能重置它们,也不能提交“更改”的原因。我必须在一个区分大小写的操作系统上重命名文件并提交结果。 - Highway of Life
如果您已经得出了答案,请添加该答案并将其标记为已接受。 - swatkins
@swatkins 我还没有,我还在努力工作中。 - Highway of Life
太好了!祝你完成顺利! - swatkins
11个回答

23

出现这种情况是由于同名但大小写不同的多个文件。在不区分大小写的OSX系统中,不喜欢有同名但大小写不同的多个文件,它将它们视为同一文件。 要解决这个问题,我运行了git mv(或只是mv)命令来将文件临时重命名,并添加了临时文件。这样就可以让git删除旧的/错误命名的版本,然后再进行第二次提交以重新命名它们。 这个问题也可以在允许同名文件但大小写不同的文件系统上进行修复。


谢谢!这帮助我解决了CocoaPods中一个非常令人沮丧的bug。 - ndbroadbent

9
你尝试过吗?
git config --global core.autocrlf false

或者

git config --global core.filemode false

7
为什么会有人尝试那样做? - Finster
我在Windows上使用Cygwin来运行Git。我们有一些疯狂的安全策略,在Git操作期间会神奇地更改文件权限。(Cygwin邮件列表中的其他人也注意到了这一点。)Git检测到这些文件模式更改,但是git checkout -- ${file}无法还原它们。git config --global core.filemode false是一个有趣的想法! - kevinarpe
这很有帮助。在使用“git checkout -- file”检出后,请尝试执行git diff。如果它说整个文件已更改,但实际上看起来完全相同,则可能是autocrlf的问题。 - Rob

6

根据您的评论,您需要将存储库配置为区分大小写:

git config core.ignorecase false

这使得git可以跟踪两个文件(尽管文件系统只显示一个,这非常令人困惑)。以下是演示当git正确跟踪大小写敏感时发生的情况的复制步骤:
git init /tmp/test && cd /tmp/test
git config core.ignorecase false
echo test>test && git add test && git commit -m "lowercase t"
mv test Test

现在git status显示与test没有差异:
git status -s
 ?? Test

提交 Test 并使用 git ls-files 命令查看正在跟踪的内容:

git add Test && git commit -m "uppercase T"
git ls-files
 Test
 test
< p >ls命令报告什么?当然是'Test'。 < /p >
ls
 Test

最后,当我们修改测试时会发生什么?

echo garbage>Test
git status -s
 M Test
 M test

这真是一团糟。


2

使用 . 代替 --

git checkout .

1
为什么?“--”只是一个用于比较提交和文件之间差异的命令。你可以使用任何一个命令获得完全相同的结果。而我也是这样做的。 - Highway of Life
git checkout -- .git checkout . 做的是同一件事情,执行效果没有好坏之分。然而,我发现了这个异常的原因:OSX 不区分大小写,有些文件名称相同但大小写不同。尽管 core.ignorecase = true/false 无法解决这个问题,但我找到解决方法后会立即发布答案。 - Highway of Life
@HighwayofLife 他们显然不是做同样的事情。即使“--”没有起作用,这对我来说仍然有效。 - BartoszKP

1

由于某些原因,我遇到了同样的问题,但这并不是大小写敏感的问题。删除文件,然后更改分支可以解决问题。


1

在我的情况下有所帮助的是:(同时改进了vinboxx的答案)

我已经按照以下方式配置了.gitattributes

* text eol=crlf

(我希望-X renormalize在合并后自动使用正确的格式)

在暂时注释掉该行以及设置git config core.autocrlf false之后,一切都恢复正常了。


0

我遇到了同样的问题。我发现这两个有问题的文件有DOS行结束符。我采取了以下措施来解决这个问题。

1- 使用不同的克隆来将行结束符更改为UNIX格式 2- 删除出现问题的克隆并重新克隆它。


0
如果您想放弃所有更改,只需使用以下代码:

git checkout .

这就是我所做的,看看我的问题。请注意,git checkout -- .git checkout . 将执行相同的操作。 - Highway of Life

0
为了避免这个问题再次发生,我决定将我的文件系统转换为区分大小写的格式。
令人惊喜的是,在Mac OS(10.13.4)上这非常容易。
可以快速创建一个具有不同文件系统的新磁盘卷:
- 运行磁盘工具 - 点击容器 - 点击卷(+)
我将新卷命名为“Projects”,并将格式设置为APFS(区分大小写)。
之后,我将所有项目移动到新卷中。

-1

我使用了 git checkout -- .

还有 git checkout .

== 就像楼上说的一样,两者都适用于 Mac OSX 10.7 和 Linux。

使用 git 版本 1.7.7.5 (Apple Git-26) 和 git 1.7.1 编译。

尝试使用不同的仓库,看看是否得到相同的结果。也许是 git 版本中的命令错误?


我发现了问题。我正在使用一个存储库,其中似乎有多个文件具有相同的名称但大小写不同。由于我在一个大小写不敏感的OSX工作站上工作,这些文件看起来会发生变化,但实际上并没有。这就是为什么我无法重置它们,也无法提交“更改”的原因。我必须在一个大小写敏感的操作系统上实际重命名文件并提交结果。 - Highway of Life
看起来很简单,但是这个问题真奇怪。(好知道) - topdown

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