gpt4 book ai didi

git - git log 的祖先路径如何处理多个否定提交?

转载 作者:行者123 更新时间:2023-12-03 14:28:05 24 4
gpt4 key购买 nike

git --ancestry-path 的行为git log 的选项或 git rev-list当只有一个否定提交时相对简单 - 也就是说,如果您有:

git rev-list ^A B
# or it's shorthand form:
git rev-list A..B
...然后结果是所有作为 A 的后代和 B 的祖先的提交(有关更完整的解释,请参见 here )。
但是,我想知道 --ancestry-path如果您有两个(或更多)否定修订,则行为 - 即:
git rev-list ^C ^A B
(注意——我将把非否定的修订,例如上面的 B 称为“积极”提交,而所有否定的修订都称为“否定”提交。)
在检查了一些简单测试用例的结果后, --ancestry-path 施加的“后代”限制对于负面提交似乎是 OR'd/union'ed 在一起 - 也就是说,git似乎正在做:
  • 首先,找到至少一个肯定提交
  • 的祖先的所有提交
  • 然后,过滤到仅作为至少一个否定提交
  • 的后代的提交
  • 然后,过滤掉至少一个否定提交
  • 的祖先的提交

    或者,用更类似集合的表示法:
    IntersectionOf(
    Union(ancestors(positive1), ...ancestors(positiveN))
    AND
    Union(descendents(negative1), ...descendents(negativeN))
    )
    - Union(ancestors(negative1), ...ancestors(negativeN))
    然而,在一些更复杂的场景中,这被证明是不正确的——最终结果中排除的提交比上述逻辑所暗示的要多。
    例如,假设您有这个完整的图表:
    ancestors(MA3)

    -----MA3
    / |
    / MB3
    A3 /|
    /| B3 |
    / | /| |
    R3-+--- | |
    | | | |
    | | --+--MA2
    | | / | |
    | |/ | MB2
    | A2 | /|
    | /| B2 |
    |/ | /| |
    R2-+--- | |
    | | | |
    | | --+--M1
    | | / | /
    | A1 | /
    | / B1
    |/ /
    R1-----
    这表示一个共同的根分支 (R),特征分支 A 和 B 都继承自该分支,并且 A 和 B 依次 merge 为一个共同的 merge 分支 (M)。 ( And here's a bash script to set up a repo with this structure!)
    我们希望找到:
    --ancestry-path ^R2 ^B3 MA3
    如果我们这样做
    Union(descendents(R2),      Union(ancestors(R2),
    descendents(B3)) ancestors(B3))

    -----MA3
    / |
    / MB3
    A3 /|
    /| B3 | B3
    / | /| | /|
    R3-+--- | | R3----- |
    | | | | |
    | --+--MA2 | |
    | / | | | |
    |/ | MB2 MINUS | |
    A2 | / | |
    B2 | B2
    | /|
    R2----- |
    | |
    | |
    | |
    | |
    | B1
    | /
    R1-----
    那么我们期望:
          -----MA3
    / |
    / MB3
    A3 |
    | |
    | |
    | |
    | |
    | -----MA2
    | / |
    |/ MB2
    A2
    然而,我们实际上得到了什么
    git rev-list --ancestry-path ^R2 ^B3 MA3 | xargs -i git tag --points-at '{}'
    是:
    MA3
    MB3
    A3
    MA2
    A2
    IE:
          -----MA3
    / |
    / MB3
    A3 |
    | |
    | |
    | |
    | |
    | -----MA2
    | /
    |/
    A2
    ...这是相同的,除了 MB2 被排除在外。
    所以,很明显,我猜如何 --ancestry-path与多个 ^ 一起使用否定是错误的。谁能解释 git 实际使用的逻辑,以及为什么排除 MB2 ?
    编辑
    所以,只是为了直观地澄清下面 jthill 的答案( https://stackoverflow.com/a/65450624/920545 ),他说它是这样工作的:
  • 首先,git计算ancestors(MA3) - Union(ancestors(R2), ancestors(B3) - 所以我们最终得到:
  • ancestors(MA3) - Union(ancestors(R2),
    ancestors(B3))

    -----MA3
    / |
    / MB3
    A3 |
    | |
    | |
    | |
    | |
    | -----MA2
    | / |
    |/ MB2
    A2 |
    | |
    | |
    + |
    | |
    | -----M1
    | /
    A1
    然后它会尝试沿着从 R2 开始的路径查找所有节点。或 B3MA3 ,使用这组有限的节点。因此,它尝试在此图上找到从 (x) 到 [y] 的所有路径:
            ----[MA3]
    / |
    / MB3
    A3 /|
    | (B3) |
    | |
    | |
    | |
    | -----MA2
    | / |
    |/ MB2
    A2 |
    /| |
    / | |
    (R2) | |
    | |
    | -----M1
    | /
    A1
    ...这就是为什么我们最终得到我上面显示的结果。谢谢你!

    最佳答案

    MB2位于 R2 的祖先路径上,顾名思义,但是当您排除 B3 的祖先时,该祖先路径超出了您设置的范围。从你的步行。
    Git 正在做你所要求的:采取 MA3及其所有祖先,不包括 B3R2以及他们所有的祖先,然后尝试将祖先路径追溯到排除的提示。
    得到的效果通常会产生与 all-descendants-minus-all-ancestors 追踪相同的结果,但您发现了差异很重要的情况。 Git追溯祖先,而不是血统。

    关于git - git log 的祖先路径如何处理多个否定提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65259554/

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