如何理解git log --graph

时间:2013-11-25 18:13:16

标签: git git-log

我对图形git log的输出很困惑。

我确实理解每个*意味着提交,无论是分歧,共同提交还是合并提交。 我明白管道意味着分支。

让我们看一个简单的图形日志:

enter image description here

首先,红色管道(最左手的那个)代表哪个分支?我不认为这是我当前的分支,因为在我结账到其他分支后,图表看起来是一样的。此外,它也不代表主分支。

其次,如果最左手的分支代表一个分支,为什么它在提交“0e5b5”后会改变颜色?

我搜索了一个关于如何阅读git log graph的教程,不幸的是,我什么也没得到。如果有关于此主题的一些很棒的教程,请随时分享。

3 个答案:

答案 0 :(得分:4)

Git的工作原理是当前提交的祖先。分支不是“实体”,它们是(移动)引用。 git log(或gitk具有不同的配色方案但与git log --graph或tig类似)无法知道当前分支是分支A还是分支B的后代。它只知道父母。来自man git-log:

   git log -p -m --first-parent
       Shows the history including change diffs, but only from the "main 
       branch"   perspective, skipping commits that come from merged
       branches, and showing full diffs of changes introduced by the merges. 
       This makes sense only when following a strict policy of merging
       all topic branches when staying on a single integration branch.

会在某种程度上解决您的担忧。 git log默认使用当前签出提交作为参考(与执行git log HEAD

相同)

虽然我个人认为man页面对git非常清楚,但你可能想看一下gitk或tig。前者是图形界面,后者是类似终端​​的最小gitk工具。我根据我想做的事情使用两者。

答案 1 :(得分:0)

在Git 2.25(2020年第一季度)中,重构了“ git log --graph”的实现,然后简化了其输出。

在某些情况下反过来又可以固定颜色。
下面提供了有关如何使用git log --graph管理颜色和边缘的说明。

请参见commit d784d97Denton Liu (Denton-L)(2019年11月12日)。
参见commit bbb13e8commit 92beecccommit 479db18commit 0195285commit d62893ecommit 0f0f389commit 458152ccommit ee7abb5,{ {3}},commit 46ba2abcommit a551fd5commit 9157a2acommit 210179a(2019年10月15日)由commit fbccf25发表。
(由James Coglan (jcoglan)Junio C Hamano -- gitster --中合并,2019年12月1日)

  

commit 0be5caf:修复章鱼虚线的颜色

     

签名人:James Coglan

     

graph中(“ log:修复某些章鱼合并形状的颜色”,2018-09-01,Git v2.20.0-rc0-04005834ed在{{3 }}),此操作解决了章鱼合并后破折号的着色问题。
  区分所有父项都引入新列的情况与第一个父项折叠成现有列的情况之间的区别:

| *-.           | *-.
| |\ \          | |\ \
| | | |         |/ / /
     

后一种情况意味着与前一种情况相比,合并父级的列在new_columns数组中的左侧开始。

     

但是,该实现仅在提交的父级映射到可视列时保持顺序的情况下才有效,因为我们在打印破折号时通过遍历new_columns来获得颜色
  通常,提交的父母可以与现有的列任意合并,并在此过程中更改其顺序。

     

例如,在下图中,每列的编号指示每列中显示哪个提交父级。

| | *---.
| | |\ \ \
| | |/ / /
| |/| | /
| |_|_|/
|/| | |
3 1 0 2
     

如果列是彩色的(红色,绿色,黄色,蓝色),则短划线当前将被着色为黄色和蓝色,而虚线应为蓝色和红色。

     

要解决此问题,我们需要查找mapping数组中的每一列,该数组在GRAPH_COLLAPSING状态之前指示在每个可视列中显示哪个逻辑列。
  此实现比较简单,因为它没有任何边缘情况,并且还可以处理现在显示左偏第一亲代的方式:

| *-.
|/|\ \
| | | |
0 1 2 3
     

第一个破折号的颜色始终是在提交符号右侧的mapping两列中找到的颜色。因为提交是在所有边都折叠在一起之后显示的,并且视觉列与逻辑列匹配,所以我们可以使用commit_index找到提交符号的视觉偏移。


关于边缘(仍然适用于Git 2.25,2020年第一季度)

  

merge:提交线上塌陷边缘的平滑外观

     

签名人:James Coglan

     

当图形包含正在向左折叠的边缘,但这些边缘与提交线交叉时,其结果是这些边缘具有锯齿状外观:

*
|\
| *
|  \
*-. \
|\ \ \
| | * |
| * | |
| |/ /
* | |
|/ /
* |
|/
*
     

我们已经采取措施在边缘扩展时对其进行平滑处理;当边沿GRAPH_COMMIT之后的GRAPH_POST_MERGE行上的合并提交标记的右边出现一条边时,我们将其渲染为\

* \
|\ \
| * \
| |\ \
     

我们可以对塌陷的边缘进行类似的改进,使边缘更易于跟随,并为整个图形增加对称感:

*
|\
| *
|  \
*-. \
|\ \ \
| | * |
| * | |
| |/ /
* / /
|/ /
* /
|/
*
     

为此,我们为GRAPH_COMMIT行上紧接GRAPH_COLLAPSING行的边上的边引入了一种新的特殊情况。
  通过保留用于渲染mapping数组中的GRAPH_COLLAPSING线的old_mapping数组的副本,我们可以确定一条边在GRAPH_COMMIT线上塌陷了,应该平滑。


