git reset --hard留下的未分级更改


274

之后git reset --hardgit statusChanges not staged for commit:部分中给我文件。

我也试过git reset .git checkout -- .而且git checkout-index -f -a,也没有用。

那么,我该如何摆脱那些未进行的变更呢?

这似乎只命中Visual Studio项目文件。奇怪的。看到此粘贴:http : //pastebin.com/eFZwPn9Z。这些文件的特殊之处在于,我在.gitattributes中具有:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

另外,autocrlf在我的global中设置为false .gitconfig。可能以某种方式相关吗?


您是否从存储库的根目录应用了这些命令?注意.代表当前目录而不是根目录
Alexander

1
我确实从根存储库中完成了这些操作。
2012年

您的git版本是?您是犯了一个愚蠢的错误,还是旧版本有错误?
沙巴兹(Shahbaz)2012年

它是git 1.7.4 msysgit。可能是一个错误,但是命令看起来很简单,我找不到错误。
2012年

作为记录,我尝试使用最新版本的msysgit(1.7.11),但问题仍然存在。
2012年

Answers:


361

我有同样的问题,它与.gitattributes文件有关。但是,导致问题的文件类型未在中指定.gitattributes

我可以通过简单地运行来解决问题

git rm .gitattributes
git add -A
git reset --hard

7
这是gitattributes文件中的* text = auto指令。它会自动更改文件结尾,因此当您检查状态时,文件将自动标记为“已修改”。
Cody Django

3
这行得通,但是我不完全理解为什么。有人在乎解释每个命令吗?
Edwin Stoteler

18
@NLwino,git rm .gitattributes从索引中删除.gitattributes。git add -A将所有内容(包括删除.gitattributes)添加到索引中,如果确实存在问题,那么应该仅删除.gitattributes。git reset --hard重置所有未提交的更改,其中包括删除.gitattributes。本质上,这* text=auto会通过删除一个提交忽略.gitattributes(和指令),然后在删除索引时重置索引,因此将其放回原处,但是在您已重置其他文件之后,便不会再次对其进行修改。
cloudworks

4
@GameScripting,此解决方案不适用于我。没有这样的文件.gitattributes“致命:pathspec'.gitattributes'与任何文件都不匹配”
Pacerier 2015年

4
我这样做,它说fatal: pathspec '.gitattributes' did not match any files 。我究竟做错了什么?
蜂蜜

136

解决!!!

我已按照以下步骤解决了此问题

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

git rm --cached -r .

2)重写Git索引以拾取所有新行结尾。

git reset --hard

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


5
当没有其他操作时,此方法有效!我们已经尝试了此线程以及许多其他线程中的所有内容-这是一个庞大的开发团队,因此让每个人都处于相同的状态是一个噩梦,但这解决了问题。
tkersh

有趣的是...我使用“ git rm --chached <one_specific_file>”,而不是删除所有内容。“ git status”报告该文件为已删除和未跟踪。然后“ git reset --hard”修复该文件所有其他文件正在报告为“不更改上演”(使用Git RM之前,我硬重置尝试努力没有效果)我喜欢这种神秘的源代码控制系统。
joeking

您知道,它会删除所有缓存。在大型项目中,这可能会浪费大量时间。
Ohar

那太残酷了。您可以通过删除repo目录并重新克隆来完成相同的操作。
ingyhere

4
考虑您在Windows上,并且不区分大小写。如果您还与区分大小写的文件系统(例如Mac或Linux)上的开发人员一起工作,则他们可能会在不同情况下提交标签,分支甚至文件。在这种情况下,您的索引将显示操作系统拉出时覆盖的现有文件。解决该问题的唯一方法是在您的Git服务器上建立命名策略(挂钩)或预先嗅出错误。
ingyhere

97

Git不会重置不在存储库中的文件。这样你就可以:

$ git add .
$ git reset --hard

这将暂存所有更改,这将使Git意识到这些文件,然后将其重置。

如果这不起作用,则可以尝试隐藏和删除更改:

$ git stash
$ git stash drop

4
文件已被跟踪。无论如何都尝试过,它也不起作用。我的仓库肯定存在某些问题,但是我不知道该怎么办。有关git stash的问题,请参阅我对Shahbaz的回答。
2012年

当您执行git status时会发生什么?
YuriAlbuquerque

