【问题标题】:'git status' shows changed files, but 'git diff' doesn't'git status' 显示更改的文件,但 'git diff' 不显示
【发布时间】:2013-01-11 23:07:12
【问题描述】:

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

在一台服务器上(带有 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 输出。

【问题讨论】:

  • 它在您的索引中吗?如果是这样,您可以使用git diff --cached 查看差异。
  • git diff --cached 也只是给我空白输出。
  • git log 也没有输出。
  • 假设确实存在错误,您应该能够创建一个最小示例。尝试复制它并分享示例。
  • 1) 文件模式已更改?寻找core.fileMode 选项here 2)另外,当Console2 实际运行时,我面临与Console2 配置(我在git 下)类似的问题。也许有点文件锁使 git 知道文件已更改。

标签: git diff


【解决方案1】:

我将文件添加到index

git add file_name

然后跑:

git diff --cached file_name

你可以看到git diffhere的描述。

如果您需要撤消 git add,请查看此处:How do I undo 'git add' before commit?

【讨论】:

  • 也许 git diff 会记住以前的内容,即使你已经修改了这个文件并且 git add 会刷新它。
【解决方案2】:

对我来说,它与文件权限有关。 在我的项目中使用 Mac/Linux 的人似乎提交了一些具有非默认权限的文件,而我的 Windows Git 客户端无法重现这些文件。

我的解决方案是告诉 Git 忽略文件权限:

git config core.fileMode false

其他见解:How do I make Git ignore file mode (chmod) changes?

【讨论】:

  • 这解决了我在处理一堆文件时遇到的问题,尽管我认为是文件的创建/修改时间。
  • 这为我解决了。 fileMode 值在 Mac/Linux 卷上默认为 true,在 Windows 卷上默认为 false。我将一个项目从 Mac 移至 Windows,需要将其切换为 false。
  • 如果您使用 Docker 容器在 Windows 10 上挂载您的目录运行 VSCode,这也很有帮助。在容器外部,检查 git 状态,正确显示您没有更改任何文件.但是,如果您检查容器内的 git status,它会显示文件已更改。在容器内运行上述命令解决了我的问题。
  • 这对我有用!谢谢!
【解决方案3】:

git status 可能显示不同但git diff 可能没有的原因有几个。

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

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

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

【讨论】:

  • 如果更改权限文件适用:git config core.filemode false 忽略文件权限
  • 您是如何发现换行从 CRLF 更改为 LF 是 git status 会显示差异而 git diff 不会显示差异的情况之一?
  • 拥有使用 Windows 的同事将帮助您找到关于行尾的各种有趣的事情。我认为可能是“git diff”确实显示从 CRLF 到 LF 的变化的情况——它可能取决于您的配置。我有一段时间没有使用 Windows,所以我不知道现在的默认设置是什么。
  • 如果行尾样式已更改,请使用dos2unix 实用程序更改它们。然后添加所有文件git add -A。行尾更改将全部消失。
  • @NagabhushanSN 我使用了一个我从中提取但不想推送的仓库。我不想创建提交,git add -A 也不想添加到索引中。我同时使用 windows 和 linux 并且有 crlf 问题。但是知道如何修复它now。所以 dos2unix 是没有选择的。等等,jaakko 的回答。
【解决方案4】:

我遇到了一个问题,数百个行尾被某个程序修改,git diff 列出了所有已更改的源文件。修复行尾后,git status 仍然将文件列为已修改。

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

git add -A
git reset

core.filemode 设置为 false。

【讨论】:

  • 谢谢!像魅力一样工作!
  • 我用git add --renormalize .解决了,见下面我的answer
  • 我添加git restore ..以不污染索引。
  • git restore . 帮助建立了一个干净的索引。
【解决方案5】:

