[英]How does ancestry path work with git log?
I've read the git log documentation , but I still find it very difficult to understand what the --ancestry-path
option does.我已经阅读了git 日志文档,但我仍然很难理解--ancestry-path
选项的作用。 I see different ways to invoke git log
:我看到调用git log
的不同方法:
$ git log origin/master..HEAD
$ git log --ancestry-path origin/master..HEAD
In the first command, I get a list of commits that are on HEAD but not on origin/master
, basically this shows me what is on my branch that isn't merged.在第一个命令中,我得到一个在 HEAD 但不在origin/master
上的提交列表,基本上这向我显示了我的分支上未合并的内容。
In the second command, I get nothing.在第二个命令中,我什么也没得到。 If I change to 3 dots ( ...
) it shows me something , but I'm not sure how to make sense of it.如果我改为 3 个点 ( ...
),它会向我展示一些东西,但我不知道如何理解它。 Basically, how is the addition of --ancestry-path
any different?基本上,添加--ancestry-path
有什么不同? What exactly does it simplify ?它究竟简化了什么?
Matthieu Moy's answer is correct but may not help you very much, if you haven't been exposed to the necessary graph theory. Matthieu Moy 的回答是正确的,但如果您没有接触过必要的图论,可能不会对您有多大帮助。
First, let's take a quick look at D irected A cyclic G raphs or DAGs.首先,让我们快速浏览一下d irected的循环摹raphs或DAG的。 A DAG is just a graph (hence the g
), ie, a collection of nodes and connections between them—these work like train stations on rail lines, for instance, where the stations are the nodes—that is "directed" (the d
: trains only run one way) and have no loops in them (the a
). DAG 只是一个图(因此g
),即节点和它们之间的连接的集合 - 这些工作就像铁路线上的火车站,例如,车站是节点 - 即“有向”( d
:火车只以一种方式运行)并且其中没有循环( a
)。
Linear chains and tree structures are valid DAGs (note: newer commits are to the right, in general, here):线性链和树结构是有效的 DAG(注意:较新的提交在右边,一般来说,在这里):
o <- o <- o
or:或:
o <- o
/
o <- o
\ o
\ /
o
\
o <- o
(imagine the diagonal connections having arrow heads so that they point up-and-left or down-and-left, as needed). (想象一下有箭头的对角线连接,以便它们根据需要向上和向左或向下和向左指向)。
However, non-tree graphs can have nodes that merge back (these are git's merges):但是,非树图可以具有合并回的节点(这些是 git 的合并):
o <- o
/ \
o <- o \
\ o \
\ / \
o o
\ /
o <- o
or:或:
o--o
/ \
o--o o--o
\ /
o--o
(I'm just compressing the notation further here, nodes still generally point leftward). (我只是在这里进一步压缩符号,节点通常仍指向左侧)。
Next, git's ..
notation does not mean what most people usually first think it means.其次,git 的..
符号并不意味着大多数人通常首先认为的意思。 In particular, let's take a look at this graph again, add another node, and use some single letters to mark particular nodes:特别是,让我们再次看一下这个图,添加另一个节点,并使用一些单个字母来标记特定节点:
o---o
/ \
A--o \
\ B \
\ / \
o C--D
\ /
o---o
And, let's do one more thing, and stop thinking about this as just git log
but rather the more general case of "selecting revisions with ancestry".并且,让我们再做一件事,不要将其视为git log
,而是“选择具有祖先的修订”的更一般情况。
If we select revision A
, we get just revision A
, because it has no ancestors (nothing to the left of it).如果我们选择修订版A
,我们只会得到修订版A
,因为它没有祖先(它的左边没有任何东西)。
If we select revision B
we get this piece of the graph:如果我们选择修订版B
我们会得到这张图:
A--o
\ B
\ /
o
This is because select-with-ancestry means "Take the commit I identify, and all the commits I can get to by following the arrows back out of it."这是因为 select-with-ancestry 的意思是“获取我确定的提交,以及我可以通过跟随箭头返回的所有提交。” Here the result is somewhat interesting, but not very interesting since there are no merges and following the arrows nets us a linear chain of four commits, starting from B
and going back to A
.这里的结果有点有趣,但不是很有趣,因为没有合并,并且按照箭头为我们提供了四个提交的线性链,从B
开始并返回到A
。
Selecting either C
or D
with ancestry, though, gets us much further.但是,选择具有祖先的C
或D
会让我们走得更远。 Let's see what we get with D
:让我们看看D
得到了什么:
o---o
/ \
A--o \
\ \
\ \
o C--D
\ /
o---o
This is, in fact, everything except commit B
.事实上,这就是除了提交B
之外的所有内容。 Why didn't we get B
?为什么我们没有得到B
? Because the arrows all point leftward: we get D
, which points to C
, which points to two un-lettered commits;因为箭头都指向左边:我们得到D
,它指向C
,它指向两个无字母的提交; those two point left, and so on, but when we hit the node just left-and-down of B
, we aren't allowed to go rightward, against the arrow, so we can't reach B
.这两个点向左,依此类推,但是当我们击中B
左下方的节点时,我们不允许逆着箭头向右走,因此我们无法到达B
。
Now, the two-dot notation in git is really just shorthand syntax for set subtraction.现在,git 中的两点表示法实际上只是集合减法的速记语法。 1 That is, if we write B..D
for instance, it means: "Select D
with ancestry, and then select B
with ancestry, and then give me the set of commits from the D
selection after excluding (subtracting away) all commits from the B
selection." 1也就是说,如果我们以B..D
为例,它的意思是:“选择D
with ancestry,然后选择B
with ancestry,然后在排除(减去)所有提交后从D
选择中给我一组提交从B
选择。”
Selecting D
with ancestry gets the entire graph except for the B
commit.选择具有祖先的D
将获得除B
提交之外的整个图。 Subtracting away the B
selection removes A
, the two o
nodes we drew earlier, and B
.减去B
选择将删除A
、我们之前绘制的两个o
节点和B
。 How can we remove B
when it's not in the set?当B
不在集合中时,我们如何删除它? Easy: we just pretend to remove it and say we're done!简单:我们只是假装删除它并说我们完成了! That is, set subtraction only bothers to remove things that are actually in the set.也就是说,集合减法只会删除实际上在集合中的东西。
The result for B..D
is therefore this graph:因此B..D
的结果是这个图:
o---o
\
\
\
\
C--D
/
o---o
The three-dot notation is different.三点符号是不同的。 It's more useful in a simple branch-y graph, perhaps even a straight tree.它在简单的分支 y 图中更有用,甚至可能是直树。 Let's start with the tree-like graph this time and look at both two- and three-dot notation.这次让我们从树状图开始,看看两点和三点表示法。 Here's our tree-like graph, with some single letter names for nodes put in:这是我们的树状图,其中包含一些节点的单字母名称:
o--I
/
G--H
\ J
\ /
K
\
o--L
This time I've added extra letters because we'll need to talk about some of the places the commits "join up", in particular at nodes H
and K
.这次我添加了额外的字母,因为我们需要讨论提交“连接”的一些地方,特别是在节点H
和K
。
Using two-dot notation, what do we get for L..I
?使用两点表示法,我们可以得到L..I
什么? To find the answer, start at node I
and work backwards.要找到答案,请从节点I
开始并向后工作。 You must always move leftward, even if you also go up or down.您必须始终向左移动,即使您也向上或向下移动。 These are the commits that are selected.这些是选择的提交。 Then, start at node L
and work backwards, finding the nodes to un -select;然后,从节点L
开始向后工作,找到要取消选择的节点; if you come across any earlier selected ones, toss them out.如果您遇到任何较早选择的内容,请将它们扔掉。 (Making the final list is left as an exercise, though I'll put the answer in as a footnote. 2 ) (制作最终列表留作练习,但我会将答案放在脚注中。2 )
Now let's see the three-dot notation in action.现在让我们看看实际使用的三点符号。 What it does is a bit complicated, because it must find the merge base between two branches in the graph.它所做的有点复杂,因为它必须找到图中两个分支之间的合并基。 The merge base has a formal definition, 3 but for our purposes it's just: "The point where, when following the graph backwards, we meet up at some commit."合并基础有一个正式的定义, 3但就我们的目的而言,它只是:“当向后跟踪图表时,我们会在某个提交处相遇。”
In this case, for instance, if we ask for L...I
or I...L
—both produce the same result—git finds all commits that are reachable from either commit, but not from both .在这种情况下,例如,如果我们要求L...I
或I...L
两者都产生相同的结果——git 会找到所有可从任一提交访问的提交,但不能从两者中找到。 That is, it excludes the merge base and all earlier commits, but keeps the commits beyond that point.也就是说,它排除了合并基础和所有较早的提交,但保留了超出该点的提交。
The merge base of L
and I
(or I
and L
) is commit H
, so we get things after H
, but not H
itself, and we cannot reach node J
from either I
or L
since it's not in their ancestry. L
和I
(或I
和L
)的合并基础是提交H
,所以我们在H
之后得到东西,但不是H
本身,而且我们无法从I
或L
到达节点J
,因为它不在它们的祖先中。 Hence, the result for I...L
or L...I
is:因此, I...L
或L...I
是:
o--I
K
\
o--L
(Note that these histories do not join up, since we tossed out node H
.) (请注意,这些历史记录不会合并,因为我们丢弃了节点H
。)
--ancestry-path
Now, all these are ordinary selection operations.现在,所有这些都是普通的选择操作。 None have been modified with --ancestry-path
.没有被修改过--ancestry-path
。 The documentation for git log
and git rev-list
—these two are almost the same command, except for their output format—describes --ancestry-path
this way: git log
和git rev-list
的文档——这两个命令几乎相同,除了它们的输出格式——这样描述--ancestry-path
:
When given a range of commits to display (eg
commit1..commit2
orcommit2 ^commit1
), only display commits that exist directly on the ancestry chain between thecommit1
andcommit2
, ie commits that are both descendants ofcommit1
, and ancestors ofcommit2
.当给定要显示的提交范围(例如commit1..commit2
或commit2 ^commit1
)时,仅显示直接存在于commit1
和commit2
之间的祖先链上的提交,即既是commit1
后代又是commit1
祖先的commit2
。
We define ancestors here in terms of the commit DAG: a first commit is a direct ancestor of a second if the second has an arrow pointing back at the first, and an indirect ancestor if the second points back at the first through some chain of commits.我们在这里根据提交 DAG 定义祖先:如果第二个提交的箭头指向第一个,则第一个提交是第二个的直接祖先,如果第二个提交通过一些提交链指向第一个,则为间接祖先. (For selection purposes a commit is also considered an ancestor of itself.) (出于选择目的,提交也被视为其自身的祖先。)
Descendants (also sometimes called children ) are defined similarly, but by going against the arrows in the graph.后代(有时也称为children )的定义类似,但与图中的箭头相反。 A commit is a child (or descendant) of another commit if there's a path between them.如果它们之间存在路径,则提交是另一个提交的子项(或后代)。
Note that the description of the --ancestry-path
talks about using the two-dot notation, not the three-dot notation, probably because the implementation of the three-dot notation is a little bit weird inside.请注意,-- --ancestry-path
的描述谈到使用两点表示法,而不是三点表示法,可能是因为三点表示法的实现内部有点奇怪。 As noted earlier, B...D
excludes (as if with leading ^
) the merge base (or bases, if there is/are more than one) of the two commits, so the merge base is the one that play the "must be child-of" role.如前所述, B...D
排除了(好像带有前导^
)两个提交的合并基(或基,如果有/多于一个),因此合并基是播放“必须成为孩子”的角色。 I'll mention how --ancestry-path
works with this, though I'm not sure how useful it is in "real world" examples.我会提到--ancestry-path
如何与它一起工作,尽管我不确定它在“现实世界”的例子中有多有用。
What does this mean in practice?这在实践中意味着什么? Well, it depends on the arguments you give, and the actual commit DAG.好吧,这取决于您提供的参数以及实际提交的 DAG。 Let's look at the funky loopy graph again:让我们再看看这个时髦的循环图:
o---o
/ \
A--o \
\ B \
\ / \
o C--D
\ /
o---o
Suppose we ask for B..D
here without --ancestry-path
.假设我们在这里要求B..D
没有--ancestry-path
。 This means we take commit D
and its ancestors, but exclude B
and its ancestors, just as we saw before.这意味着我们接受提交D
及其祖先,但排除B
及其祖先,就像我们之前看到的那样。 Now let's add --ancestry-path
.现在让我们添加--ancestry-path
。 Everything we had earlier was an ancestor of D
, and that's still true, but this new flag says we must also toss out commits that are not children of B
.我们之前所有的东西都是D
的祖先,这仍然是真的,但是这个新标志说我们还必须扔掉不是B
孩子的提交。
How many children does node B
have?节点B
有多少个孩子? Well, none!嗯,没有! So we must toss out every commit, giving us a completely empty list .所以我们必须扔掉每一次提交,给我们一个完全空的 list 。
What if we ask for B...D
, without the special --ancestry-path
notation?如果我们要求B...D
,而没有特殊的--ancestry-path
符号怎么办? That gives us everything reachable from either D
or B
, but excludes everything reachable from both D
and B
:这给了我们从D
或B
可达的一切,但排除了从D
和B
可达的一切:
o---o
\
\
B \
\
C--D
/
o---o
This is the same as B..D
except that we get node B
as well.这与B..D
相同,只是我们也得到了节点B
[Note: the section below on mixing --ancestry-path
with B...D
was wrong for almost a year, between April 2016 and Feb 2017. It has been fixed to note that the "must be child" part starts from the merge base(s) , not from the left side of the B...D
notation.] [注意:下面关于将--ancestry-path
与B...D
混合的部分在 2016 年 4 月至 2017 年 2 月之间错误了将近一年。它已被修复以注意“必须是孩子”部分从合并 base(s) ,而不是从B...D
符号的左侧。]
Suppose we add --ancestry-path
here.假设我们在这里添加--ancestry-path
。 We start with the same graph we just got for B...D
without --ancestry-path
, but then discard items that are not children of the merge base.我们从刚刚为B...D
获得的相同图开始,没有--ancestry-path
,然后丢弃不是合并基础的子项的项目。 The merge base is the o
just to the left of B
.合并基础是B
左侧的o
。 The top row o
commits are not children of this node, so they are discarded.第一行o
提交不是该节点的子节点,因此它们被丢弃。 Again, as with ancestors, we consider a node its own child, so we would keep this node itself—giving this partial result:同样,与祖先一样,我们认为一个节点是它自己的子节点,所以我们会保留这个节点本身——给出这个部分结果:
B
/
o C--D
\ /
o---o
But, while we are (or --ancestry-path
is) discarding children of this merge base node, the merge base node itself, to the down-and-left of B
, was not in the B...D
graph in the first place.但是,虽然我们(或--ancestry-path
是)丢弃了这个合并基节点的子节点,但合并基节点本身,在B
的左下角,不在B...D
图中第一名。 Hence, the final result (actually tested in Git 2.10.1) is:因此,最终结果(实际在 Git 2.10.1 中测试过)是:
B
C--D
/
o---o
(Again, I'm not really sure how useful this is in practice. The starting graph, again, is that of B...D
: everything reachable from either commit, minus everything reachable from both commits: this works by discarding starting from every merge base, if there are two or more. The child-of checking code also handles a list of commits. It retains everything that is a child of any of the merge bases, if there are multiple merge bases. See the function limit_to_ancestry
in revision.c
.) (同样,我不确定这在实践中有多有用。同样,起始图是B...D
:从任一提交可到达的所有内容,减去从两个提交可到达的所有内容:这通过丢弃从每一个合并的基础上,如果有两个或更多。孩子-的检查代码还处理提交的清单。它保留一切是任何合并基础的孩子,如果有多个合并基地。参见功能limit_to_ancestry
在revision.c
.)
The final action of X..Y
or X...Y
, with or without --ancestry-path
, depends on the commit graph. X..Y
或X...Y
的最终操作,有或没有--ancestry-path
,取决于提交图。 To predict it, you must draw the graph.要预测它,您必须绘制图形。 (Use git log --graph
, perhaps with --oneline --decorate --all
, or use a viewer that draws the graph for you.) (使用git log --graph
,也许使用--oneline --decorate --all
,或者使用为您绘制图形的查看器。)
1 There's an exception in git diff
, which does its own special handling for X..Y
and X...Y
. 1 git diff
有一个例外,它对X..Y
和X...Y
进行自己的特殊处理。 When you are not using git diff
you should just ignore its special handling.当您不使用git diff
您应该忽略它的特殊处理。
2 We start with I
and the o
to its left, and also H
and G
. 2我们从I
和左边的o
开始,还有H
和G
。 Then we lose H
and G
when we work back from L
, so the result is just o--I
.然后当我们从L
返回时我们失去了H
和G
,所以结果只是o--I
。
3 The formal definition is that the merge base is the L owest C ommon A ncestor, or LCA, of the given nodes in the graph. 3正式定义是,合并的碱是在图中所述给定节点的L个Ç亏欠于ommon甲ncestor,或LCA,。 In some graphs there may be multiple LCAs;在某些图中,可能有多个 LCA; for Git, these are all merge bases, and X...Y
will exclude all of them.对于 Git,这些都是合并基础,而X...Y
将排除所有这些基础。
It's interesting / instructive to run git rev-parse B...D
for the graph I drew.为我绘制的图形运行git rev-parse B...D
很有趣/很有启发性。 These commit hashes here depend on not just the graph itself, and the commit, but also the time stamps at which one makes the commits, so if you build this same graph, you will get different hashes, but here are the ones I got while revising the answer to fix the description of --ancestry-path
interacting with B...D
:这里的这些提交哈希不仅取决于图本身和提交,还取决于提交的时间戳,因此如果您构建相同的图,您将获得不同的哈希,但这里是我得到的修改答案以修复--ancestry-path
与B...D
交互的描述:
$ git rev-parse B...D
3f0490d4996aecc6a17419f9cf5a4ab420c34cc2
7f0b666b4098282301a9f95e056a646483c2e5fc
^843eaf75d78520f9a569da35d4e561a036a7f107
but we can see that these are D
, B
, and the merge base, in that order, using several more commands:但是我们可以看到这些是D
, B
和合并基础,按这个顺序,使用更多的命令:
$ git rev-parse B # this produces the middle hash
7f0b666b4098282301a9f95e056a646483c2e5fc
and:和:
$ git rev-parse D # this produces the first hash
3f0490d4996aecc6a17419f9cf5a4ab420c34cc2
and:和:
$ git merge-base B D # this produces the last, negated, hash
843eaf75d78520f9a569da35d4e561a036a7f107
Graphs with multiple merge bases do occur, but they're somewhat harder to construct—the easy way is with "criss cross" merges, where you run git checkout br1; git merge br2; git checkout br2; git merge br1
具有多个合并基础的图确实会出现,但它们构建起来有些困难——简单的方法是使用“交叉”合并,在那里你运行git checkout br1; git merge br2; git checkout br2; git merge br1
git checkout br1; git merge br2; git checkout br2; git merge br1
git checkout br1; git merge br2; git checkout br2; git merge br1
. git checkout br1; git merge br2; git checkout br2; git merge br1
。 If you get this situation and run git rev-list
you will see several negated hashes, one per merge base.如果你遇到这种情况并运行git rev-list
你会看到几个否定的哈希,每个合并基础一个。 Run git merge-base --all
and you will see the same set of merge bases.运行git merge-base --all
,您将看到相同的合并基础集。
As the documentation says, --ancestry-path
removes commits that are not descendant of origin/master
.正如文档所说, --ancestry-path
删除不是origin/master
后代的提交。 If you have a local, unmerged branch, and this branch is based on a commit which is older than origin/master
, then commits in this branch will not be shown because these commits are not descendant of origin/master
.如果您有一个本地未合并的分支,并且此分支基于比origin/master
更旧的提交,则不会显示此分支中的提交,因为这些提交不是origin/master
后代。
Git 2.38 (Q3 2022) illustrates how git log --ancestry-path
works, and extends that --ancestry-path
option with a value. Git 2.38(2022 年第三季度)说明了git log --ancestry-path
工作原理,并使用值扩展了--ancestry-path
选项。
" git rev-list --ancestry-path=C A..B
" ( man ) is a natural extension of git rev-list A..B
; " git rev-list --ancestry-path=C A..B
" ( man )是git rev-list A..B
的自然扩展;
instead of choosing a subset of A..B
to those that have ancestry relationship with A
, it lets a subset with ancestry relationship with C
.而不是选择A..B
的子集与那些与A
具有祖先关系的子集,它允许与C
具有祖先关系的子集。
See commit 1838e21 (19 Aug 2022) by Derrick Stolee ( derrickstolee
) .请参阅Derrick Stolee ( derrickstolee
) 的提交 1838e21 (2022 年 8 月 19 日)。
See commit 257418c , commit 11ea33c (19 Aug 2022) by Elijah Newren ( newren
) .请参阅Elijah Newren ( newren
)的提交 257418c 、 提交 11ea33c (2022 年 8 月 19 日)。
(Merged by Junio C Hamano -- gitster
-- in commit 0b08ba7 , 29 Aug 2022) (由Junio C Hamano -- gitster
--在提交 0b08ba7中合并,2022 年 8 月 29 日)
revision
: allow --ancestry-path to take an argumentrevision
:允许 --ancestry-path 接受参数Signed-off-by: Elijah Newren签字人:以利亚·纽伦
Acked-by: Derrick Stolee委托方:Derrick Stolee
We have long allowed users to run eg我们长期以来允许用户运行例如
git log --ancestry-path master..seen
which shows all commits which satisfy all three of these criteria:它显示了满足所有这三个标准的所有提交:
- are an ancestor of
seen
是seen
的祖先- are not an ancestor of
master
不是master
的祖先- have
master
as an ancestor有master
This commit allows another variant:此提交允许另一个变体:
git log --ancestry-path=$TOPIC master..seen
which shows all commits which satisfy all of these criteria:它显示了满足所有这些标准的所有提交:
- are an ancestor of
seen
是seen
的祖先- are not an ancestor of master不是master的祖先
- have
$TOPIC
in their ancestry-path在他们的祖先路径中有$TOPIC
that last bullet can be defined as commits meeting any of these criteria:最后一个项目符号可以定义为满足以下任何标准的提交:
- are an ancestor of
$TOPIC
是$TOPIC
的祖先- have
$TOPIC
as an ancestor有$TOPIC
作为祖先- are
$TOPIC
是$TOPIC
This also allows multiple
--ancestry-path
arguments, which can be used to find commits with any of the given topics in their ancestry path.这也允许多个--ancestry-path
arguments,可用于在其祖先路径中查找具有任何给定主题的提交。
rev-list-options
now includes in its man page : rev-list-options
现在包含在其手册页中:
--ancestry-path[=<commit>]
When given a range of commits to display (eg '
commit1..commit2
' or 'commit2 {caret}commit1
'), only display commits in that range that are ancestors of<commit>
, descendants of<commit>
, or<commit>
itself.当给定要显示的提交范围时(例如“commit1..commit2
”或“commit2 {caret}commit1
”),仅显示该范围内的提交,即<commit>
<commit>
或<commit>
的后代本身。If no commit is specified, use '
commit1
' (the excluded part of the range) as<commit>
.如果未指定提交,则使用“commit1
”(范围的排除部分)作为<commit>
。Can be passed multiple times;可以多次通过; if so, a commit is included if it is any of the commits given or if it is an ancestor or descendant of one of them.如果是这样,如果它是任何给定的提交,或者它是其中一个的祖先或后代,则包含一个提交。
As an example use case, consider the following commit history:作为示例用例,请考虑以下提交历史记录:
----------------------------------------------------------------------- D---E-------F / \ \ B---C---G---H---I---J / \ A-------K---------------L--M -----------------------------------------------------------------------
When we want to find out what commits in
M
are contaminated with the bug introduced byD
and need fixing, however, we might want to view only the subset of 'D..M
' that are actually descendants ofD
, ie excludingC
andK
.但是,当我们想找出M
中的哪些提交被D
引入的错误污染并需要修复时,我们可能只想查看实际上是D
后代的“D..M
”子集,即不包括C
和K
。This is exactly what the
--ancestry-path
option does.这正是--ancestry-path
选项的作用。
Applied to the 'D..M' range, it results in:应用于“D..M”范围,结果为:----------------------------------------------------------------------- E-------F \ \ G---H---I---J \ L--M -----------------------------------------------------------------------
rev-list-options
now includes in its man page : rev-list-options
现在包含在其手册页中:
We can also use
--ancestry-path=D
instead of--ancestry-path
which means the same thing when applied to the 'D..M
' range but is just more explicit.我们也可以使用--ancestry-path=D
而不是--ancestry-path
,这在应用于 'D..M
' 范围时意味着同样的事情,但更明确。If we instead are interested in a given topic within this range, and all commits affected by that topic, we may only want to view the subset of
D..M
which contain that topic in their ancestry path.相反,如果我们对此范围内的给定主题感兴趣,并且所有受该主题影响的提交,我们可能只想查看D..M
的子集,该子集在其祖先路径中包含该主题。So, using
--ancestry-path=H D..M
for example would result in:因此,例如使用--ancestry-path=H D..M
会导致:----------------------------------------------------------------------- E \ G---H---I---J \ L--M -----------------------------------------------------------------------
Whereas
--ancestry-path=K D..M
would result in而--ancestry-path=K D..M
会导致----------------------------------------------------------------------- K---------------L--M -----------------------------------------------------------------------
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.