更一般地:

  

batch #6:用于左偏合并的提交和合并后行

     

签名人:James Coglan

     

引入“左偏斜”合并之后,这些合并的第一个父对象与左侧的另一边融合,我们在提交和显示中还需要处理更多的边沿情况。合并后的行。

     

当前图形代码处理以下情况,以确保在提交行上出现在提交(*)右侧的边。

     

两路合并通常后跟垂直线

| | |
| * |
| |\ \
     

章鱼合并(两个以上的父母)之后总是向右倾斜的边缘:

| |  \          | |    \
| *-. \         | *---. \
| |\ \ \        | |\ \ \ \
     

如果提交行紧随合并后的行而出现在与当前提交相同的列中,或者该行左侧的任何列中,则2向合并后跟右偏边缘:

| *             | * |
| |\            | |\ \
| * \           | | * \
| |\ \          | | |\ \
     

此提交为提交行引入了以下新情况。如果两路合并偏向左侧,则即使提交遵循合并后的一条线,其右侧的边缘也始终是垂直线:

| | |           | |\
| * |           | * |
|/| |           |/| |
     

有3个父母的提交向左倾斜,其后是垂直边缘:

| | |
| * |
|/|\ \
     

如果在合并后行之后立即出现3向左偏斜的合并提交,则它可能跟在右斜边之后,就像不偏斜的2向偏斜的合并一样。

| |\
| * \
|/|\ \
     

章鱼与4个或更多的向左倾斜的父级合并时,将始终跟随右倾斜的边缘,因为现有的列需要围绕合并进行扩展。

| |  \
| *-. \
|/|\ \ \
     

在合并后行上,通常在当前提交斜率之后的所有边都向右:

| * | |
| |\ \ \
     

但是,如果提交是向左倾斜的2向合并,则其右侧的边缘将保持垂直。
  我们还需要在垂直于提交标记的垂直线之后显示一个空格,而该行通常后跟一个反斜杠。

| * | |
|/| | |
     

如果左斜合并有两个以上的父对象,则其右边缘在围绕合并引入的边缘弯曲时仍会倾斜。

| * | |
|/|\ \ \
     

要处理这些新情况,我们不仅需要知道每个提交有多少父母,还需要知道它在显示中增加了多少新列。该数量记录在当前提交的edges_added字段中,上一次提交记录在prev_edges_added字段中。

     

此处,“列”是指可视列,而不是columns数组的逻辑列
  这是因为,即使所有提交的父对象最终都与现有的边缘融合在一起,它们也会在这些边缘塌陷之前在提交和合并后行中最初引入不同的边缘。

     

例如,三向合并(其第二和第三父级与现有边缘融合)仍会引入2个可视列,这些可视列会影响其右侧边缘的显示。

| | |  \
| | *-. \
| | |\ \ \
| |_|/ / /
|/| | / /
| | |/ /
| |/| |
| | | |
     

此合并不会引入任何逻辑列;一旦所有边都折叠,在此提交前后有4条边。但是它最初确实引入了2个新的边缘,它们的右边需要容纳这些边缘。


经典输出已简化:

  

graph:可以简化图形输出的示例

     

签名人:James Coglan

     

此后的提交对图形的布局进行了一系列改进,整理了一些边缘情况,即:

     
      
  • 合并其第一父级与左侧现有列融合的
  •   
  • 合并其最后一个父母与右侧的直接邻居融合的人
  •   
  • 在提交线上下左右折叠的边缘
  •   
     

该测试用例举例说明了这些用例,并提供了一个有启发性的示例,旨在说明我打算清除的那种历史。

     

合并E的第一个父级与H的父级相同,因此这些边融合在一起。

* H
|
| *-.   E
| |\ \
|/ / /
|
* B
     

我们可以“倾斜”此合并的显示,以便它不会引入立即折叠的其他列:

* H
|
| *   E
|/|\
|
* B
     

E的最后一个父级是D,与合并右边的F的父级相同。

* F
|
 \
. \   E
 \ \
 / /
| /
|/
* D
     

通向D的两条边可以更快地融合:在合并后的行中,F边可以与E边融合,而不是在合并周围扩展F边,然后让边塌陷。

* F
|
 \
. | E
 \|
 /
|
* D
     

如果将其与上面的“偏斜”效果结合使用,我们将得到以下边缘更清晰的图形显示:

* F
|
| E
|
|
* D
     

最后,从C到A的边沿穿过B的提交线时出现锯齿状:

| * | C
| |/
* | B
|/
* A
     

可以对其进行平滑处理,以使这些边缘更易于阅读:

| * | C
| |/
* / B
|/
* A

答案 2 :(得分:0)

首先,哪个分支执行红色管道(最左撇子 一)代表?我不认为这是我当前的分支 继续,因为在我结帐到其他分支后,该图看起来 相同。此外,它也不代表master分支。

红色管道显示您最后一次提交的来源以及与该来源的任何偏离。因此,当您使用'git log --graph --all'时,它可能并不指向当前分支或主节点上的提交。

第二,如果最左撇子的分支代表单个分支,为什么在提交“ 0e5b5”后颜色会改变>

请参阅上面的答案。最左边的行表示您最后提交的分支。那条线可以有许多不同的颜色,因为当有偏差时它会改变颜色。最上面的部分变成红色。