对于一个参数,带有和不带有–onto选项的gitrebase有什么区别?
之间有什么区别
git rebase master
git rebase master
git rebase master
和
git rebase --onto master
我在我的分支 X 上,它偏离了 master 并且我运行了这两个命令。然而,第一个要求我在能够推送之前解决很多冲突,而带有 --onto 的第二个命令没有任何冲突。什么解释了这种差异?
回答
rebase 命令需要知道两件事:
- 复制什么(提交什么);和
- 把这些副本放在哪里。
为了获得这两样东西,git rebase需要在最低限度,一个参数,它的git rebase文档,电话upstream:
使用master的upstream参数。
侧边栏:rebase 的工作方式是像用cherry-pick 一样复制
让我们看一个 rebase 的典型案例。我们有:
...--G--H--L <-- master
I--J--K <-- feature
在这里,我们在选择 commit时feature从master分支上创建了一个功能分支 ( ) 。因此,我们进行了提交以保留该功能的更改。(新的提交实际上保存了完整的快照,不仅仅是更改,我们的目的是保存特定的更改。)然后我们必须对 进行快速修复,这导致了 commit 。masterHI-J-KI-J-KmasterL
(最右侧的分支名称保存实际提交的原始哈希 ID。字母代表这些哈希 ID,每个提交通过存储这些前驱提交的原始哈希 ID 向后指向其前驱。 )
现在我们已经 commit L,我们想更新我们的更改以基于K而不是H。要做到这一点,我们可以得到Git的“复制”每次提交,I并J和K,来后L,并基于快照在 L。此 rebase 的最终结果将如下所示:
I'-J'-K' <-- feature
/
...--G--H--L <-- master
I--J--K [abandoned]
哪里I'是我们的副本I,J'是我们的副本J,K'是我们的副本K。新提交具有与旧提交相同的更改。它们的快照和父提交哈希 ID 与旧提交不同——这就是为什么它们具有不同的哈希 ID 和不同的提交——但git log -p或git show将显示与以前相同的更改。
返回变基
为了制作这些副本并实现最终的变基,Git 必须:
- 列出要复制的提交的原始哈希 ID;
- 做一分离的头的提交目标的结帐;
git cherry-pick为每个要复制的提交运行命令或等效命令;- 移动分支名称(使用
git branch -f或git checkout -B)。
对于侧边栏中的情况,一个名称——就master足以确定要复制的内容并决定将副本放在哪里。
该怎样复制部分是运行的问题git rev-list-rev-list是的内部管道变形git log,多数为与等价的:
git rev-list master..feature
此列出了正确的散列的ID:药粥提交I,J和K。
将副本部分放在哪里是运行的问题git checkout --detach master。这让 Git 进入正确的位置,开始进行挑选操作。
(在这一点之后,Git 只做樱桃挑选和最后的分支运动。)
但是,如果我们什么也不想要复制每一个承诺?
这种情况以多种不同的方式发生,但这是一种情况:
...--G--H <-- master
I--J <-- feature1
K--L <-- feature2 (HEAD)
开始我们的特性 2 工作后,我们现在意识到我们错误地在feature1—with commit — 而J不是在masterwith commit结束时开始H。
我们想移植 commits K-L,以便得到这个:
K'-L' <-- feature2
/
...--G--H <-- master
I--J <-- feature1
K--L [abandoned]
如果我们运行:
Git 会运行:
git rev-list master..feature2
这将列出提交I-J-K-L,因为提交I-J 是在feature2. 他们只是在这两个 feature1 和 feature2。(提交通过H在每个分支上。)
这意味着我们需要一种方法来将复制内容部分与副本部分放置位置分开。 添加--onto为我们提供了这种能力。
我们跑:
git rebase --onto master feature1
现在git rebase可以git rev-list feature1..feature2用来列出复制部分的提交,并git checkout --detach master到达放置副本部分的位置。
概括
这就是全部。我们需要--onto当且仅当我们需要将放置副本的位置与要复制的内容分开时。如果我们可以为两者使用单个名称或提交哈希 ID,则不需要--onto. 如果我们需要两个不同的名称和/或哈希 ID,我们需要--onto. 文档调用--onto参数newbase。如果我们省略--onto,则newbase和upstream是相同的名称/哈希ID。
(在您的情况下,您从第二个 rebase 中省略了upstream参数。这导致 Git 使用其默认值:它选择当前分支的上游设置,--fork-point如果您使用的是 Git 2.0 或更高版本,还添加了该选项。)