1
我想到了一个解决方案。进行提交,并进行交互式变基以擦除该提交。
YuriAlbuquerque 2012年

我曾尝试过一次,但确实有效,后来我又尝试了一下,并得出了我的答案编辑中概述的令人惊讶的结果。
诺斯瓦普2012年

@ YuriAlbuquerque,Git不太了解POLA。难道不是git reset --hard要“ 将登台区域和工作目录都重新设置为匹配 ”?如果未暂存文件,显然我们想在执行时将其删除reset --hard
Pacerier,2015年

71

如果您将Git用于Windows,则可能是您遇到的问题

我遇到了同样的问题,并且藏匿,硬重置,清理甚至所有这些都仍然留下更改。原来是问题所在是git没有正确设置x文件模式。这是Windows的git的“已知问题”。本地更改以gitk和git状态显示为旧模式100755新模式100644,没有任何实际文件差异。

解决方法是忽略文件模式:

git config core.filemode false

更多信息在这里


2
即使rm -rf *; git checkout HEAD .没有,这也能奏效。!
论坛用户

为我工作,而隐藏存储/硬重置/ rm .attributes全部失败。
kakyo

当我在Mac上托管的Linux中使用git repo时遇到问题时,这对我也
有用

为我工作-尝试了其他所有方法,是旧模式与新模式出现了问题(注意到我的数字不同,但是文件相同)
Taehoon A Kim

节省生命和时间。
Yogesh Patil

31

好的,我已经解决了问题。

.gitattributes文件似乎包含:

*.sln        eol=crlf
*.vcproj     eol=crlf
*.vcxproj*   eol=crlf

使项目文件显示为未暂存。我不知道为什么会这样,我真的希望有人对git的方法有所了解会给我们一个很好的解释。

我的修复是删除这些文件,并添加autocrlf = false[core].git/config

这并不等同于先前的配置,因为它要求每个开发人员都拥有autocrlf = false。我想找到一个更好的解决方案。

编辑:

我评论了那些令人信服的台词,对它们发表了评论,并且奏效了。什么...我什至没有...!


1
我只是发生了同样的问题,这是唯一有效的解决方案。在我的情况下,我从功能分支切换到我的主服务器,并从上游拉出了一些新更改,并且刚开始对2个已修改的文件进行更改。看来文件可能已从Unix切换到Windows行尾,这可能与它有关。不知道如何或为什么。
史蒂文·苏洛维茨

+1 Windows Git上的相同问题。已经有autocrlf = false。我合并了来自上游svn repo(git svn fetch/ git merge git-svn)的更改,只剩下1个标记为已修改的文件。奇怪的是,我之前遇到过这个问题,而我所要做的就是签出另一个分支(带有-f标志),然后再切换回去。我做到了,并且奏效了,但是当我切换到功能分支时,“更改”又回来了!您在答案底部的编辑就是解决方案。以我为例,我在.gitattributes文件顶部的注释/未注释了一行:* text=auto !eol
Aaron Blenkush 2013年

1
那个EDIT也对我有用:注释掉行.gitattributes,运行git status,取消注释行.gitattributesgit status再次运行
Ignitor

这是因为git正在重置这些文件,然后再次应用指定的行尾.gitattributes。在git diff大概展示了著名的绿的红/墙的墙是典型的行结束差异。
Dagrooms

21

可能的原因1-线路末端标准化

可能发生这种情况的一种情况是,当没有适当配置行尾(1)的情况下将相关文件检入到存储库中时,导致存储库中的文件具有错误的行尾或混合的行尾。要进行确认,请确认git diff仅显示了行尾的更改(默认情况下可能看不见这些更改,请尝试git diff | cat -v将回车视为文字^M字符)。

随后,可能有人添加.gitattributes或修改了core.autocrlf设置以标准化行尾(2)。基于.gitattributes或全局配置,Git已将本地更改应用于您的工作副本,该更改将应用​​请求的行末尾标准化。不幸的是,由于某些原因git reset --hard并不能撤消这些行规范化更改。

重新设置本地行尾的解决方法无法解决问题。每次git“看到”文件时,它将尝试重新应用规范化,从而导致相同的问题。

最好的选择是让git通过对仓库中的所有行尾进行标准化以匹配.gitattributes,并提交这些更改,从而应用所需的标准化,并提交这些更改-请参阅尝试使用git filter-branch来修复行尾,但是没有运气

