gpt4 book ai didi

git - git log -p:显示差异还是生成补丁?

转载 作者:行者123 更新时间:2023-12-02 09:06:21 25 4
gpt4 key购买 nike

在阅读git的文档时,我似乎发现了一个矛盾。

this official tutorial of git中,据说git log -p可显示提交的历史记录以及完整的差异信息。但是,在the documentation of git-log中,据说-p选项产生补丁文件,而不是直接输出。而且,“至少它们对我来说”这样的描述令人困惑,因为“上述”很模糊。

除了上面给出的部分外,我只发现one other place提到了-p选项,该选项与本教程中的描述相匹配,而不是补丁部分。另外,当我在计算机上运行git log -p时,它显示提交历史记录和diff信息,并且看不到生成任何补丁文件。那么文档的两个部分矛盾吗?还是我误解了“生成补丁文件”的过程?谢谢!

最佳答案

我们可以说,有很多Git文档不是很理想。

重要的是要意识到,每个Git提交都会保存快照而不是更改,因为这解释了Git在某些棘手情况下的行为。然后,各种Git命令(包括git diffgit log)都可以提取两个快照并进行比较。比较旧快照和较新快照(或“左侧”与“右侧”)的结果是差异或补丁,因为您可以将其反转,然后将较新快照与较早的快照进行比较。

准备这样的diff / patch的默认方法是产生一系列指令,如果遵循字母,则会将每个左侧文件转换为相应的右侧文件。这些指令的一般形式为:希望此特定上下文在左侧和右侧文件中均可见,然后从左侧文件中删除任何-行,并从右侧文件中添加任何+行。如果左侧文件来自某个提交的(单个)父级,而右侧文件来自该提交本身,则可以告诉您该文件中有人进行了更改。

毫无疑问,您已经看到了此输出,甚至可能有些道理。

但是,您正在阅读的文档是根据多个输入片段自动编译的,并且 git log description to which you linked被编写为在this other description of the default output of git diff-tree 之后读取,其中包括以下特定文本:

in-place edit  :100644 100644 bcd1234 0123456 M file0
copy-edit :100644 100644 abcd123 1234567 C68 file1 file2
rename-edit :100644 100644 abcd123 1234567 R86 file1 file3
create :000000 100644 0000000 1234567 A file4
delete :100644 000000 1234567 0000000 D file5
unmerged :000000 000000 0000000 0000000 U file6


当然, git log -p根本不产生该输出-因此 git log文档不包括此部分。但是 git log -p确实产生与 git diff-tree -p相同的输出。当 git diff-tree -p文档的后面部分使用短语“不产生上述输出”时,它是在谈论 :100644 ...内容。

Tell me lies, tell me sweet little lies

回到声称 git log -p

show[s] the history of commits together with complete diff info



嗯,这也是错误的。这里的问题是完整信息对于 git log -p而言太复杂了。具体来说,合并提交定义为具有两个或多个父提交的任何提交。

每次提交都会保存所有文件的快照。但是每次提交还记录一组父级或前级提交哈希ID。大多数提交只有一个父母。在这种特殊且非常常见的情况下, git log可以运行 git diff,其左侧的父代(单数),右侧的提交(单数)。通过这种方式,您可以看到父子之间的变化:提交的作者在提交中发生了变化。

但是有些提交有两个父母。这些提交称为合并提交; git merge命令倾向于构建它们。 (我们不能说它总是构建它们,因为-与Git命令非常常见- git merge实际上可以根据情况和某些命令行参数来执行几个不同的任务之一。)给定这种合并提交, git log不只是选择一个父级,然后向您显示该父级快照与提交快照之间的差异。它不会选择两个父对象并进行区分(通常这不是很明智,并且不会告诉您有关合并结果的任何信息),它甚至不会尝试同时比较所有三个提交,至少默认情况下不会。

相反, git log对双亲(或双亲以上)合并提交的作用是向您显示日志消息,然后根本不用显示差异。在大多数情况下,这实际上是最实际的操作,这就是 git log要做的原因。但这立即告诉我们,我们绝对无法获得完整的图像!

您可以从合并提交中获取差异

请注意,使用不错的简单线性提交链:
A <-B <-C ... <-F <-G <-H   <--master
git log的工作是从最后一次提交开始-它具有一些哈希ID,但是在这里,我将其称为 H-并向您显示其作者和日志消息,然后提取两个快照,一个快照来自父 G,另一个快照来自 H本身,然后进行比较。然后它继续前进(或向后退)以提交 G。现在,它向您显示 G的作者和日志消息,然后提取 F( G的父级)和 G的快照并进行比较。重复上述过程,Git从子提交到父提交逐个提交。只是在合并时 git log根本不会打扰差异。
git show命令与 git log非常相似:它主要完成 git log的工作,但仅执行一次提交。也就是说,如果为 git show提供commit G的哈希ID,它将向您显示 G的作者信息及其日志消息,以及 FG的区别,但只是到此为止-它不会继续也显示 F。但是,如果您将 git show指向合并提交,则至少有时会显示差异。它显示的是组合的差异,这些手册页中对此进行了进一步的描述。重要的是要注意,组合diff仍然故意遗漏了一些东西。特别要特别注意文档的(单独)部分,其中提到:

combined diff lists only files which were modified from all parents.



同样,这实际上是有帮助的。有时,这很有帮助。但是,文档对此并不十分清楚。在这种情况下,尚不清楚为什么 git log不显示任何内容而 git show产生组合差异。

这里发生的是 git loggit show以及其他各种命令可以执行这种特殊的组合差异操作。但是默认情况下, git log不会打扰。您可以给 git log一个 -c--cc标志(请注意,第一个是“一个破折号,一个c”,第二个是“两个破折号,两个c”),以使 git log产生合并的差异以进行合并。 git show命令默认为 --cc行为。

最后,请注意,您可以给 git loggit show一个 -m标志。在这种情况下,这些命令将更加特别地对待合并:对于具有两个父P1和P2的合并提交C,这两个命令实际上将运行:
git diff P1 C git diff P2 C
向您显示通常的标题信息(作者和日志消息)之后。

在所有情况下,除非您使用 --graph,否则 git log不会为您提供足够的信息来再现实际的提交图—这对于理解 git merge至关重要。但这是另一天...

关于git - git log -p:显示差异还是生成补丁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57941299/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com