正如a previous answer 中已经指出的那样,这种情况可能是由于行尾问题(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.

【讨论】:

  • 这是新的最佳答案。
  • 认为不需要重置。
  • @Timo 是的,这个命令应该可以在不需要git reset 之后工作。
  • 谢谢!!我做了git config --global core.autocrlf true 然后运行它并解决了。
  • 行尾问题只是一个例子;其他在文件提交(clean 操作)和/或提取(smudge 操作)时执行自动更改的 git 过滤器也可能是罪魁祸首;检查 git 配置文件中的 filter 部分。
【解决方案6】:

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

尝试运行:

GIT_TRACE=2 git <command>

看看有没有什么有用的。如果这没有帮助,只需使用strace 看看出了什么问题:

strace git <command>

【讨论】:

  • @towi:既然这对你来说是一笔赏金,我很想看看你对类似失败原因的了解。
  • 在我的例子中,我将-F 标志添加到LESS env 变量中,如果要显示的信息少于一屏,则该标志告诉 less 退出。由于 git 使用 less 作为寻呼机,而且我的差异很小,因此没有显示任何内容。要么我必须将-X 添加到LESS 环境中,即使在较少的退出后也会在屏幕上显示内容,或者只是删除-FGIT_TRACE 显示 less 正在执行,这提醒我我最近更改了 LESS 变量。 @rcwxok 的回答中的相同原因,但想评论 GIT_TRACE 如何提供帮助。
  • 这个答案为我提供了“寻呼机”的提示,并引导我到 the solution.gitconfig 中设置 core.pager,这对我来说非常适合。
【解决方案7】:

我遇到了类似的问题:git diff 会显示差异,但 git diff &lt;filename&gt; 不会。原来我将LESS设置为一个包含-F--quit-if-one-screen)的字符串。删除该标志解决了问题。

【讨论】:

  • 除了删除-F,添加-X 也可能有效,请参阅下面的类似案例回答。
  • 谢谢你!快把我逼疯了。
【解决方案8】:

简答

运行git add 有时会有所帮助。

示例

Git status 显示已更改的文件,而 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
> 

【讨论】:

  • 这听起来像是“对抗症状”而不是“治愈疾病”...... ;)
  • @einjohn 你认为这个病例是什么病?
  • 这种疾病可能是多方面的。正如其他人所提到的,这可能是权限问题或行尾问题。它也可能是已经阶段性的变化。但是,最后一种可能性不适合您的示例。然而,使用您的解决方案,您将不知道原因(疾病),您只是消除了问题(看似错误的空差异(症状))。需要明确的是:我并不是说这是一个糟糕的解决方案。如果他/她只是想让问题消失,它可能会对某人有所帮助。 ...希望我对我的疾病隐喻有所了解。 :)
  • @einjohn 大多数时候似乎是行尾。 statusdiff 似乎有不同的处理方式。
  • 这对我有用:git add,而不是取消暂存所有文件。虚假的差异消失了。谢谢。
【解决方案9】:

我遇到了这个问题。我的情况类似于the LESS issue posted by rcwxok

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

但是,与之前的答案不同,我不想删除 -F 选项,因为我明确地把它放在那里希望防止在 less 中显示差异,如果它比一个屏幕短。

为了得到想要的结果,我没有删除-F,而是添加了-XPAGER='less -RSFX'。这既解决了git diff 的问题,又防止了与less 的短差异。

【讨论】:

  • 大写似乎很奇怪。您的意思是“less -RSFX”而不是“LESS -RSFX”吗?选项是否正确?
  • 是的,谢谢,这是一个错误。不知道它是怎么发生的。现已修复。
【解决方案10】:

TL;DR

行尾问题:

  1. 将 autocrlf 设置更改为默认 true。即,在 Windows 上签出 Windows 样式的行尾,并在远程 Git 存储库上提交 Linux 样式的行尾:
    git config --global core.autocrlf true
    
  2. 在 Windows 机器上,将存储库中的所有文件更改为 Windows 样式:
    unix2dos **
    
  3. Git 添加所有修改过的文件,修改过的文件会去:
    git add .
    git status
    

背景

  • 平台:Windows,WSL

我偶尔会遇到git status 显示我修改了文件而git diff 没有显示任何内容的问题。这很可能是行尾问题。

根本原因

我经常遇到这个问题的原因是我在 Windows 机器上工作并在 WSL 中与 Git 交互。在 Linux 和 Windows 设置之间切换很容易导致此行尾问题。由于操作系统中使用的行结束格式不同:

  • Windows:\r\n
  • OS X / Linux:\n

常见做法

当你在你的机器上安装 Git 时,它会要求你选择行尾设置。通常,通常的做法是在远程 Git 存储库上使用(提交)Linux 风格的行尾,并在 Windows 机器上签出 Windows 风格。如果你使用默认设置,这就是 Git 为你做的。

这意味着如果您的存储库中有一个 shell 脚本 myScript.sh 和 Bash 脚本 myScript.cmd,则这些脚本都以 Linux 风格的结尾存在于您的远程 Git 存储库中,并且都以 Windows 风格的结尾存在于您的 Windows 中机器。

我曾经检查过 shell 脚本文件并使用dos2unix 更改脚本行尾,以便在 WSL 中运行 shell 脚本。这就是我遇到这个问题的原因。 Git 一直告诉我我对行尾的修改已更改,并询问是否提交更改。

解决方案

使用默认的行尾设置,如果您更改某些文件的行尾(例如使用dos2unixdos2unix),请放弃更改。 如果行尾更改已经存在并且您想摆脱它,请尝试git add 他们,更改将会消失。

【讨论】:

    【解决方案11】:

    我刚刚遇到了类似的问题。 git diff file 没有显示任何内容,因为我将文件添加到 Git 索引中,其中部分名称为大写:GeoJSONContainer.js

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

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

    【讨论】:

      【解决方案12】:

      我对您的用例的假设:

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

      其实有两种方法。

      克隆 repo - mv .git - git reset --hard

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

      git reset --hard
      

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

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

      第二个不那么烦人:cd 进入你的目的地,然后用

      开始一个新的存储库
      git init
      

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

      git remote add origin original_git_repo_path
      

      然后安全

      git fetch origin master
      

      在不更改本地文件的情况下复制数据。现在一切都应该好了。

      我总是推荐第二种方法来减少出错的可能性。

      【讨论】:

      • 你似乎暗示这是一个 git 错误。好的,可以。我仍然认为我缺乏对 git 的正确理解,因为我没有 Linus 聪明 ;-)
      • @towi:不,我不是暗示这是一个 git 错误,也不是暗示相反。我不熟悉 git 内部结构。但作为一般经验法则,通过将.git 文件夹移动到其他工作区域,我们可能会违反 git 的假设。如果这导致了不稳定的行为,我们不能责怪 git,我们必须责怪自己玩弄 git。 git 提供了解决这个问题的方法,例如reset --hard。只是那不是我们想要的。这正是推荐init/remote add方式的原因,一切都很好。
      • @towi 和 Oliver P:虽然我理解您希望解决您的特定错误案例,但有时只是建议您遵循一般建议 - 特别是如果它们完全适合您的用例。也没有数据丢失。 remote add 的做事方式仍然可以应用于像 Oliver P 所描述的混乱情况
      • 没有评论的否决票无助于改善此答案,也无助于整个网站。谁投了反对票,请发表评论,以便问题得到解决。
      【解决方案13】:

      我遇到了同样的问题,描述如下: 如果我输入了

      $ git diff
      

      Git 直接返回提示,没有错误。

      如果我输入了

      $ git diff <filename>
      

      Git 直接返回提示,没有错误。

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

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

      所以如果你输入:

      git diff
      

      它只是返回到你可能有这个问题的提示。

      git 运行的实际 diff.exe 位于您的 mingw64\bin 目录

      最后,为了解决这个问题,我实际上将我的 mingw64\bin 目录复制到了 Git 正在寻找它的位置。我尝试了它,但它仍然没有工作。

      然后,我关闭了我的Git Bash 窗口并再次打开它,转到了失败的同一个存储库,现在它可以工作了。

      【讨论】:

        【解决方案14】:

        我又一次偶然发现了这个问题。但这一次发生的原因不同。 我已将文件复制到存储库以覆盖以前的版本。现在我可以看到文件已修改,但 diff 不返回差异。

        例如,我有一个 mainpage.xaml 文件。 在文件资源管理器中,我将一个新的 mainpage.xaml 文件粘贴到我当前存储库中的文件上。 我在另一台机器上完成了这项工作,只是将文件粘贴到这里。

        文件显示修改,但是当我运行git diff时,它不会显示更改。

        这可能是因为文件上的文件信息发生了变化,Git 知道它不是同一个文件。很有趣。

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

        【讨论】:

          【解决方案15】:

          git diff -a 将所有文件视为文本,它适用于我。

          【讨论】:

            【解决方案16】:

            我使用了git svn,但在一个文件中遇到了这个问题。对文件的每个祖先使用ls-tree,我注意到一个有2个子文件夹-Submitsubmit。由于我使用的是 Windows,因此无法同时检出它们,从而导致此问题。

            解决方案是直接从TortoiseSVNRepo-browser 中删除其中一个,然后运行git svn fetch,然后运行git reset --hard origin/trunk

            【讨论】:

              猜你喜欢
              • 2015-06-08
              • 1970-01-01
              • 2013-04-01
              • 1970-01-01
              • 1970-01-01
              • 2017-03-12
              • 2019-04-14
              • 2019-09-24
              • 2011-04-24
              相关资源
              最近更新 更多