【问题标题】:Mercurial, Get history of branch since last tag - including merged in commitsMercurial,获取自上次标记以来的分支历史记录 - 包括合并提交
【发布时间】:2017-12-18 13:16:12
【问题描述】:

使用 Mercurial,我试图获取自上一个标签以来分支的历史记录。 但我也想包括所有合并的 cmets。

我们的开发人员通常会创建一个分支,做一些工作,可能会多次提交,然后将分支合并回来。

使用:hg log -b 。 -r "last(tagged())::" --template "{desc|firstline}\n"

我会得到“合并”之类的条目 - 没有关于该合并中包含哪些提交的信息。

如何让它包含合并的提交? 我们还有多个活动分支,因此仅包含所有分支的所有提交是行不通的。

【问题讨论】:

    标签: mercurial revision-history


    【解决方案1】:

    这里至少有两个问题(经过分析)源于使用-b .。可能还有更多问题。我会按某种顺序排列它们,不一定是最好的,甚至可能是最差的。 :-)

    -blast(set) 结合起来一般来说是不明智的

    您的-b . 约束意味着您只能获得当前分支上的提交。如果您的 revset 将包含另一个分支上的提交,则这些提交将被排除在外。或者,换一种说法(更具集合论),在hg log 中使用-b . 有点像使用您拥有的任何revset 说明符并添加:

    (revset) & branch(.)
    

    ——虽然只是问了这个问题,但这带来了我不确定的一点:限制是在计算tagged() 之前完成的,还是在计算tagged() 之后完成的? hg --debugger 中的一些讨论告诉我它是“之后”,这意味着我们得到:

    (last(tagged()) & (branch(.))
    

    这意味着如果有标签,例如revs 1、7和34,我们将首先选择rev 34,然后选择分支为当前分支的修订版。假设 rev 7 是当前分支的成员,但 rev 34 不是。 & 的结果就是空集。

    这可能不是这里的问题——实际的最终表达式是,或者可能是,branch(.) & descendants(last(tagged()))——但至少在某些情况下,使用它可能会更好:

    last(tagged() & branch(.))
    

    这样您就可以从已标记的最后一个修订版和当前分支上开始。 (如果这个 revlist 为空,则不清楚下一步应该做什么,但在这个级别很难编程,所以我们假设 revlist 中有一个修订,例如,在我们的示例中为 rev 7。)

    不过,这可能不是您想要的;请参阅下面的最后一节。

    结合 -b 和 DAG 范围

    像 Mercurial 中的 X::Y 这样的 DAG 范围运算符仅表示:所有作为 X 后代的提交/修订,包括 X 本身,以及 Y 的祖先,包括 Y 本身. 完全省略Y 意味着X 的所有后代。没有-b 限制器,您将获得所有 个这样的提交,但使用-b .,您再次将自己限制在当前 分支上的那些提交。 p>

    如果您在一个分支中合并提交,那么您将获得该分支上的合并提交及其祖先和后代。 (请记住,在 Mercurial 中,任何提交永远都在一个分支上:这是提交本身时当前的分支。)但是,如果您在 Mercurial 中使用分支,您可能正在合并位于其他分支机构。如果你想查看任何这些提交,你不能在这里使用-b .

    得到你想要的

    让我们回到上面的第一句话:

    使用 Mercurial,我试图获取自上一个标签以来分支的历史记录。但我也想包括所有被合并的 [commits]。

    让我们画一个或两个简单的例子,看看你可能想要哪些提交。

    这是一个水平图,右侧是较新的提交。每个提交都由o 表示,除非它被标记,在这种情况下它由* 表示。有几个合并。前两行的提交在分支 B1,第三行的提交在分支 B2。

        o--o---o--o---o--*--o--o--o
    b1:     \    /            /
             *--o            /
                 \          /
    b2:           o--*--o--o--o--o
    

    我不清楚你希望看到哪些提交。 b1 上的最后一个标记提交是* 的顶行,但b2 上也有一个标记提交(其版本号可能低于b1 上的版本号)。或者假设我们有一个稍微不同的图表,因此编号最高的标记修订版是b2上的一个:

        o--o---o--o---*--o--o--o--o
    b1:     \    /            /
             *--o            /
                 \          /
    b2:           o--o--*--o--o--o
    

    如果我们使用表达式last(tagged()) 没有任何分支屏蔽,我们将选择最右边的星号提交。如果我们然后将其输入到 DAG 运算符中(例如,作为 X:: 中的 X 或使用 descendants(),我们将获得“之后”的所有提交。

    当我们从b2 上的单个星号提交开始时(如上图所示),我们得到该提交和b2 上的其余三个提交,以及b1 上的最后两个提交。这可能是你想要的,但也许你还想要一些在b1上的提交,这些提交在之前合并,但在(可能包括)最后加星标之后提交在 b1 本身。

    请注意,这就是您使用 descendants(last(tagged()) 得到的结果,即,如果您从原始 hg log 命令中删除 -b .


    当我们从b1 上的最后一个星号提交开始时,就像前面的图表一样,我们只得到那个提交加上分支b1 上的最后三个提交。分支b2 上合并的所有提交都不是我们选择的星号提交的后代。所以 DAG-range 方法本身是可疑的,在这里。不过,如果消除直接在 b1 上的标记提交就足够了,请注意我们可以使用:

    descendants(last(tagged() and not branch(b1)))
    

    (这里and&没有区别,我只是拼出来因为我拼出来了not)。


    我在这里看到另一种可能性:也许您想要 any 提交是当前分支的最终提交的祖先,但在以下位置停止:

    • 任何标记的提交,或
    • 任何其他分支的前任合并,而不是通过遍历祖先到达的第一个合并分支。

    可视化最后一种情况需要更复杂的分支拓扑,总共有两个以上的命名分支。由于 (a) 很难并且 (b) 我完全不清楚这 你想要的,所以我不打算编写表达式来生成它。

    【讨论】:

    • 哇,一篇博士论文!远远超出我的汞技能!因此,使用您的第二个示例图。我对导致 b1 当前状态的任何东西特别感兴趣。每次从它构建安装程序时,我们都会标记一个分支。所以我想要自上次标记 b1 以来进入 b1 的所有内容。看起来这将是 b1 上的最后 4 个更改,而 b2 上的前 3 个更改。这能说明问题吗?
    • 确实如此(澄清事情)。我不确定如何最好地在 Mercurial 中编写它(我更熟悉在 Git 中做事,这确实需要大量的图论,因为 Git 中的分支名称几乎没有意义——所以可能有更短的方法以汞为单位)。我们可能想查看 (tag-on-b1::end-of-b1) 范围内的提交,对于任何合并,查看它们的 p2() 并从那里返回到 tag-on-that-branch .在 shell 中编码,或者在 Python 中的 Mercurial 扩展,只是编程的小问题,但可能不是那么小。 :-)
    猜你喜欢
    • 2011-11-08
    • 2023-03-27
    • 2019-01-24
    • 2013-12-18
    • 2018-05-14
    • 1970-01-01
    • 2013-08-02
    • 2018-02-17
    • 2016-03-13
    相关资源
    最近更新 更多