如果您真的想尝试将更改手动还原到文件,那么最简单的解决方案似乎是擦除已修改的文件,然后告诉git恢复它们,尽管我注意到该解决方案似乎无法始终如一地工作时间(警告:如果修改后的文件除行尾以外,请勿运行此命令!):

    git status --porcelain | grep "^ M" | cut -c4- | xargs rm
    git checkout -- .

请注意,除非您确实在某个时候对存储库中的行结尾进行了标准化,否则您将继续遇到此问题。

可能的原因2-区分大小写

第二个可能的原因是Windows或Mac OS / X上不区分大小写。例如,假设存储库中存在以下路径:

/foo/bar

现在,Linux上的某个人将文件提交/foo/Bar(可能是由于构建工具或创建该目录的某种东西)并推送。在Linux上,实际上这是两个单独的目录:

/foo/bar/fileA
/foo/Bar/fileA

在Windows或Mac fileA上签出此仓库可能会导致修改后的内容无法重置,因为每次重置时,Windows上的git都会签出/foo/bar/fileA,然后由于Windows不区分大小写,会覆盖fileAwith 的内容/foo/Bar/fileA,从而导致它们被“修改”。

另一种情况可能是存储库中存在单个文件,当在不区分大小写的文件系统上签出该文件时,它们会重叠。例如:

/foo/bar/fileA
/foo/bar/filea

可能还有其他类似情况可能导致此类问题。

