git-log:具有拓扑排序的合并提交的祖先分支的输出顺序

问题描述

我的项目中有一段代码依赖于这个命令的输出:

git log -n 2 --topo-order --pretty=format:"%H"

这适用于主分支上的合并提交(合并的拉取请求),并假设结果是当前(合并)提交和来自功能分支的父提交的哈希值。所以例如。

master   a - b - m
          \     /
feature    x - y 

在合并提交 m 上执行时,假定结果将是 m y 而不是 m b。我通过检查多个这样的合并提交来验证确实如此 - 总是返回来自功能分支的父级。但是,在 git-log --topo-order 的文档中,我看到没有保证首先打印哪个父分支。

谁能解释一下在使用 git-log --topo-order 时如何选择首先打印哪个父分支,以及为什么在我的用例中它总是首先显示功能分支?

解决方法

内部 git log 算法是将“新”(未访问)提交插入优先级队列。整个循环是:

while queue is not empty:
    commit = queue.remove_front()
    ... deal with commit ...

其中 deal with 代码可以将提交的父项插入队列。

--topo-order 开关简单地(或复杂地,视情况而定)修改提交的优先级,因为 Git 沿着合并的两条腿前进,以便您从一条腿得到一切,然后从另一条腿得到一切。

作为 joanis notes in a comment,文档明确未指定父排序。这允许 Git 实现在未来切换到新算法,这可能会选择一个不同的“起点”。所以依赖你现在得到的东西是不明智的。

(我认为您现在得到的是父提交按提交者日期顺序排序,因此如果父 #1 的提交者时间戳比父 #2 早,{ {1}}会先追踪第二条腿。但是这段代码非常混乱,而且有很多暗角,所以我不愿意说绝对是这样。)

如果您知道您在某个变量 git log --topo-order 中有一个合并提交哈希 ID,或者通过某个名称 $H 找到,这是获取此哈希 ID 和父哈希 ID 的完全可靠的方法,在那个顺序,就是用 $name 来做:

git rev-parse

或:

git rev-parse ${H} ${H}^2

请注意,如果您有一个任意表达式 git rev-parse ${name} ${name}^2 $expr 可以将其转换为哈希 ID,那么在添加 git rev-parse 后缀以获得第二个父级之前执行一次是明智的。那是因为有些表达式会“使用”后缀。例如,gitrevisions 语法 ^2 是在提交消息中搜索该文本的有效方法。添加 :/fix nasty bug 生成 ^2,它搜索 :/fix nasty bug^2,而不是先找到散列,然后移动到其第二个父项。所以:

bug^2

是一种在 shell 脚本中编写将表达式转换为所需的两个哈希 ID 的命令的可靠方法。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...