0

运行git log时我看到奇怪的图表。我将进一步解释。下面是带有图形的 git log 的输出。

$ git log --graph  --oneline
*   df1834d (HEAD -> master, tag: r-0.1, origin/master) Merge branch 'master' of https://github.com/samshers/graphql-hibernate
|\
| * d56a675 fixed country null issue
* | ee9bb70 fixed country null issue
|/
* 2617f2a hibernate cascade error issue. country field in state table set to null

如您所见,master 本身有两个独立的分支。为了进一步证实这一点,我跑了

$ git branch --contains ee9bb706c8fcc329fac4acf69ad6b684f1069170
  joincolumn_issue
  ls
  mappedBy
* master

进而

$ git branch --contains d56a6751771b1f62d9ceb0bcce9a2391c004ee44
  joincolumn_issue
  ls
  mappedBy
* master

很明显,这两个提交都存在于 master 上 - 那么为什么会有两个图表。 我怎么知道两个提交是否都在 master 上或者,如果只有其中一个的变化实际上出现在主控器上,那么两者中的哪一个?

编辑 - 遵循 RY 和 Mark 的回复 添加图表截图 (如果颜色代码增加了任何进一步的含义,请也提示这一点。)
因此,我进一步试图理解为什么提交(Y)不基于先前的提交(X)(如果 X在 Y) 之前提交。git log 显示同时提交了这两者d56a675ee9bb70 提交的位置。

commit ee9bb706c8fcc329fac4acf69ad6b684f1069170
Author: itsvamshers <itsvamshers@gmail.com>
Date:   Mon Sep 9 17:24:01 2019 +0530

    fixed country null issue

commit d56a6751771b1f62d9ceb0bcce9a2391c004ee44
Author: itsvamshers <itsvamshers@gmail.com>
Date:   Mon Sep 9 17:24:01 2019 +0530

    fixed country null issue

但是,在进一步挖掘时,可以看出细微的差别..

$ git show -s --format="%ct" d56a6751771b1f62d9ceb0bcce9a2391c004ee44
1568030041

$  git show -s --format="%ct"  ee9bb706c8fcc329fac4acf69ad6b684f1069170
1568031643

这些信息应该足以让 git 将提交按正确的顺序排列。但如果不是,那我想它更聪明,而且是有原因的,只是试图理解原因和原因。

4

2 回答 2

1

ee9bb70 的历史中不存在 d56a675,而 d56a675 的历史中也不存在 ee9bb70。两者都存在于 master 的历史中,因为它们在 df1834d 中重新合并在一起。所有这一切都是图表中有一个叉子的原因。

它们的两个更改都存在于 master 的历史记录中,但这并不意味着合并提交以您可能想要的方式保留了这些更改。您必须查看当前状态并进行比较。

git show d56a675
git show ee9bb70
git diff 2617f2a..df1834d

此外,如果两个提交是相同的,或者一个是另一个的更新版本(他们的总结表明),那么合并它们可能是一个错误。

于 2019-09-15T18:58:34.540 回答
1

听起来混淆是关于什么是分支,以及分支在 git 中“包含”提交意味着什么。

分支只是指向提交的指针。分支不是git 中的提交集合,就像在某些工具中一样。git 与“包含或不包含”提交的分支最接近的事情是,提交要么是该分支“可访问”的,要么不是该分支“可访问的”。分支指向的提交是可访问的,通过遵循可访问提交的父指针(递归)找到的任何提交也是如此。

合并是具有两个(或更多)父指针的提交。因此,当您将分支合并到master时,该分支的所有提交都可以从master(通过合并提交的第二个父指针)访问。所以分支提交被“包含在”主控中(即可以从主控访问),因为您将它们合并到主控中;这是正常的 git 行为。

如果您只想知道提交时“在master上”的提交......好吧,git并没有真正跟踪这样的事情,但您可以这样做

git log --graph --one-line --first-parent

现在,如果您做一些不寻常的事情(例如将 master 合并到一个分支中,然后将 master 快速转发到生成的合并中,这只是一个示例),那么这仍然可能无法达到您的预期;但是,如果您遵循相当正常的分支/合并策略(并坚持使用“瓷器”命令 - 那些旨在供最终用户使用的命令),它应该看起来更像您所期望的。

这种默认情况下遵循合并的两个分支的行为是该选项对 IMO 有用log的主要原因。--graph

无论如何,示例图中显示的所有提交的更改都存在于 master 中,因为它们都显示为可从 master 访问。有一个陷阱 - 这假设合并提交是两个分支的合理合并。如果您使用ours合并策略合并,则该分支不存在。如果您通过冲突解决做了一些非常奇怪的事情,从分支中撤消了一些更改,那么您有时会遇到所谓的“邪恶合并”,并且它撤消的更改不存在。如果您知道您的团队中没有人这样做,那么您无需担心。

您可以依靠git log的历史简化来告诉您分支是否在合并中被完全破坏(除非您提供类似的选项,否则不应显示这样的分支--full-history,因为log将决定它可以完全解释当前状态而无需提及分支) , 但这可能不是 100% 可靠的,在任何情况下,log逻辑中的任何内容都无法告诉您是否有恶意合并 - 所以在某些时候,您必须相信您和您的团队遵循合理流程的想法。

或良好的工具和测试覆盖率;你也可以依靠它。

于 2019-09-15T19:18:15.653 回答