我有本地master
和develop
分支机构。我在develop
上完成所有工作,然后将它们合并到master
版本中。有一个远程分支upstream/master
,它有我想要的更改,但我想在develop
(它共享一个共同的祖先)的基础上更改我的更改,并将它们放回{{1 }}。我已经完成了develop
。
Git book chapter on rebasing说要做:
git fetch upstream
我(假设)在我的情况下意味着:
$ git checkout experiment
$ git rebase master
然后我会在$ git checkout upstream/master
$ git rebase develop
和处于分离头状态。但是,如果我合并upsteam/master
,我会从upstream/master
执行此操作,并且更改将在develop
上,例如。
develop
所以这种改变方式对我来说似乎很落后。我想在$ git checkout develop
$ git merge upstream/master
分支上的develop
中更改我的更改,其中develop
的更改类似于合并的工作方式。我是否应该在upstream/master
上执行rebase,修复任何冲突,然后添加它,将其存储并弹出到upstream/master
?
希望这是有道理的,有人可以帮助我,我将非常感激。
答案 0 :(得分:12)
最简单(对每个人来说最明显)的方法是首先更新您的master
分支,然后重新定位到更新的master
,现在与origin/master
完全相同:
$ git fetch origin # Get updates from remote.
$ git checkout master # Now bring master into sync:
$ git merge --ff-only origin/master # if this fails you have stuff
# in your master that they don't
# have in theirs, and you need
# to decide what to do about it
此时,如果一切顺利,master
和origin/master
相同(您可以使用gitk
或git log --graph --oneline --decorate
等图形查看器查看,并且应该清楚git rebase master
将如何运作。
但你实际上不必这样做。在git rebase origin/master
上时,您可以develop
。 (这会让你的master
无法前进 - 大概在某些时候你会想要它前进 - 所以它并没有真正为你节省太多。但它是现在更容易做到。)
漫长的无聊"为什么"部分:git rebase
以长篇形式提供三个点,文档描述为 newbase
, upstream
和< EM> branch
:
git rebase ... [--onto <newbase>] [<upstream>] [<branch>]
如果您只指定一个参数,例如在git rebase master
中指定 upstream
以及 newbase
和 branch
。 branch
是当前分支(即HEAD
,不得分离)。如果省略--onto
, newbase
将被视为 upstream
参数。因此,如果您现在develop
,并且您运行git rebase X
,则 branch
为develop
,并且 {{ 1}} 和 newbase
是upstream
。
实际上,rebase方法(有各种内部优化,对reflog的影响有点不同):
X
branch
)保存到 ORIG_HEAD
指向的提交branch
)至 git reset --hard
newbase
1 中的每个提交(从最旧到最新的顺序),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
,以显示原始提交是&#34;仍然在那里&#34; ,HEAD=
是对HEAD
)的引用。
那么,如果您拥有topic
和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
这与移动的一些标签是一样的。
分支标签的全部内容,它们只是标签。每个标签指向一个(单个)提交。提交本身指向以前的提交,这是构建提交树(或者#34;提交DAG&#34;,真的)。
1 A -- B -- C -- D master, origin/master
\
E' - F' HEAD=develop
语法隐藏了很多&#34;深刻的魔法&#34;。这意味着&#34;所有从标签 Git's X..Y
可以从标签 Y
无法访问的提交。这正是需要挑选的提交集合,因为那些是 X
上的提交,而不是 branch
在&#34; rebase&#34;之前运。它看起来像&#34;乍一看是基于时间的序列,通常在人们头脑中起作用,但它基于提交图拓扑。有时这会引起人们的兴奋:upstream
,其中A..B
根本与A
无关(因为回购中有多个提交树),意味着&#34;每个修订版都可以从B
。
答案 1 :(得分:9)
rebase实际上是:
git checkout develop
git rebase upstream/master
(git rebase
应为:“将我当前的分支,此处develop
,置于目标分支之上,此处为upstream/master
”)
最终结果不是一个独立的头,而是新重写的develop
分支。
答案 2 :(得分:1)
您正在寻找的命令是:
git checkout develop
git rebase upstream/master
然而,Git比这更聪明,你可以将upstream / master配置为develop的上游跟踪分支:
git branch --set-upstream-to upstream/master develop
现在当你执行git rebase
时,它会自动使用'upstream / master'。但更好的是,这些命令:
git fetch origin
git rebase upstream/master
只需简单操作即可简化:
git pull --rebase