rebase
Git提供了一种称为rebasing的独特功能,作为 merge 的替代方案。它的语法是:
git rebase [new-commit]
运行时,Git执行以下步骤:
- 假设你所在的分支为 new-branch, 你要rebase 的分支是 master。 找到 master 和 new-branch 的共同祖先部分,从这个commit开始到new-branch HEAD 之间的所有commit。都要找出来。 这可以被认为是一个两步过程:首先,找到[new-commit] 和 master 的共同祖先; 称之为 祖先提交。其次,收集祖先提交和当前提交之间的所有 提交。
- 确定每个提交的更改内容,并将这些更改放在一边。
- 将 current head 设置为[new-commit]。
- 找到第二步中的每一个更改,重播更改到当前 HEAD 并创建新提交。
结果是当前提交的HEAD是[new-commit]的后代,但它包含所有更改,就像它已与[new-commit]合并一样。
例如,假设存储库看起来像:
+-------------- (D)
/ |
(A) -- (B) -- (C) |
| |
master new-branch
|
HEAD
执行 git rebase master 将会产生下面的结果:
+------ (E)
/ |
(A) -- (B) -- (C) |
| |
master new-branch
|
HEAD
这里 (E) 是一个新的 commit, 他将包含之前 (B)和 (D)之间的变更。但会把这些变更重新组织,放在基于(C)之上。
Rebase 的优势在于这里没有创建 merge commit. 但是,因为HEAD不是pre-rebase HEAD提交的后代,所以rebase可能会有问题。首先,这意味着无法将重新定位的头部推送到远程服务器,因为它不会导致快速合并。而且,它会导致信息丢失。不再知道(D)曾经在 新的分支头上。这导致“历史的变化”,这可能使已经知道提交(D)的人感到困惑。
Common Rebasing Use Practices
首先,如果您自己开发分支而不与任何人共享分支,您可以对其进行重新设置以使分支与主分支保持同步。然后,当您最终将已开发的分支合并到主分支时,它将没有合并提交,因为看起来您的开发分支是主头的后代。此外,主分支可以通过快进合并而不是常规合并提交继续前进。
其次,如果您提交分支但该分支在远程计算机上同时更改,则可以使用rebase来转移您自己的提交,从而允许您将提交推送到远程存储库。从上面的例子:
+-- (D)
/ |
(A) -- (B) -- (C) (A) -- (B) |
| |
master master
Your repository Remote repository
如果执行 fetch,您的存储库将如下所示:
+-------------- (D)
/ |
(A) -- (B) -- (C) |
| |
master origin/master
现在,假设master是你当前的头,你运行:
git rebase origin / master
您的存储库将如下所示:
+------ (D) ------+
/ | \
(A) -- (B) | (E)
| |
origin/master master
Commit(E)包含你在提交(B)和(C)之间所做的更改,但现在commit(E)是(D)的后代。这允许您作为快进合并推动您的主头 ,以更新origin / master。