git status显示修改,git checkout — <file>不会删除它们


222

我想删除对我的工作副本的所有更改。
正在运行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 2010年

2
如果删除文件并使用checkout -- <file>它应该可以。在某些情况下(尤其是存在CRLF不匹配的情况),更改检测有些挑剔
eckes


1
@ BuZZ-dEE-它是重复的,并且更旧,因此优先。但是,尽管您链接到的问题基本相同,但是我在下面接受的答案比那里的任何答案都提供了更多信息,从而解决了我的问题。
rbellamy 2015年

不是解决方案,而是无聊git update-index --assume-unchaged的瑞士刀:强制文件的未更改状态(即使更改的文件也是如此!)
pdem

Answers:


126

存在多个可能导致此行为的问题:

行结束标准化

我也遇到过这类问题。归结为git自动将crlf转换为lf。这通常是由单个文件中的行尾混合引起的。该文件在索引中进行了规范化,但是当git然后再次对其进行规范化以使其与工作树中的文件进行比较时,结果将有所不同。

但是,如果要解决此问题,则应禁用core.autocrlf,将所有行尾更改为lf,然后再次启用它。或者您可以通过以下方式完全禁用它:

git config --global core.autocrlf false

除了core.autocrlf之外,您还可以考虑使用.gitattribute文件。这样,您可以确保每个使用存储库的人都使用相同的规范化规则,以防止混合的行尾进入存储库。

如果要让git在执行不可逆规范化时发出警告,还可以考虑将core.safecrlf设置为警告。

git 手册页说:

CRLF转换几乎不会破坏数据。autocrlf = true将在提交期间将CRLF转换为LF,在签出期间将LF转换为CRLF。git无法重新创建提交之前包含LF和CRLF的混合文件。对于文本文件,这是正确的做法:它会纠正行尾,以使我们在存储库中只有LF行尾。但是对于意外分类为文本的二进制文件,转换可能会破坏数据。

不区分大小写的文件系统

在不区分大小写的文件系统上,当存储库中的相同文件名带有不同的大小写时,git尝试检出两个文件,但是在文件系统上只有一个结束。当git尝试比较第二个文件时,它将把它与错误的文件进行比较。

解决方案将是切换到不区分大小写的文件系统,但这在大多数情况下不可行,或者在另一个文件系统上重命名并提交一个文件。


8
好的...做到了...现在git status保持不变。我已经阅读了autocrlf设置,但似乎无法正确理解。
rbellamy

1
接得好!+1。对我来说,还有另一个论点将其设置为false(stackoverflow.com/questions/1249932/…)。
VonC

这是什么意思:“在git无法重新创建提交之前,包含LF和CRLF的混合文件。” 这是因为git总是根据core.autocrlf设置对行尾进行归一化吗?
rbellamy 2010年

1
对大小写敏感问题更明智的解决方案是,在您的存储库中不要有多个文件夹,其名称仅因大小写而不同
奥哈德·施耐德

3
要查找仅大小写不同的文件名,可以运行git ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d。要列出此类文件的大写和小写名称,请运行git ls-tree -r --name-only HEAD | fgrep -i -f <(git ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d) | sort -i
Diomidis Spinellis

220

我在Windows上遇到了这个问题,但是没有准备好考虑使用的后果,config --global core.autocrlf false也没有准备放弃存储中的其他私有分支和好东西,而是从一个新的克隆开始。我只需要把事情做好。现在。

这对我有用,因为您让git完全重写了您的工作目录:

git rm --cached -r .
git reset --hard

(请注意,在原始问题的注释中所建议的运行之前,运行git reset --hard还不够好rm,文件也不是很简单reset


8
更改后的另一个成功core.autocrlf没有任何效果。
丹尼尔·巴克马斯特2014年

8
即使在Windows上也存在此问题core.autocrlf false。在没有其他办法的情况下,此答案有效。
kenchilada 2015年

9
我已经从这个问题和其他问题中尝试了多个建议。这是唯一对我有用的修复程序。我没有属性文件,因此我已经从core.autocrlf开始,为false。
BrotherOdin

4
这对我不起作用。因此,我通过创建一个新分支来提交这些更改,因为它们对我毫无用处,因此采取了更加丑陋的方式。[java] git checkout -b a-branch-to-commit-bad-crlf-files [/ java] [java] git commit -am“提交错误的crlf文件” [/ java]
Mohd Farid

3
有时候像这样的问题让我真的很想念SVN。
Mike Godin

104

另一个可能对人们有用的解决方案,因为没有一个文本选项对我有用:

  1. .gitattributes一行替换的内容* binary。这告诉git将每个文件都视为不能执行任何操作的二进制文件。
  2. 检查是否有违规文件的消息;如果不是,您可以git checkout -- <files>将它们还原到存储库版本
  3. git checkout -- .gitattributes.gitattributes文件还原到其初始状态
  4. 检查文件是否仍未标记为已更改。

1
在过去的几个小时中,我一直无法恢复,拉动或隐藏文件。这就是我的解决办法!谢谢!(Git 1.8.3.1)
NuSkooler

3
在尝试最终成功之前,我尝试了许多事情。谢谢!
ghenghy

1
这是如何运作的?我认为恢复.gitattributes到原始状态会重新引入相同的问题,但是可惜我的问题现在已经解决。在我的情况下,其他建议均无效。
jdk1.0

1
@ jdk1.0我的理解/猜测是涉及两种不同的比较方法。当您在某处有不同的行结尾时,会发生错误,而git有时会忽略它。当您询问时git status,它发现它们是不同的文件。当您询问时git checkout,它会发现它们具有相同的内容。此解决方案是暂时指示git忽略任何可能的行末尾技巧,并确保本地副本的字节对字节相同HEAD。解决该问题后,就可以恢复聪明了,因为它不会增加新的错误。
zebediah49

3
花了几个小时处理这个问题,这个解决方案终于为我工作了!
Maryam

71

对于将来遇到此问题的人:更改文件模式也可能具有相同的症状。 git config core.filemode false将修复它。


3
完成此操作后,您可能需要做git checkout .
Marty Neal 2013年

2
为我工作而不必再次结帐
phillee 2013年

3
供以后参考:要知道这是否是您需要的修补程序(而不是其他答案中的其他修补程序),请使用git diff,它将显示模式更改为这样的文件old mode 100755 / new mode 100644
pgr

在绝对没有其他事情之后,这将为我解决问题。我真的不认为人们应该在互联网上制作git备忘单和“简单指南”。Git确实不是要拿起和使用的东西,我认为这是您在使用它之前必须经过专门且正式的培训和练习的东西。

谢谢,您救了我很多眼泪!
Lukasz

33

这让我发疯,尤其是在没有在线找到任何解决方案的情况下,我无法解决此问题。这是我解决的方法。因为这是同事的工作,所以不能在这里获得学分:)

问题的根源:我最初安装的git在Windows上没有自动行转换。这导致我最初对GLFW的提交没有正确的行结尾。

注意:这仅是本地解决方案。下一个克隆存储库的家伙仍然会遇到这个问题。永久解决方案可以在这里找到:https : //help.github.com/articles/dealing-with-line-endings/#re-normalizing-a-repository

设置:带有glfw项目的Xubuntu 12.04 Git回购

问题:无法重设glfw文件。无论我尝试了什么,它们始终显示为已修改。

解决了:

edit .gitattributes

Comment out the line:    # text=auto

Save the file

restore .gitattributes:   git checkout .gitattributes

提及注释行的内容可能会有所帮助。
rbellamy

不幸的是,大多数项目没有此可选的.gitattribute文件
mchiasson 2014年

谢谢。我只是不明白为什么这样做是必要的
diogovk 2014年

