简体   繁体   English

`git rebase`使用哪个命令从合并分支中挑选提交?

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

Suppose we have: 假设我们有:

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

(We added an empty file1 and commited to C1 , added an empty file2 and commited to C2 , and so on). (我们添加了一个空file1和致力于为C1 ,加入一个空file2和致力于为C2 ,等等)。

Then we do: 然后我们做:

$ git rebase master

The result is: 结果是:

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

I already created an auto bash script here , you could test it if you want. 我已经在这里创建了一个自动bash脚本,你可以根据需要进行测试。

As I learned from chapter 3.6 in git-scm.com book , Git skipped the C6 which is the merged result, so the C6' isn't presented here. 正如我从git-scm.com一书中的第3.6章中学到的那样 ,Git跳过C6这是合并的结果,所以这里没有提供C6'

My question is, which order Git use to cherry-pick from the topic branch? 我的问题是,Git使用哪个命令从topic分支中挑选? Why the result is ...-C4'--C2'--C5'--C3'--C7' instead of ...-C2'--C3'--C4'--C5'--C7' (which is in order of time)? 为什么结果是...-C4'--C2'--C5'--C3'--C7'而不是...-C2'--C3'--C4'--C5'--C7' (这是按时间顺序)?

(By the way, thanks for the reproducer script—it was extremely helpful here.) (顺便说一下,感谢重现者脚本 - 这里非常有帮助。)

The order has varied in the past, but in general it is generated by running git rev-list (the sister command of git log that produces just hash IDs by default). 顺序在过去有所不同,但一般来说它是通过运行git rev-list (默认情况下只产生哈希ID的git log的姐妹命令)生成的。 Since hash IDs are difficult for humans, it's usually easier to use git log to see the order. 由于哈希ID对于人类来说很难,因此使用git log来查看顺序通常更容易。

In this case the order came from: 在这种情况下,订单来自:

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

However, if we add --topo-order , which git rebase did in various older Git versions, we get: 但是,如果我们添加--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

The actual order is based on commit timestamps in the case where there is more than one active commit to choose from. 在有多个活动提交可供选择的情况下,实际顺序基于提交时间戳。 That is, Git is doing a revision walk, from tip commit backwards. 也就是说,Git正在进行修改,从提示向后提交。 Whenever there is a merge, Git puts all the parents into the priority queue, increasing the number of commits to be visited. 只要有合并,Git就会将所有父项放入优先级队列,从而增加要访问的提交数。 The default sort order for the priority queue is based on committer timestamp. 优先级队列的缺省排序顺序基于提交者时间戳。 Since git rebase does not set any other priority, this is the one that gets used. 由于git rebase没有设置任何其他优先级,因此这是一个被使用的优先级。

(The new-ish, non-topologically-sorted order is a result of the new-ish git rebase--helper internal command, which first appeared in Git version 2.13. The merge "preserving"—really, re-creating—variant of git rebase -p still uses a topological sort. The fancy new labeled git rebase -r does not require a topo-sort.) (新的,非拓扑排序的顺序是新的git rebase--helper内部命令的结果,它首先出现在Git版本2.13中。合并“保留” - 真正的,重新创建变体git rebase -p仍然使用拓扑排序。花哨的新标记git rebase -r不需要拓扑排序。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM