'git status'显示更改的文件,但'git diff'不显示


178

我看过所有类似的问题。但是,我仔细检查过,肯定发生了奇怪的事情。

在一台服务器上(具有Git 1.8.1的Solaris),我克隆了Git存储库,然后将.git文件夹复制到我现有的实时文件中。这工作得很好,我可以跑步

git status

然后

git diff [filename]

检查所有不同的文件。

在另一台服务器(带有Git 1.7.6的Solaris)上,我正在做完全相同的操作

git diff [filename]

即使文件内容绝对不同,也什么也不显示。我还测试了添加新文件,提交并进行编辑。相同的问题,git status显示文件已更改,但不git diff显示任何内容。如果我下载更改后的文件并在本地运行diff,则会得到diff输出。


9
它在您的索引中吗?如果是这样,您可以使用查看差异git diff --cached
jeremyharris 2013年

2
git diff --cached也给了我空白的输出。
奥利弗·P

git log也没有输出。
奥利弗·P

假设确实存在一个错误,那么您应该能够创建一个最小的示例。尝试复制它并共享示例。
mheinzerling

1)文件模式已更改?在此处查找core.fileMode选项2)另外,当Console2实际运行时,我也面临着Console2配置的类似问题(我在git下拥有它)。也许有点文件锁定使git对文件已更改的事物有所了解。
madhead

Answers:



63

有几种原因git status可能会有所不同,但git diff可能不会有所不同。

  • 文件的模式(权限位)已更改-例如,从777更改为700。

  • 换行样式从CRLF(DOS)更改为LF(UNIX)

找出发生了什么的最简单方法是运行git format-patch HEAD^并查看生成的补丁说明。


11
如果更改了权限文件,请执行以下操作:git config core.filemode false,表示忽略文件权限
jruzafa 2015年

您如何发现换行从CRLF更改为LF的情况之一是git status会显示差异,而git diff不会?
Alex Spurling

拥有使用Windows的同事将帮助您发现有关行尾的所有有趣内容。我认为在某些情况下,“ git diff”确实显示了从CRLF到LF的更改-这可能取决于您的配置。我已经有一段时间没有使用Windows了,所以我不知道默认值是什么样。
cmccabe

58

对我来说,这与文件权限有关。在我的项目中使用Mac / Linux的人似乎提交了具有非默认权限的文件,而Windows git客户端无法复制这些文件。我的解决方案是告诉git忽略文件权限:

git config core.fileMode false

其他见解:如何使Git忽略文件模式(chmod)更改?


这解决了我一堆文件的问题,尽管我认为这与文件创建/修改时间有关。
Derek

这为我解决了。在Mac / Linux卷上,fileMode值默认显示为true,在Windows卷上,默认为false。我将项目从Mac移动到Windows,需要将其切换为false。
geekinit

1
如果您正在使用Docker容器运行VSCode,该容器将您的目录安装在Windows 10上,那么这也有帮助。在该容器的外部,检查git状态,正确显示您没有更改任何文件。但是,如果您检查容器内的git status,则表明文件已更改。在容器内运行上述命令解决了我的问题。
Frederick Ollinger

39

我遇到一个问题,其中某些程序修改了数百行结尾,并git diff列出了所有已更改的源文件。修复行尾后,git status仍列出修改后的文件。

通过将所有文件添加到索引中,然后重置索引,我能够解决此问题。

git add -A
git reset

core.filemode 被设置为假。


谢谢!像魅力一样工作!
Starwave

1
我用解决了git add --renormalize .,请参阅下面的答案
Stefano M

17

我怀疑您的Git安装或存储库有问题。

尝试运行:

GIT_TRACE=2 git <command>

看看是否有有用的东西。如果那没有帮助,请使用strace看看出了什么问题:

strace git <command>

6
@towi:因为这对您来说是一笔赏金,所以我很想了解您对类似失败原因的了解。
cfi

5
就我而言,我将-F标志添加到LESSenv变量中,如果少于一个显示完整信息的屏幕,则告诉少退出。由于git较少用作传呼机,而我的差异较小,因此未显示任何内容。我要么必须添加-XLESSenv 才能在屏幕上显示内容,即使退出次数减少了也可以删除-FGIT_TRACE显示less正在执行,这提醒我LESS最近更改了变量。@rcwxok答案中的原因相同,但希望评论如何提供GIT_TRACE帮助。
Raghu Dodda

此答案为我提供了“寻呼机”的提示,并引导我找到设置in 的解决方案,它对我来说非常有效。core.pager.gitconfig
ytu

10

我有一个类似的问题:git diff会显示差异,但git diff <filename>不会。原来,我设置LESS了一个包含-F--quit-if-one-screen)的字符串。删除该标志即可解决问题。


1
除了删除之外-F,添加-X也可能有效,请参阅以下类似情况的答复。
幸存者

这次真是万分感谢!令我发疯。
hackel

8

前面的回答中已经提到的,这种情况可能是由于行尾问题(CR / LF与LF)引起的。我使用以下命令解决了此问题(在Git版本2.22.0下):

git add --renormalize .

根据手册:

       --renormalize
           Apply the "clean" process freshly to all tracked files to
           forcibly add them again to the index. This is useful after
           changing core.autocrlf configuration or the text attribute in
           order to correct files added with wrong CRLF/LF line endings.
           This option implies -u.

5

简短答案

跑步git add有时会有所帮助。

Git状态显示更改的文件,而git diff不显示任何内容...

> 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:   package.json

no changes added to commit (use "git add" and/or "git commit -a")
> git diff
> 

...运行git add解决了不一致问题。

> git add
> git status
On branch master
nothing to commit, working directory clean
> 

