94

我有一个仓库,里面有两个文件,据说我在本地更改过。

所以我坚持这个:

$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use "git add" and/or "git commit -a")

Doinggit diff表示整个文件内容已经改变,即使从目测来看这似乎是不真实的(似乎存在 diff 似乎无法看到的常见行范围)。

有趣的是,我不记得在本地更改这些文件。此存储库与一个远程存储库(私有,位于 GitHub.com,FWIW)一起使用。

无论我尝试过什么,我都无法丢弃这些本地更改。我已经尝试了所有:

$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f

换句话说,我已经尝试了如何在 Git 中丢弃未暂存的更改?加上更多。但是这两个文件仍然卡在“已更改但未提交”。

到底是什么会导致两个文件像这样卡住并且看似“未还原表”?

PS 在上面显示我已经尝试过的命令的列表中,git revert当我的意思是git checkout. 很抱歉,感谢那些回答我应该尝试的人checkout。我编辑了问题以更正它。我肯定已经尝试过了checkout

4

14 回答 14

141

我花了几个小时试图解决一个类似的问题——我签出的一个远程分支,它顽固地将四个文件显示为“已更改但未更新”,即使删除所有文件并git checkout -f再次运行(或这篇文章的其他变体)也是如此!

这四个文件是必需的,但肯定没有被我修改过。我的最终解决方案 - 说服 Git 他们没有被改变。以下适用于所有签出的文件,显示“修改”状态 - 确保您已经提交/隐藏了任何真正被修改的文件!:

git ls-files -m | xargs -i git update-index --assume-unchanged "{}"

在 Mac OSX 上,但是 xargs 的操作有点不同(感谢 Daniel 的评论):

git ls-files -m | xargs -I {} git update-index --assume-unchanged {}

我已经将此添加为下次自己的占位符,但我希望它也对其他人有所帮助。

-铝

于 2013-01-02T21:16:41.510 回答
35

文件中的行尾是什么?我打赌他们是CRLF。如果是,请查看本指南:http ://help.github.com/line-endings/

简而言之,您需要确保将 git 设置为在提交时将行尾转换为 LF,然后提交这些文件。假设您正确设置了 git,repo 中的文件应该始终是 LF,签出的文件应该是操作系统的原生文件。

于 2011-06-13T21:19:44.303 回答
22

这就是我在我的情况下解决相同问题的方法:打开 .gitattributes 更改:

* text=auto

至:

#* text=auto

保存并关闭,然后恢复或重置,感谢@Simon East 的提示

于 2016-03-08T09:36:28.043 回答
12

另一种可能性是差异(阻止您使用签出命令恢复这些文件)是文件模式之一。这就是发生在我身上的事情。在我的 git 版本上,您可以使用

git diff dir1/foo.aspx

它会向您显示文件模式更改。但是,它仍然不会让您还原它们。为此使用

git config core.filemode false

或通过添加更改您的文本编辑器中的 git .config

[核]

filemode = false

完成此操作后,您可以使用

git 重置 HEAD dir1/foo.aspx

并且文件应该消失。

(我从How do I make git ignore mode changes (chmod)的答案中得到了所有这些? )

于 2012-06-13T15:39:23.953 回答
4

尝试还原本地更改

git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx
于 2011-06-13T19:55:03.177 回答
3

我有一些幻像更改的文件显示为已修改,但实际上是相同的。

运行此命令有时会起作用:(
关闭 git 的“智能”但通常无用的行尾转换)

git config --local core.autocrlf false

但在另一种情况下,我发现这是由于根目录中的一个文件存在一些行尾设置,即使它被关闭.gitattributes,它也试图申请某些文件。autocrlf这实际上并没有帮助,所以我删除.gitattributes了,提交,文件不再显示为已修改。

于 2016-02-12T06:44:28.877 回答
2
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx
于 2011-06-13T19:53:46.220 回答
2

我遇到了同样的问题,有趣的是文件在 Windows 上发生了更改,但在从 WSL 中查看时却没有。再多的乱七八糟的行尾、重置等都无法改变它。

最终,我在这个答案中找到了解决方案。以下是为方便起见的文字:


我已经使用以下步骤解决了这个问题

1) 从 Git 的索引中删除每个文件。

git rm --cached -r .

2) 重写 Git 索引以获取所有新的行尾。

git reset --hard

解决方案是 git 站点 https://help.github.com/articles/dealing-with-line-endings/上描述的步骤的一部分

于 2019-12-05T08:01:54.933 回答
2

您也可能遇到与目录命名字母大小写有关的问题。您的一些同事可能已经将目录的名称从例如myHandler 更改MyHandler。如果您稍后推送和拉取原始目录的一些文件,您将在远程存储库上有2 个单独的目录,而在本地计算机上只有一个目录,因为在 Windows 上您只能有一个。而你有麻烦了。