不区分大小写的文件系统上的git应该确实检测到这种情况并显示有用的警告消息,但目前没有((将来可能会改变-请参阅git.git邮件列表上的讨论和相关建议的补丁程序)。

解决方案是使git索引中的文件大小写与Windows文件系统上的大小写对齐。这可以在显示事物真实状态的Linux上完成,也可以在Windows中使用非常有用的开源实用程序Git-Unite来完成。Git-Unite会将必要的大小写更改应用于git索引,然后可以将其提交给存储库。

(1)这是最有可能使用Windows的人,没有任何.gitattributes有问题的文件定义,并使用默认的全局设置的core.autocrlffalse(见(2))。

(2)http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/


该死的儿子,一路过关斩将。我必须在第一行之后提交,但最终我可以结帐master。那不好玩。
Tim Lieberman

16

如果其他答案不起作用,请尝试添加文件,然后重设

$ git add -A
$ git reset --hard

就我而言,这在git跟踪大量空文件时很有帮助。


这可行。我只是用$ git add .代替$ git add -A
比亚格哈特-彼得森

8

造成此问题的另一个原因可能是不区分大小写的文件系统。如果您的存储库中有多个位于同一级别的文件夹,其名称仅因大小写而不同,则您将受到此打击。确保使用其Web界面(例如GitHub或VSTS)浏览源存储库。

有关更多信息:https : //stackoverflow.com/a/2016426/67824


要查找此类文件的名称,请运行git ls-tree -r --name-only HEAD | tr A-Z a-z | sort | uniq -d
Diomidis Spinellis


5

这些方法都不适合我,唯一的解决方案是删除整个存储库并重新克隆它。这包括隐藏,重设,添加然后重设,clrf设置,区分大小写等。


更新后,事实证明我安装的区分大小写的文件系统实际上并不区分大小写。在我修复此问题后,可以使用上述技术修复该问题。
约翰·亨特2016年

4

运行clean命令:

# Remove all untracked files and directories. (`-f` is `force`, `-d` is `remove directories`)

git clean -fd

3
不幸的是,这不能解决与行尾相关的问题。
Christopher Schneider

无论我遇到什么问题,这都是解决我问题的方法。我没有.gitattributes文件,行尾也不是问题,因为我在linux机器上,所有开发人员和我们的服务器都是linux。
塞缪尔·内夫

4

检查您的.gitattributes

就我而言,我有*.js text eol=lfgit选项core.autocrlftrue

当git自动转换我的文件行结尾并阻止我修复它甚至git reset --hard HEAD什么都没做时,这使我陷入困境。

我通过*.js text eol=lf在我的评论中对其进行修复.gitattributes,然后对其进行注释。

看起来就像是git magic。


这是对我来说,升级我的项目介绍*.bat text eol=crlf到我的项目。
狮子座

1

我遇到了一个类似的问题,也涉及.gitattributes,但就我的案例而言,涉及到GitHub的LFS。尽管这不是OP的确切情况,但我认为它提供了一个机会来说明.gitattributes文件的作用以及为什么文件会导致“虚拟”差异形式的无阶段变更。

就我而言,就像从时间开始以来,文件已经在我的存储库中。在最近的一次提交中,我添加了一个新的git-lfs track使用规则规则,该模式事后看来太宽泛了,最终匹配了这个古老的文件。我知道我不想更改此文件;我知道我没有更改文件,但是现在它是在我的暂存更改中,并且对该文件的任何签出或硬重置都无法修复它。为什么?

GitHub LFS扩展主要通过利用钩子来工作,该钩子git通过.gitattributes文件提供访问。通常,中的条目.gitattributes指定应如何处理匹配文件。对于OP,它关心的是规范化行尾;在我的系统中,是否让LFS处理文件存储。无论哪种情况,git计算a时看到的实际文件git diff都与检查文件时看到的文件不匹配。因此,如果您通过.gitattributes与其匹配的模式更改了文件的处理方式,即使该文件实际上没有任何更改,它也将在状态报告中显示为未暂存的更改。

话虽如此,我对这个问题的“答案”是,如果.gitattributes文件更改是您要执行的操作,那么您应该实际上应该只是添加更改并继续进行。如果不是,请修改,.gitattributes以更好地表示您要执行的操作。

参考资料

  1. GitHub LFS Specification-很好地描述了它们如何与cleanand smudge函数调用挂钩git,以使用带哈希的简单文本文件替换对象中的文件。

  2. gitattributes文档 -有关可用于自定义git文档处理方式的所有详细信息。


0

我有同样的问题。我确实做了,git reset --hard HEAD但是每次git status我都看到一些文件被修改了。

我的解决方案相对简单。我刚刚关闭了我的IDE(这里是Xcode)并关闭了命令行(这里是我的Mac OS上的终端),然后再次尝试它就可以了。

但是,我始终无法找到问题的根源。


0

我认为Windows的git存在问题,其中git在签出时随机写入错误的行结尾,唯一的解决方法是签出其他分支并强制git忽略更改。然后签出您实际要处理的分支。

git checkout master -f
git checkout <your branch>

请注意,这将放弃您可能有意进行的任何更改,因此仅在结帐后立即遇到此问题时才这样做。

编辑:我可能第一次真的很幸运。事实证明,在切换分支后,我又有点生气了。事实证明,更改分支后,文件git报告已被修改。(显然是因为git不能始终如一地将CRLF行结尾正确地应用于文件。)

我已更新至Windows的最新git,并希望问题解决。


0

类似的问题,尽管我确定只是表面上的。无论如何,它可能对某人有帮助:我的工作(在SourceTree中,FWIW):存放未提交的文件,然后进行硬重置。


0

正如其他答案所指出的那样,问题在于线路端自动校正。我在* .svg文件中遇到了此问题。我在项目中使用了svg文件作为图标。

为了解决这个问题,我通过将以下行添加到.gitattributes中,让git知道svg文件应被视为二进制文件而不是文本文件

* .svg二进制


0

在类似情况下。由于许多程序员遭受了多年的折磨,他们能够将行尾的不同编码(.asp,.js,.css ...不是本质)填充到一个文件中。前段时间拒绝了.gitattributes。回购左侧autorclf = true和右侧的设置safecrlf = warn

从存档的不同行尾进行同步时,出现了最后一个问题。从存档中复制后,在git状态下,许多文件都带有注释

The line will have its original line endings in your working directory. warning: LF will be replaced by CRLF in ...

如何在Git中标准化工作树行结尾的技巧帮助了

git add -u


0

我遇到的另一种可能性是,存储库中的一个软件包最终以分离的HEAD结尾。如果此处的答案均无济于事,并且您遇到这样的git status消息,则可能有相同的问题:

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:   path/to/package (new commits)

进入path/to/package文件夹a git status将产生以下结果:

HEAD detached at 7515f05

然后,以下命令应解决此问题,该位置master应由您的本地分支替换:

git checkout master

然后您会收到一条消息,表明您的本地分支将在远程分支后面进行一定数量的提交。git pull你应该走出困境!


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.