查找给定祖先的提交

时间:2018-10-08 19:48:14

标签: bash git ancestor

有一次,我的git存储库包含以下结构:

A1    A2    A3
 o-----o-----o
        \     \
         o X   o Y
B1    B2/   B3/
 o-----o-----o
        \
         o Z
C1    C2/
 o-----o

我正在尝试从几个指定的提交中检索最早的提交,该提交是其后代。抢七将成为提交日期。例如:

descendant A1 B2 -> X
descendant A2 B3 -> Y
descendant A1 C1 -> nothing

合并提交可能有两个以上的父级。我找到了许多有关git merge-base的文档,它执行的任务却截然相反,但是找不到任何函数至少可以返回我可以排序的后代列表。

2 个答案:

答案 0 :(得分:0)

这是经过更多研究后我设法完成的工作。这很丑陋,可能效率很低,但看起来确实可行。

#!/bin/bash

common_descendants=$(git rev-list --ancestry-path --all $1.. | sort)
shift

while [ $# -ne 0 ]; do
    common_descendants=$(
        echo "$common_descendants"
        | comm -12 --nocheck-order - <(
            git rev-list --ancestry-path --all $1.. | sort
        )
    )
    shift
done

git rev-list --reverse --date-order --no-walk $common_descendants | head -n 1

它使用git rev-list --ancestry-path --all依次查找每个请求提交的所有后代。
sortcomm的帮助下,将这些列表相交以获得候选提交列表。
最后,git rev-list --ancestry-path --all按提交日期对其进行排序,而head -n 1选择最早的一个。

答案 1 :(得分:0)

chepner commented一样,Git仅具有向后指针。 提交C的查找后代必须转换为一个新的不同问题,即:查找T的祖先,而他们本身以C为始祖。在这里 T 是提示提交,或者在您的情况下,可能是很多提示提交-所有分支,也许还包括所有标签和所有其他引用。

git rev-list命令适合解决该问题。特别是,您可以让它从笔尖(后代)到父级遍历图形,但可以收集在处理过程中遍历的边,然后使用--children将其反转。如the documentation所述,这使父级重写和历史记录简化。

(我认为您需要对选择的任何起始提示提交运行git rev-list --children,然后自己解析其输出以应用其他约束。您可以将要搜索的提交的父级用作停止点,使用the ^hash^@ gitrevisions syntax来削减图的迭代。请注意,这确实领先^,它与--not类似,但应用于rev^@的是局部而不是全局的。)< / p>