gpt4 book ai didi

git - 如何理解 git log --graph

转载 作者:IT王子 更新时间:2023-10-29 01:27:59 26 4
gpt4 key购买 nike

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

我确实理解每个 * 都意味着一次提交,无论它是发散提交、普通提交还是 merge 提交。我明白管道意味着分支。

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

enter image description here

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

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

我搜索了有关如何阅读 git 日志图的教程,不幸的是,我一无所获。如果有关于此主题的精彩教程,请随时分享。

最佳答案

在 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 ee7abb5commit 46ba2abcommit a551fd5commit 9157a2acommit 210179acommit fbccf25(2019 年 10 月 15 日)作者 James Coglan (jcoglan)
(由 Junio C Hamano -- gitster -- merge 到 commit 0be5caf ,2019 年 12 月 1 日)

graph: fix coloring of octopus dashes

Signed-off-by: James Coglan

In 04005834ed ("log: fix coloring of certain octopus merge shapes", 2018-09-01, Git v2.20.0-rc0 -- merge listed in batch #6), there is a fix for the coloring of dashes following an octopus merge.
It makes a distinction between the case where all parents introduce a new column, versus the case where the first parent collapses into an existing column:

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

The latter case means that the columns for the merge parents begin one place to the left in the new_columns array compared to the former case.

However, the implementation only works if the commit's parents are kept in order as they map onto the visual columns, as we get the colors by iterating over new_columns as we print the dashes.
In general, the commit's parents can arbitrarily merge with existing columns, and change their ordering in the process.

For example, in the following diagram, the number of each column indicates which commit parent appears in each column.

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

If the columns are colored (red, green, yellow, blue), then the dashes will currently be colored yellow and blue, whereas they should be blue and red.

To fix this, we need to look up each column in the mapping array, which before the GRAPH_COLLAPSING state indicates which logical column is displayed in each visual column.
This implementation is simpler as it doesn't have any edge cases, and it also handles how left-skewed first parents are now displayed:

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

The color of the first dashes is always the color found in mapping two columns to the right of the commit symbol. Because commits are displayed after all edges have been collapsed together and the visual columns match the logical ones, we can find the visual offset of the commit symbol using commit_index.


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

graph: smooth appearance of collapsing edges on commit lines

Signed-off-by: James Coglan

When a graph contains edges that are in the process of collapsing to the left, but those edges cross a commit line, the effect is that the edges have a jagged appearance:

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

We already takes steps to smooth edges like this when they're expanding; when an edge appears to the right of a merge commit marker on a GRAPH_COMMIT line immediately following a GRAPH_POST_MERGE line, we render it as a \:

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

We can make a similar improvement to collapsing edges, making them easier to follow and giving the overall graph a feeling of increased symmetry:

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

To do this, we introduce a new special case for edges on GRAPH_COMMIT lines that immediately follow a GRAPH_COLLAPSING line.
By retaining a copy of the mapping array used to render the GRAPH_COLLAPSING line in the old_mapping array, we can determine that an edge is collapsing through the GRAPH_COMMIT line and should be smoothed.


更一般地说:

graph: commit and post-merge lines for left-skewed merges

Signed-off-by: James Coglan

Following the introduction of "left-skewed" merges, which are merges whose first parent fuses with another edge to its left, we have some more edge cases to deal with in the display of commit and post-merge lines.

The current graph code handles the following cases for edges appearing to the right of the commit (*) on commit lines.

A 2-way merge is usually followed by vertical lines:

| | |
| * |
| |\ \

An octopus merge (more than two parents) is always followed by edges sloping to the right:

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

A 2-way merge is followed by a right-sloping edge if the commit line immediately follows a post-merge line for a commit that appears in the same column as the current commit, or any column to the left of that:

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

This commit introduces the following new cases for commit lines. If a 2-way merge skews to the left, then the edges to its right are always vertical lines, even if the commit follows a post-merge line:

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

A commit with 3 parents that skews left is followed by vertical edges:

| | |
| * |
|/|\ \

If a 3-way left-skewed merge commit appears immediately after a post-merge line, then it may be followed the right-sloping edges, just like a 2-way merge that is not skewed.

| |\
| * \
|/|\ \

Octopus merges with 4 or more parents that skew to the left will always be followed by right-sloping edges, because the existing columns need to expand around the merge.

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

On post-merge lines, usually all edges following the current commit slope to the right:

| * | |
| |\ \ \

However, if the commit is a left-skewed 2-way merge, the edges to its right remain vertical.
We also need to display a space after the vertical line descending from the commit marker, whereas this line would normally be followed by a backslash.

| * | |
|/| | |

If a left-skewed merge has more than 2 parents, then the edges to its right are still sloped as they bend around the edges introduced by the merge.

| * | |
|/|\ \ \

To handle these new cases, we need to know not just how many parents each commit has, but how many new columns it adds to the display; this quantity is recorded in the edges_added field for the current commit, and prev_edges_added field for the previous commit.

Here, "column" refers to visual columns, not the logical columns of the columns array.
This is because even if all the commit's parents end up fusing with existing edges, they initially introduce distinct edges in the commit and post-merge lines before those edges collapse.

For example, a 3-way merge whose 2nd and 3rd parents fuse with existing edges still introduces 2 visual columns that affect the display of edges to their right.

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

This merge does not introduce any logical columns; there are 4 edges before and after this commit once all edges have collapsed. But it does initially introduce 2 new edges that need to be accommodated by the edges to their right.


经典输出已被简化:

graph: example of graph output that can be simplified

Signed-off-by: James Coglan

The commits following this one introduce a series of improvements to the layout of graphs, tidying up a few edge cases, namely:

  • merge whose first parent fuses with an existing column to the left
  • merge whose last parent fuses with its immediate neighbor on the right
  • edges that collapse to the left above and below a commit line

This test case exemplifies these cases and provides a motivating example of the kind of history I'm aiming to clear up.

The first parent of merge E is the same as the parent of H, so those edges fuse together.

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

We can "skew" the display of this merge so that it doesn't introduce additional columns that immediately collapse:

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

The last parent of E is D, the same as the parent of F which is the edge to the right of the merge.

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

The two edges leading to D could be fused sooner: rather than expanding the F edge around the merge and then letting the edges collapse, the F edge could fuse with the E edge in the post-merge line:

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

If this is combined with the "skew" effect above, we get a much cleaner graph display for these edges:

* F
|
| E
|
|
* D

Finally, the edge leading from C to A appears jagged as it passes through the commit line for B:

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

This can be smoothed out so that such edges are easier to read:

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

自从最近对日志图渲染代码进行更新后,绘制某些 merge 开始在不再成立的条件下触发断言,这已通过 Git 2.25(2020 年第一季度)得到纠正。

参见 commit a1087c9commit 0d251c3(2020 年 1 月 7 日),作者 Derrick Stolee (derrickstolee)
(由 Junio C Hamano -- gitster -- merge 到 commit 1f5f3ff ,2020 年 1 月 8 日)

graph: drop assert() for merge with two collapsing parents

Helped-by: Jeff King
Reported-by: Bradley Smith
Signed-off-by: Derrick Stolee

When "git log --graph" shows a merge commit that has two collapsing lines, like:

| | | | *
| |_|_|/|
|/| | |/
| | |/|
| |/| |
| * | |
* | | |

we trigger an assert():

graph.c:1228: graph_output_collapsing_line: Assertion
`graph->mapping[i - 3] == target' failed.

The assert was introduced by eaf158f8 ("graph API: Use horizontal lines for more compact graphs", 2009-04-21, Git v1.6.4-rc0 -- merge), which is quite old.
This assert is trying to say that when we complete a horizontal line with a single slash, it is because we have reached our target.

It is actually the _second_ collapsing line that hits this assert.
The reason we are in this code path is because we are collapsing the first line, and in that case we are hitting our target now that the horizontal line is complete.
However, the second line cannot be a horizontal line, so it will collapse without horizontal lines. In this case, it is inappropriate to assert that we have reached our target, as we need to continue for another column before reaching the target.
Dropping the assert is safe here.

The new behavior in 0f0f389f12 ("graph: tidy up display of left-skewed merges", 2019-10-15, Git v2.25.0-rc0 -- merge listed in batch #2) caused the behavior change that made this assertion failure possible.
In addition to making the assert possible, it also changed how multiple edges collapse.

In a larger example, the current code will output a collapse as follows:

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

However, the intended collapse should allow multiple horizontal lines as follows:

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

This behavior is not corrected by this change, but is noted for a later update.


通过“git log --graph”呈现导致 merge 提交的祖先行在最近的更新中变得次优以浪费垂直空间,已使用 Git 2.26 (Q1) 更正2020 年)。

参见 commit c958d3bcommit 8588932(2020 年 1 月 8 日),作者 Derrick Stolee (derrickstolee)
(由 Junio C Hamano -- gitster -- merge 到 commit d52adee ,2020 年 1 月 30 日)

graph: fix collapse of multiple edges

Signed-off-by: Derrick Stolee

This fix resolves the previously-added test_expect_failure in t4215-log-skewed-merges.sh.

The issue lies in the "else" condition while updating the mapping inside graph_output_collapsing_line().
In 0f0f389f ("graph: tidy up display of left-skewed merges", 2019-10-15, Git v2.25.0-rc0 -- merge listed in batch #2), the output of left-skewed merges was changed to allow an immediate horizontal edge in the first parent, output by graph_output_post_merge_line() instead of by graph_output_collapsing_line().
This condensed the first line behavior as follows:

Before 0f0f389f:

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

After 0f0f389f:

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

However, a very subtle issue arose when the second and third parent edges are collapsed in later steps. The second parent edge is now immediately adjacent to a vertical edge. This means that the condition

} else if (graph->mapping[i - 1] < 0) {

in graph_output_collapsing_line() evaluates as false. The block for this condition was the only place where we connected the target column with the current position with horizontal edge markers.

In this case, the final "else" block is run, and the edge is marked as horizontal, but did not back-fill the blank columns between the target and the current edge.
Since the second parent edge is marked as horizontal, the third parent edge is not marked as horizontal.
This causes the output to continue as follows:

Before this change:

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

By adding the logic for "filling" a horizontal edge between the target column and the current column, we are able to resolve the issue.

After this change:

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

This output properly matches the expected blend of the edge behavior before 0f0f389f and the merge commit rendering from 0f0f389f.

关于git - 如何理解 git log --graph,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20200226/

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