要检查是否是这种情况,只需查看远程存储库是否具有双重结构。

要解决此问题,请在 repo 之外制作父目录的备份副本,然后删除父目录,推送它。拉动(此时标记为已删除的第二个应该出现在状态上)并再次推动。之后,从备份中重新创建整个结构并再次推送更改。

于 2018-08-22T09:56:16.623 回答
2

我认为提供有关如何重现问题的提示会很有帮助,以便更好地理解问题:

$ git init
$ echo "*.txt -text" > .gitattributes
$ echo -e "hello\r\nworld" > 1.txt
$ git add 1.txt 
$ git commit -m "committed as binary"
$ echo "*.txt text" > .gitattributes
$ echo "change.." >> 1.txt

# Ok let's revert now

$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Oooops, it didn't revert!!


# hm let's diff:

$ git diff
 warning: CRLF will be replaced by LF in 1.txt.
 The file will have its original line endings in your working 
 directory.
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No actual changes. Ahh, let's change the line endings...

$ file 1.txt 
 1.txt: ASCII text, with CRLF line terminators
$ dos2unix 1.txt
 dos2unix: converting file 1.txt to Unix format ...
$ git diff
 git diff 1.txt
 diff --git a/1.txt b/1.txt
 index c78c505..94954ab 100644
 --- a/1.txt
 +++ b/1.txt
 @@ -1,2 +1,2 @@
 -hello
 +hello
  world

# No, it didn't work, file is still considered modified.

# Let's try to revert for once more:
$ git checkout -- 1.txt
$ git status
 modified:   1.txt

# Nothing. Let's use a magic command that prints wrongly committed files.

$ git grep -I --files-with-matches --perl-regexp '\r' HEAD

HEAD:1.txt

第二种重现方式: 在上面的脚本中替换这一行:
echo "*.txt -text" > .gitattributes
使用
git config core.autocrlf=false
并保持其余行不变


以上都说了什么?可以(在某些情况下)使用 CRLF 提交文本文件(例如-text.gitattributes/ 或中core.autocrlf=false)。

当我们稍后想要将相同的文件视为文本(-text-> text)时,将需要再次提交。
当然,您可以暂时恢复它(如Abu Assar正确回答)。在我们的例子中:

echo "*.txt -text" > .gitattributes
git checkout -- 1.txt
echo "*.txt text" > .gitattributes

答案是:你真的想这样做吗,因为每次更改文件都会导致同样的问题。


作为记录:

要检查哪些文件会在您的 repo 中导致此问题,请执行以下命令(git 应使用 --with-libpcre 编译):

git grep -I --files-with-matches --perl-regexp '\r' HEAD

通过提交文件(假设您想将它们视为文本),这与执行此链接http://help.github.com/line-endings/中提出的解决此类问题的方法相同. 但是,您可以只更改文件,然后执行然后提交,而不是删除.git/index和执行。resetgit checkout -- xyz zyf

于 2017-07-11T09:38:14.123 回答
2

这个问题也可能是因为 git 将大小写差异视为不同的文件,但 windows 将它们视为同一个文件。如果一个文件名只是改变了它的大小写,那么该 repo 的每个 Windows 用户都将在这种情况下结束。

解决方法是确认文件内容正确,然后重新提交。我们不得不将这两个文件的内容合并在一起,因为它们是不同的。然后拉,会有一个合并冲突,你可以通过删除重复文件来解决。重新提交合并决议,您将回到稳定状态。

于 2020-01-08T19:52:46.440 回答
1

对我来说,问题不在于行尾。这是关于更改文件夹名称的大小写(Reset_password -> Reset_Password)。这个解决方案帮助了我: https ://stackoverflow.com/a/34919019/1328513

于 2017-11-01T16:11:06.270 回答
0

去过那里,时间一直是我最大的敌人之一,所以决定采用最简单的解决方案。

  1. 将 2 个本地版本文件移至别处
  2. 提交并推送
  3. 手动将文件复制到 git 服务器
于 2022-01-06T04:25:23.067 回答
0

我的问题是别的。没有多少reset, clean, restore, 或其他 git 命令解决了我的问题。我也试过删除文件,恢复等,每次拉,它都会回来。

> git status
On branch master
Your branch is behind 'origin/master' by 319 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   bucket/stellarium.json

我通过以下方式修复了它:

重命名/将文件移开。(-->不是 git mv)

> mv .\bucket\stellarium.json .\bucket\stellarium_DELETEME.json
> git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    bucket/stellarium.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        bucket/stellarium_DELETEME.json

恢复文件。

> git restore .\bucket\stellarium.json
> git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        bucket/stellarium_DELETEME.json

删除重命名的文件。

> rm .\bucket\stellarium_DELETEME.json
> git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

所以... ?

也许磁盘的 FAT 搞砸了?我不确定。还是不知道。但是,它奏效了

于 2021-11-16T00:34:49.673 回答