简单来说,假设:
Before rebase After rebase
A---B---C---F---G (branch) A---B---C---F---G (branch)
\ \ \
D---E---H---I (HEAD) \ E'---H' (HEAD)
\
D---E---H---I
git rebase --onto F D H
这与使用--onto
参数效果相同(因为该参数只接受一个参数):
git rebase D H --onto F
将范围在(D,H]之间的提交(不包括D)变基在F之上。 注意该范围是左开右闭的。 之所以选择左开右闭是因为可以通过输入例如branch
让git
查找从branch
分叉出来的第一个提交,即D
,它导致了H
。
OP案例
o---o (A)
\
o (B)(HEAD)
git checkout B
git rebase --onto B A
可以改为单个命令:
git rebase --onto B A B
看起来出错的地方是
B
的放置位置,这意味着“将导致分支
B
的某些提交移动到
B
的顶部”。问题是什么是“某些提交”。如果添加
-i
标志,则会看到它是由
HEAD
指向的单个提交。该提交被跳过,因为它已经应用于
--onto
目标
B
,因此不会发生任何事情。
在任何重复使用分支名称的情况下,该命令都没有意义。这是因为提交范围将是那个分支中已经存在的一些提交,在重新设置期间,所有这些提交都将被跳过。
进一步解释和适用的
git rebase <upstream> <branch> --onto <newbase>
用法。
git rebase
默认值。
git rebase master
扩展为以下之一:
git rebase --onto master master HEAD
git rebase --onto master master current_branch
重新定义后自动完成结账。
当以标准方式使用时,例如:
git checkout branch
git rebase master
在rebase之后,你不会注意到git
将branch
移动到最新的rebase commit,并执行git checkout branch
(请参见git reflog
历史记录)。当第二个参数是commit hash而不是分支名称时,rebase仍然有效,但没有分支可移动,因此您最终进入"detached HEAD",而不是被检出到已移动的分支。
省略主要分歧提交。
--onto
中的master
取自第一个git rebase
参数。
git rebase master
/ \
git rebase --onto master master
实际上它可以是任何其他提交或分支。这样您就可以通过获取最新的提交并保留主要分叉提交来限制rebase提交的数量。
git rebase --onto master HEAD~
git rebase --onto master HEAD~ HEAD # Expanded.
将由HEAD
指向的单个提交变基到master
,并最终处于“分离头指针”状态。
避免显式检出。
默认的HEAD
或current_branch
参数是从你所在的位置上下文地获取的。这就是为什么大多数人会检出他们想要变基的分支。但是当显式给出第二个变基参数时,您不必先检出再进行变基以隐式方式传递它。
(branch) $ git rebase master
(branch) $ git rebase master branch
(branch) $ git rebase master $(git rev-parse --abbrev-ref HEAD)
这意味着您可以从
任何位置重新安排提交和分支。 因此,与重新安排后自动检出。一起使用,您无需在重新安排之前或之后单独检出重定基分支。(master) $ git rebase master branch
(branch) $
B
后尝试运行git rebase --onto A A
。 - Prihex