繁体   English   中英

“git diff”、“git diff HEAD”和“git diff --staged”的奇怪 output?

[英]Strange output of “git diff”, “git diff HEAD” and “git diff --staged”?

有 3 个主要的git diff版本:

  • git diff - WORKING DIRECTORYSTAGE之间的区别
  • git diff --staged - HEADSTAGE的区别
  • git diff HEAD - HEADWORKING DIRECTORY之间的区别

以上是我在网上从不同的人那里找到的几乎每个地方的定义

我按以下顺序对 3 个文件执行了某些提交:

 ce6f5bb (HEAD -> master) 6th commit, file1 c1c67da 5th commit, file3 ea51776 4th commit, file1 file2 001675b 3rd commit, file1 file2 ec04f53 2nd commit, file2 21cb6c1 1st commit, file1

一个。 file2在工作目录中修改
湾。 没有任何准备提交
c。 文件 1和文件3未修改


我的查询是:

1. git 差异

    git diff
    diff --git a/file2.txt b/file2.txt
    index 21106bf..c755a1e 100644
    --- a/file2.txt
    +++ b/file2.txt
    @@ -1,3 +1,4 @@
     123
     345
     678
    +90.    

即使暂存区是空的,为什么会显示差异?


2. git diff HEAD

    git diff
    diff --git a/file2.txt b/file2.txt
    index 21106bf..c755a1e 100644
    --- a/file2.txt
    +++ b/file2.txt
    @@ -1,3 +1,4 @@
     123
     345
     678
    +90.    

如果 LAST COMMIT (HEAD) 与 file1 相关,那么为什么会显示 file2 的差异?
HEAD 根本不包含与 file2 相关的任何内容



现在在暂存文件2之后

3. git 差异

它没有显示任何东西!
(我假设它只会在文件被暂存时显示差异,并且除了暂存版本之外的一些更改也在工作目录中进行)
好吧,如果是这样的话,那么为什么 diff 显示在1 中。


4. git diff --staged

    git diff
    diff --git a/file2.txt b/file2.txt
    index 21106bf..c755a1e 100644
    --- a/file2.txt
    +++ b/file2.txt
    @@ -1,3 +1,4 @@
     123
     345
     678
    +90.    

再次,如果 HEAD 指向 file1,那么为什么会显示 file2 的差异?



我在下面创建了这个图像(注意:另一个场景。与上面不同)

对于git diff HEAD ,我的猜测是对于每个 TRACKED FILE , HEAD 将继续向后移动,直到找到已提交的该文件的最新版本,以与工作目录中的文件进行比较

如果我们考虑如下新场景,那么对于git diff HEAD ,它是否像我假设的那样?

在此处输入图像描述

您犯了一个根本性错误,然后将此错误传播到您的各种命令中。

错误在于您将提交视为更改 提交不是一组更改。 提交保存文件的快照 此外,暂存区实际上从来都不是empty1它最初只是匹配当前的 commit

文件file1.txtfile2.txtfile3.txt存在于:

  • 您的工作树,作为普通文件;
  • 索引/暂存区,作为 Git 特殊提交格式的文件,准备提交;
  • 每次提交。

每个文件的每个副本都可以匹配同一文件(或任何其他文件)的其他副本,或者可以不同。

名称HEAD选择一个特定的提交。 2在您的各种测试开始时,名称HEAD选择了提交ce6f5bb 因此,除了早期提交中的文件之外,此时您和 Git 可以使用三个名为file1.txt的文件:

  • ce6f5bb:file1.txt ,又名HEAD:file1.txt :这个file1.txt的副本被冻结到提交中并且无法更改。
  • :file1.txtfile1.txt的这个副本位于索引/暂存区。 可以随时将其替换为新副本。
  • file1.txt :这只是一个普通文件。 它实际上根本不在Git 中。 它是您工作树中的常规文件。

还有三份file2.txt和三份file3.txt

在没有 arguments 的情况下运行git diff会将HEAD中的所有三个文件与工作树中的所有三个文件进行比较。 在 output 中只提到了那些不同的。

运行git diff --stagedgit diff --cachedHEAD中的所有三个文件与暂存区域中的所有三个文件进行比较。 在 output 中只提到了那些不同的。

运行git diff HEAD会将HEAD中的所有三个文件与工作树中的所有三个文件进行比较。 在 output 中只提到了那些不同的。

Note that when you use git log -p or git show to view a commit, Git does a git diff of the parent commit's snapshot—its files—vs that commit's snapshot. 您看到的 diff 中只提到了那些不同的文件。 所以看起来提交存储了更改,但实际上,它只是存储了一个快照。

还要注意, git status运行两个git diff s:一个比较HEAD与 staging-area,即,执行git diff --staged的名称和仅提及文件的名称 --staged 这些是为提交文件准备的更改 第二个差异比较索引与工作树,即执行git diff ,仅提及文件名。 这些是未暂存的更改 commit


1暂存区可以完全是空的,并且在一个新的存储库中,其中还没有文件,也没有git add -ed。 也可以git rm每个文件,这样会导致暂存区为空。 但通常,它充满了来自HEAD提交的文件副本,直到您使用git add将这些文件替换为工作树中的文件。

2你可以问 Git 关于特殊名称HEAD的两个问题:

git rev-parse HEAD

问 Git HEAD代表什么 hash ID,即当前提交是什么? 这就是git diff所要求的。 或者:

git symbolic-ref HEAD
git rev-parse --symbolic-full-name HEAD

问 Git HEAD代表什么分支名称,即git status说我在哪个分支? 例如,当它去更新分支名称时, git commit就会提出这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM