Git状态显示修改,但使用git checkout -- <file>命令无法删除它们。

260

我想要删除我的工作副本中的所有更改。
运行git status会显示已修改的文件。
无论我做什么都不能删除这些修改。
例如:

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ 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:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout -- Rhino.Etl.Core/Enumerables/CachingEnumerable.cs

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ 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:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout `git ls-files -m`

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ 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:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git reset --hard HEAD
HEAD is now at 6c857e7 boo libraries updated to 2.0.9.2 and rhino.dsl.dll updated.

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ 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:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

6
不确定为什么 git reset --hard 在这里没起作用。注意:应该使用 git checkout -- \git ls-files -m` 命令来取消文件(--`)。 - VonC
2
如果您删除了文件并使用 checkout -- <file>,它应该可以工作。在某些情况下(包括存在 CRLF 不匹配的情况),更改检测可能有点挑剔。 - eckes
可能是无法在Git中放弃更改的重复问题。 - BuZZ-dEE
1
@BuZZ-dEE - 这是一个重复的问题,而且旧的问题会优先考虑。但是,虽然您链接到的问题本质上是相同的,但我下面接受的答案比那里的任何答案都更具信息量,并解决了我的问题。 - rbellamy
“git update-index --assume-unchaged” 是一种针对无聊情况的多功能工具,它可以强制将文件保持为未更改状态(即使它们已经被更改了!)。 - pdem
25个回答

3

我有一个旧的冗余分支,其中有不同的行尾。 切换到该分支时遇到了一些困难,直到我使用了一些 --force 命令。

git checkout mainbranch --force

紧接着快速执行 git branch -D brokenbranch 命令。


这对我有用。不确定最终结果与其他建议的答案有何不同。在进行任何涉及“--force”或“rm”的操作之前,我认为备份整个本地存储库总是一个好主意... - Magnus

3
我遇到的问题是Windows不关心文件名大小写,但Git却在意。因此,Git存储了文件的大写和小写版本,但只能检出一个版本。

2
这里有很多解决方案,我可能应该在自己想出方法之前尝试一些。无论如何,这是另一个解决方法...
我们的问题是没有强制执行换行符,并且存储库混合了DOS / Unix。更糟糕的是,它实际上是一个开源存储库,在这种情况下,我们已经进行了分叉。由主要拥有OS存储库的人做出决定,将所有endlines更改为Unix,并提交了包括.gitattributes以强制执行行结束的提交。
不幸的是,这似乎引起了问题,就像在这里描述的那样,一旦从DOS-2-Unix之前的代码合并后,文件将永远被标记为已更改,无法还原。
在我的研究中,我发现了https://help.github.com/articles/dealing-with-line-endings/ -如果我再次遇到这个问题,我会首先尝试这个解决方案。
这是我做的事情:
  1. 在注意到这个问题之前,我最初进行了合并操作,后来不得不中止 - git reset --hard HEAD (我遇到合并冲突怎么办?)

  2. 我在VIM中打开了相关文件并切换为Unix格式(:set ff=unix)。当然,也可以使用像 dos2unix 这样的工具。

  3. 提交更改。

  4. master 分支合并进来(主分支已经有了DOS转Unix的更改)

    git checkout old-code-branch; git merge master

  5. 解决冲突后,文件又变成了DOS格式,因此需要在VIM中输入 :set ff=unix。(请注意,我安装了 https://github.com/itchyny/lightline.vim 以便在VIM状态栏中查看文件格式)

  6. 提交更改。搞定!

2
保持一致的行尾是件好事。例如,它不会触发不必要的合并,即使微不足道。我见过 Visual Studio 创建带有混合行尾的文件。
此外,一些程序(如 Linux 上的 bash)确实需要以 LF 结尾的 .sh 文件。
为了确保这一点,您可以使用 gitattributes。它在存储库级别上工作,无论 autcrlf 的值如何。
例如,您可以像这样拥有 .gitattributes: * text=auto
如果在您的情况下确实很重要,您还可以更具体地指定每个文件类型/扩展名。
然后 autocrlf 可以在本地为 Windows 程序转换行尾。
在一个混合的 C#/C++/Java/Ruby/R、Windows/Linux 项目中,这个方法运行良好。到目前为止没有问题。

2

我也有类似的症状,但是原因不同。

我无法:

git checkout app.js //did nothing
git rm app.js //did nothing
rm -rf app.js //did nothing

即使执行了git rm --cached app.js,它仍然会被标记为已删除的文件,在未跟踪的文件中我也可以看到app.js。但是当我尝试使用rm -rf app.js并再次执行git status时,它仍然在“未跟踪”的文件中显示。
在和同事多次尝试之后,我们发现这是由Grunt引起的!
因为Grunt已经启用,并且由几个其他js文件生成了app.js,我们发现在每次操作js文件(包括此app.js)后,grunt都会重新创建app.js。

2

当贡献者在Linux机器上工作或使用Cygwin在Windows上工作并更改文件权限时,也可能出现此问题。Git只知道755和644。

以下是此问题的示例以及如何检查它:

git diff styleguide/filename

diff --git a/filename b/filename
old mode 100644
new mode 100755

为了避免出现这种情况,您应该确保正确设置git,使用以下命令:
git config --global core.filemode false

2

我提交了所有更改,然后对提交进行了撤销。

这是我的操作:

git add .

git commit -m "随机提交"

git reset --hard HEAD~1


1
如果您克隆一个存储库并立即看到待处理更改,则该存储库处于不一致状态。请不要从.gitattributes文件中注释掉* text = auto。这是因为存储库所有者希望所有文件都与LF行结尾一致。正如HankCa所述,按照https://help.github.com/articles/dealing-with-line-endings/上的说明进行操作是解决问题的方法。易用按钮:
git clone git@host:repo-name
git checkout -b normalize-line-endings
git add .
git commit -m "Normalize line endings"
git push
git push -u origin normalize-line-endings

然后将该分支合并(或发起拉取请求)到仓库所有者。

1
对我来说问题在于执行命令时Visual Studio处于打开状态。
关闭Visual Studio后,该命令生效,我终于可以从堆栈中应用我的工作。因此,请检查所有可能更改代码的应用程序,例如SourceTree、SmartGit、NotePad、NotePad++和其他编辑器。请保留HTML标签。

1

这个页面上其他的方法都不起作用,但是这个终于对我有用了。它不会显示未跟踪或已提交的文件。

git add -A
git reset --hard

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