2
对我来说,这听起来像是“与症状作斗争”而不是“治愈疾病” ...;)
einjohn

@einjohn您认为这种情况下的病是什么?
Shaun Luttin

1
疾病可能是几件事情。正如其他人所提到的,这可能是权限问题或行尾出现问题。也可能已经进行了更改。但是,最后一种可能性不适合您的示例。不过,通过您的解决方案,您将不知道原因(疾病),只是消除了问题(看似有问题的空diff(症状))。明确一点:我并不是说这是一个不好的解决方案。如果某人只希望问题消失,则可能会有所帮助。...希望我对我的疾病患者有所了解。:)
einjohn '16

@einjohn似乎大多数时候都是行尾。这似乎statusdiff具备处理这些分道扬镳。
Shaun Luttin

5

我遇到了这个问题。我的案子类似于rcwxok发布LESS问题

就我而言,我将PAGER环境变量设置为PAGER='less -RSF'

但是,与以前的答案不同,我不想删除该-F选项,因为我明确地将其放在此处,以希望在差异less小于筛选时避免显示差异。

为了获得理想的结果-F,我没有删除,而是添加了-XPAGER='less -RSFX'。这不仅解决了git diff问题,而且还防止了使用显示的短差异less


大写似乎很奇怪。您是说“少-RSFX”而不是“少-RSFX”吗?选项是否正确?
StackzOfZtuff

1
是的,谢谢,这是一个错误。不知道怎么回事。现在已修复。
avivr

3

我刚刚遇到过类似的问题。git diff file什么也没显示,因为我将文件的名称的一部分以大写形式添加到了Git索引中GeoJSONContainer.js

之后,我将其重命名为,GeoJsonContainer.js并且停止跟踪更改。git diff GeoJsonContainer.js什么也没显示。我必须使用强制标志从索引中删除文件,然后再次添加文件:

git rm -f GeoJSONContainer.js
git add GeoJSONContainer.js

2

您并没有真正提出一个实际的问题,但是由于这是一个通用的用例,因此我经常使用这里的方法。您可以自己尝试一下,看看错误是否仍然存在。

我对您的用例的假设:

您有一个包含文件和目录的现有目录,现在想将其转换为从其他位置克隆的Git存储库,而无需更改当前目录中的任何数据。

确实有两种方法。

克隆回购-MV .git-git reset --hard

此方法就是您执行的操作-将现有存储库克隆到一个空目录中,然后将.git目录移动到目标目录中。要正常工作,通常需要您随后运行

git reset --hard

但是,这将更改当前目录中文件的状态。您可以在目录的完整副本/ rsync上尝试此操作,并研究更改内容。至少之后,您应该不再看到git log和之间的差异status

初始化新存储库-指向原始

第二个方法是减少干扰:cd进入目的地,然后使用

git init

然后,您告诉该新存储库,它在其他地方有一个祖先:

git remote add origin original_git_repo_path

然后安全

git fetch origin master

复制数据而无需更改本地文件。现在一切都很好。

我总是推荐第二种方式,以减少出错的可能性。


您似乎暗示这是git错误。好吧,可能是。我仍然认为我缺乏适当的git理解,因为我不如Linus ;-)
towi

@towi:不,我不是在暗示这是git错误,也不是在暗示相反的意思。我不熟悉git内部。但是作为一般经验法则,通过将.git文件夹移动到其他工作区域,我们有可能违反git的假设。如果这导致行为不稳定,我们不能责怪git,我们必须责怪自己玩git的把戏。git提供了解决方法,例如reset --hard。只是那不是我们想要的。这正是init/remote add推荐此方法的原因,一切都很好。
cfi

@towi和Oliver P:虽然我了解您希望解决您的特定情况的错误,但有时还是建议您遵循一般建议-尤其是如果它们完全适合您的用例。也没有数据丢失。而且remote add处事方式仍然可以应用于混乱的情况,例如Oliver P
cfi

1
没有评论的不赞成投票不会改善这个答案,也不会改善整个站点。谁投票支持,请发表评论,以便解决该问题。
cfi

1

我再次偶然发现了这个问题。但是这次发生的原因有所不同。我已经将文件复制到仓库中以覆盖以前的版本。现在,我可以看到文件已修改,但diff不返回diff。

例如,我有一个mainpage.xaml文件。在文件资源管理器中,我将一个新的mainpage.xaml文件粘贴到当前存储库中的文件上。我在另一台机器上进行了工作,只是将文件粘贴到了这里。
git显示已修改

该文件显示已修改,但是当我运行git diff时,它不会显示更改。可能是因为文件上的fileinfo已更改,并且git知道它实际上不是同一文件。有趣。

git diff什么也没显示

您可以看到,当我在文件上运行diff时,它什么也没显示,只是返回提示。


1

我用以下方式描述了相同的问题:如果输入

$ git diff

Git只是返回到提示而没有错误。

如果我输入

$ git diff <filename>

Git只是返回到提示而没有错误。

最后,通过阅读,我注意到git diff实际上是调用mingw64\bin\diff.exe来完成工作的。

这是交易。我正在运行Windows,并且安装了另一个Bash实用程序,它更改了我的路径,因此不再指向我的mingw64 \ bin目录。

因此,如果您键入:

git diff

并且仅返回提示您可能有此问题。

实际运行的gitdiff.exe位于mingw64 \ bin目录中

最后,要解决此问题,我实际上将mingw64\bin目录复制到了Git想要在其中查找的位置。我尝试了一下,但仍然无法正常工作。

然后,我关闭了Git Bash窗口,然后再次将其打开到失败的同一个存储库中,现在可以使用了。

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.