`git rebase` 使用哪个顺序从合并的分支中挑选提交?

Which order does `git rebase` use to cherry-pick the commits from a merged branch?

假设我们有:

C1--C2--C3--C6--C7   <- topic, HEAD
 \   \     /
  \  C4--C5      
   \
    C8--C9           <- master

(我们添加了一个空的 file1 并提交到 C1,添加了一个空的 file2 并提交了 C2,等等)。

然后我们做:

$ git rebase master

结果是:

C1--C8--C9                         <- master
         \
         C4'--C2'--C5'--C3'--C7'   <- topic, HEAD

我已经创建了一个自动 bash 脚本 here,如果需要,您可以测试它。

正如我从chapter 3.6 in git-scm.com book中了解到的,Git跳过了合并结果C6,所以C6'没有在这里显示。

我的问题是,Git 使用哪个顺序从 topic 分支中挑选?为什么结果是...-C4'--C2'--C5'--C3'--C7'而不是...-C2'--C3'--C4'--C5'--C7'(按时间排序)?

(顺便说一下,感谢复制器脚本——它在这里非常有用。)

顺序在过去有所不同,但通常它是由 运行 git rev-list 生成的(git log 的姊妹命令,默认情况下只生成哈希 ID)。由于哈希 ID 对人类来说很困难,因此通常使用 git log 查看顺序更容易。

在这种情况下,订单来自:

$ git log --oneline --reverse --no-merges master..topic
5ff52aa C4
aefbb19 C2
0363c27 C5
90aaf5d C3
f953082 (topic) C7

但是,如果我们添加 --topo-ordergit rebase 在各种较旧的 Git 版本中所做的,我们得到:

$ git log --oneline --reverse --topo-order --no-merges master..topic
aefbb19 C2
90aaf5d C3
5ff52aa C4
0363c27 C5
f953082 (topic) C7

在有多个活动提交可供选择的情况下,实际顺序基于提交时间戳。也就是说,Git 正在进行修订,从提示提交向后。每当有合并时,Git 将所有父级放入优先级队列,增加要访问的提交数。优先级队列的默认排序顺序基于提交者时间戳。由于 git rebase 没有设置任何其他优先级,因此这是一个被使用的优先级。

(新的、非拓扑排序的顺序是新的 git rebase--helper 内部命令的结果,它首次出现在 Git 版本 2.13 中。合并 "preserving"——真的,重新创建——git rebase -p 的变体仍然使用拓扑排序。标有 git rebase -r 的花哨新内容不需要拓扑排序。)