为什么?基本上,这是对行尾的临时修复。请按照“说明”中的链接使用永久解决方案。
理查德·兰赛特

11

我的.bat文件有相同的问题(无法在未跟踪的文件中删除它)。git checkout-不起作用,此页面上的任何建议也没有。对我而言唯一有效的方法是:

git stash save --keep-index

然后删除隐藏:

git stash drop

这对我有用。请注意,这--keep-index很重要。
user991710

为什么--keep-index很重要?
Choylton B. Higginbottom

8

两次遇到相同的问题!两次都隐藏了我所做的更改,然后试图将它们弹出。由于我已更改了许多文件,因此无法弹出更改-但事实并非如此!它们完全相同。

我现在认为我已经尝试了上述所有解决方案,但均未成功。经过尝试

git rm --cached -r .
git reset --hard

现在,我修改了存储库中的几乎所有文件。

差异文件时,它说我已删除所有行,然后再次添加它们。

有点令人不安。我现在将避免将来藏匿。

唯一的解决方案是克隆一个新的存储库并重新开始。(上次制作)


6

尝试做一个

git checkout -f

那应该清除当前正在运行的本地仓库中的所有更改


真好!这对我有用。尽管对于一个顽固的案例,我必须先git checkout -f <another recent branch>git checkout -f <branch I'm working on>
Reversed Engineer

4

我只能通过临时删除存储库的.gitattributes文件(已定义* text=auto*.c text)来解决此问题。

git status删除后我跑了,修改不见了。即使将.gitattributes放回原位,他们也没有返回。


即使使用更复杂的gitattributes(例如过滤器),也可以使用此功能
Samizdis

2

具有一致的行尾是一件好事。例如,尽管微不足道,它也不会触发不必要的合并。我已经看到Visual Studio创建带有混合行尾的文件。

另外,某些程序(如bash(在Linux上))确实要求.sh文件以LF终止。

为了确保这种情况发生,您可以使用gitattributes。无论autcrlf的值是多少,它都可以在存储库级别工作。

例如,您可以具有如下的.gitattributes:* text = auto

如果您的情况确实如此,则还可以针对每个文件类型/扩展名更具体。

然后autocrlf可以在本地转换Windows程序的行尾。

在Windows / Linux混合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执行peform git status时,它仍然显示“未跟踪”文件。

经过与同事的几次尝试,我们发现这是由Grunt引起的!

由于Grunt已打开,并且因为app.js是从其他两个js文件中生成的,所以我们发现在对js文件(也就是这个app.js)进行每次操作后,他们都开始重新创建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

这里有很多解决方案,在提出自己的解决方案之前,我也许应该尝试其中一些解决方案。无论如何,这里还有一个...

我们的问题是我们没有强制执行端线,并且存储库混合了DOS / Unix。更糟糕的是,它实际上是这个位置上的一个开放源代码回购,并且我们已经分叉了。拥有OS资料库主要所有权的人员决定将所有的终端行都更改为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-2-Unix的更改)

    git checkout old-code-branch; git merge master

  5. 解决了冲突,文件又再次成为DOS,因此:set ff=unix在VIM中必须如此。(请注意,我已经安装了https://github.com/itchyny/lightline.vim,它使我能够看到VIM状态行上的文件格式)

  6. 承诺。全部排序!

2

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


2

我提交了所有更改,然后执行并撤消了提交。这对我有用

git添加

git commit -m“随机提交”

git reset --hard HEAD〜1


2

通常情况下,在GIT清除所有的修改和新文件将下列命令应该工作非常漂亮(是小心,这将删除所有的新文件+您可以创建文件夹和将所有修改过的文件恢复到您的状态电流提交):

$ git clean --force -d
$ git checkout -- .

也许有时更好的选择是只对可选消息执行“ git stash push”,如下所示:

$ git stash push -m "not sure if i will need this later"

这还将清除所有新文件和修改过的文件,但是如果您要还原它们,则将所有这些文件都藏起来。GIT中的存储从一个分支到另一个分支,因此,您可以根据需要将它们还原到另一个分支中。

附带说明一下,如果您已经暂存了一些新添加的文件并希望摆脱它们,则可以这样做:

$ git reset --hard

如果上述所有方法均不适用于您,请阅读下面一段时间前对我有用的方法:

我之前几次遇到这个问题。我目前正在由雇主提供的Windows 10计算机上进行开发。今天,这种特殊的git行为是由我从“开发”分支创建一个新分支引起的。由于某种原因,当我切换回“ develop”分支后,一些看似随机的文件仍然存在,并在“ git status”中显示为“ modified”。

而且,那时我无法签出另一个分支,所以我被困在“ develop”分支上。

这是我所做的:

$ git log

我注意到我今天早些时候从“ develop”创建的新分支显示在第一个“ commit”消息中,并在末尾引用了“ HEAD-> develop,origin / develop,origin / HEAD,The-branch-i-created” -“今天早些时候 ”。

由于我实际上并不需要它,因此将其删除:

$ git branch -d The-branch-i-created-earlier-today

更改的文件仍在显示,所以我做了:

$ git stash

这解决了我的问题:

$ git status
On branch develop
Your branch is up to date with 'origin/develop'.

nothing to commit, working tree clean

当然$ git stash list会显示隐藏的更改,并且由于我的存储很少而且不需要任何存储,因此我确实$ git stash clear删除了所有存储。

注意:在我之前,我没有尝试过有人建议的方法:

$ git rm --cached -r .
$ git reset --hard

这可能也奏效了,下次遇到此问题时,我一定会尝试一下。


1

如果克隆存储库并立即看到挂起的更改,则该存储库处于不一致状态。请不要* text=auto.gitattributes文件中注释掉。之所以这样放置是因为存储库的所有者希望所有与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

此页面上的其他所有内容均无效。这终于对我有用。没有显示未跟踪或已提交的文件。

git add -A
git reset --hard

1

对我来说,问题是执行命令时已打开Visual Studio

git checkout <file>

关闭Visual Studio之后,该命令起作用了,我终于可以从堆栈中应用我的工作了。因此,请检查所有可能更改代码的应用程序,例如SourceTree,SmartGit,NotePad,NotePad ++和其他编辑器。


0

我们公司也面临类似的情况。所提出的方法均无济于事。研究的结果表明了问题所在。问题是在Git中有两个文件,其名称仅在符号寄存器中有所不同。Unix系统将它们视为两个不同的文件,但是Windows疯了。为了解决该问题,我们删除了服务器上的文件之一。之后,在Windows上的本地存储库中,帮助了以下几个命令(按不同顺序):

git reset --hard
git pull origin
git merge

0

我通过编辑.git / config来解决它,添加了:

[branch "name_branch"]
    remote = origin
    merge = refs/heads/name_branch

然后我去了.git / refs / heads / name_branch并放置了最后一次提交的IDenter code here


0

我是这样解决的:

  1. 复制所需的正确代码的内容
  2. 从磁盘中删除引起问题的文件(无法还原的文件)。现在,您应该找到同一文件的两个版本,标记为已删除。
  3. 提交删除文件。
  4. 再次使用相同的名称创建文件,然后粘贴您在步骤1中复制的正确代码
  5. 提交新文件的创建。

那对我有用。


0

这里提出的一个解决方案不起作用,我发现该文件实际上是指向某些特殊字符的链接:

% ls -l StoreLogo.png
lrwxrwxrwx 1 janus janus 8 Feb 21 10:37 StoreLogo.png -> ''$'\211''PNG'$'\r\n\032\n'

% git status    
Changes not staged for commit:
    modified:   StoreLogo.png

% git rm --cached -r StoreLogo.png
rm 'src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png'

% git reset StoreLogo.png         
Unstaged changes after reset:
M   src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png

% git status                      
Changes not staged for commit:
    modified:   StoreLogo.png
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.