最简单(对每个人都很明显)的方法是先更新您的
master
分支,然后在更新后的
master
上进行变基,此时
master
与
origin/master
完全相同。
$ git fetch origin
$ git checkout master
$ git merge --ff-only origin/master
此时,如果一切顺利,
master
和
origin/master
应该是相同的(您可以使用图形查看器(如
gitk
)或
git log --graph --oneline --decorate
来查看),并且应该清楚
git rebase master
将如何工作。
但实际上您并不需要这样做。您只需在
develop
分支上执行
git rebase origin/master
即可。(这将使您的
master
未前进 - 可能在某个时候您会想要前进它 - 所以它并没有为您节省太多时间。但现在做起来更容易。)
长而乏味的“为什么”部分:
git rebase
在其长格式中需要三个点,文档将其描述为
newbase
、
upstream
和
branch
。
git rebase ... [--onto <newbase>] [<upstream>] [<branch>]
如果您像这样指定精确的一个参数
git rebase master
,那么会使用该参数作为
upstream
,同时计算
newbase
和
branch
。其中,
branch
是当前分支(即
HEAD
,不能是分离的)。如果省略
--onto
,则
newbase
将被视为
upstream
参数。因此,如果您现在在
develop
上,并运行
git rebase X
,则
branch
是
develop
,而
newbase
和
upstream
都是
X
。
重新设置基础库方法实际上是:
- 检出
branch
- 保存对应于
branch
指向的提交的引用(ORIG_HEAD
)
- 重置它(类似于
git reset --hard
)到newbase
- 对于
upstream..ORIG_HEAD
中的每个提交(按从旧到新的顺序),git cherry-pick
该提交以将其添加到刚刚重置的分支中。
因此,就像文档中所述:
Assume the following history exists and the current branch is "topic":
A---B---C HEAD=topic
/
D---E---F---G master
当你执行
git rebase master
命令时,会得到以下结果:
A---B---C ORIG_HEAD
/
/ A'--B'--C' HEAD=topic
/ /
D---E---F---G master
(我所做的只是在手册示例中添加了ORIG_HEAD标签和HEAD=,以显示原始提交“仍然存在”,并且HEAD是对主题的引用。)
那么,如果您有您的develop和master,并且它们有它们的master,其中有一些额外的更改会发生什么? 让我们画出来:
A -- B -- C master
| \
| D origin/master
|
E -- F HEAD=develop
现在你需要执行以下命令:
git rebase origin/master
:
A -- B -- C master
| \
| D origin/master
| \
| E' -- F' HEAD=develop
|
E -- F ORIG_HEAD
在某个时刻,您最终将自己的 master
移动到指向提交 D
(并丢弃 ORIG_HEAD
),结果如下:
A -- B -- C -- D master, origin/master
\
E' - F' HEAD=develop
这其实就是一些标签移动了位置。
分支标签只是标签而已,每个标签指向一个(唯一的)提交。提交本身又会指向以前的提交,这就构建了提交树(或者说“提交有向无环图”)。
1Git 的 X..Y
语法隐藏了很多“深度魔法”。它的意思是“从标签 Y
可到达的所有提交,但不可从标签 X
到达的提交”,正是需要挑选樱桃的提交集合,因为这些提交集合在“变基”操作之前是在 branch
上的,而在 upstream
上不存在。初看起来“像是”基于时间顺序的序列,通常人们也会这么理解,但实际上它是基于提交图拓扑结构的。有时这会让人感到困惑:对于那些没有关系的提交树而言,A..B
表示“从 B
可到达的每个修订版本”。
git checkout master && git pull --rebase origin dev && git push -f
- alpergit rebase
时处于master
上,那么你复制并放弃的提交就是之前存在于你的master
上的提交。如果这些提交也存在于其他人的master
上,他们可能会认为这种放弃方式是相当粗鲁的。因此,这真的取决于许多因素。对于所有情况,没有一个正确答案。 - torekmaster
分支。这样你就不能错误地使用它。你总是要使用一个不同的名称。当你去创建一个新的分支,或者rebase,或者其他操作时,你将不得不使用名称origin/master
来引用“他们”的最新的master
提交(无论他们是谁):你运行git fetch origin
来更新,之后origin/master
就是他们的最新版本。 - torekmaster
,就解决了本地master
落后的问题。也就是说,我们使用亚历山大大帝解开戈尔底斯结的办法:我们干脆将它完全切掉,根本不必在第一时间去解开它。 :-) - torek