何时使用rebase master或origin / master

时间:2017-08-28 14:06:17

标签: git

我认为我们在分支中开发项目,完成后,我们将其重新命名为master分支,然后我们可以将其推送到存储库服务器。

如果我认为错了,请告诉我,并解释我们什么时候变为原点/主人

*更新:感谢你的回答,但你被误解了,我需要知道

的区别

git rebase master

git rebase origin/master

4 个答案:

答案 0 :(得分:4)

您想要将git rebase mastergit rebase origin/master进行比较。

您提供给git rebase的参数是the git rebase documentation调用上游的内容。这不是一个非常好的名字(在这种情况下,文档不是那么好),但答案

git rebase做的是复制一些提交。 Git需要两条信息:哪些提交应该复制?应该将它们复制到哪里?这一个参数,这个上游作为文档调用它,为两个问题提供答案。

要理解这个复制过程,您需要至少绘制提交图的某些部分,以便您可以看到哪些提交被复制以及之后会发生什么。

绘制提交图表有点棘手,但如果你练习它一段时间就可以很好地完成它。要绘制图形,您需要查看提交 with 其父链接。您可以使用git log --all --decorate --oneline --graph,它将执行自己的图形绘制,或使用图形查看器,如gitk或一些Git GUI。 (你不能使用GitHub的图表,因为它们包含错误的信息。)如果你手动绘制它们,那么拥有白板或类似物是有帮助的。

让我们在此处绘制一个快速示例图表。您自己的图表可能会有所不同。

                C4   <-- feature
               /
...--C1--C2--C3   <-- master
               \
                C5--C6   <-- origin/master

这些Cn代表提交。我们说每次提交&#34;指回&#34;到其父(先前)提交。请注意,提交的父级总是提前,但是&#34;之前&#34;并不总是意味着很多。在这里,可能从您的分支feature创建了分支master,然后对其进行了一次提交。从那时起,您还运行了git fetch,它从Git称为远程origin中获得了两次提交。这两个提交现在位于origin/master,但不在master上。

复制内容和复制位置

如果此时您运行git checkout feature然后git rebase master,Git会告诉您无所事事(Current branch feature is up to date)。但是,如果你运行git rebase origin/master,它会做一些事情。

关于为什么再次出现在文档中的关键。 Rebase通过使用the gitrevisions documentation中描述的双点表示法选择提交复制来开始:

master..feature

(名称feature来自您的当前分支,即您已签出的名称;名称master来自您对git rebase的参数。

这个双点表示法意味着:在提交图上,从feature开始并通过其父项向后工作,并将所有这些提交标记为绿色。然后,在同一个图表上,从master开始,然后通过其父项向后工作,并将所有这些提交标记为红色。

当我们使用已绘制的图表执行此操作时,我们将C4标记为绿色,然后将C3标记为绿色,然后将C2标记为绿色,依此类推。提交C5C6根本不会被标记。然后,我们标记C3红色 - 这会覆盖其绿色 - 并标记C2红色,依此类推。我们留下的只是C4绿色。

这意味着git rebase master将执行的操作 copy commit C4

现在,下一步是找出复制位置。答案是:在上游指向的任何提交之后。所以这说:将提交C4复制到现在的位置。这是没有意义的,所以git rebase说没有什么可做的。

如果您现在正在运行git rebase origin/master,Git会将C4标记为绿色,然后将C3标记为绿色,依此类推;然后它会标记C6红色,C5红色,C3红色,依此类推。这为我们提供了要复制的提交列表,这些提交再一次只是提交C4。我们标记了更多提交,但要复制的内容的最终结果是相同的。然后下一步是找出在哪里复制,这一次,它是不同的。

我们应该将所有提交 - 所有提交 - 复制到origin/master点之后,即C6。所以我们必须在那里复制提交C4

Git如何复制提交

复制提交的主要命令是git cherry-pick。因此,在内部,git rebase经常使用git cherry-pick进行复制。某些类型的rebase在内部使用不同的命令,但最终结果是相同的。无论如何,我们可以将其视为樱桃挑选。

要进行复制,Git首先检查&#34;&#34;&#34;提交,C6。它不会检查任何分支 - 而是检查原始提交,使用Git调用&#34;分离的HEAD&#34;模式。如果在rebase期间出现问题,你就会被留在这个&#34;分离的HEAD&#34;模式。这不是什么大问题,如果一切顺利正确,Git会立即退出这种模式,但值得记住。

无论如何,Git&#34;分离HEAD&#34;并指出提交C6:

                C4   <-- feature
               /
...--C1--C2--C3   <-- master
               \
                C5--C6   <-- origin/master, HEAD (detached)

然后樱桃挑选C4来复制它。有关详细信息,请阅读the git cherry-pick documentation,但实质上,这会通过比较C4C3来复制您所做的更改,然后使用提交消息。新副本出现在HEAD提交之后,即C6,所以看起来像这样:

                C4   <-- feature
               /
...--C1--C2--C3   <-- master
               \
                C5--C6   <-- origin/master
                      \
                       C4A   <-- HEAD (detached)

新提交很像C4,但有一个不同的提交:它指向现有提交C6,而不是C3

复制后

我们现在已经完成了复制我们必须复制的所有提交,所以对于它的最终技巧,git rebase使我们 的分支名称,即{{} 1}},指向它复制的最后一次提交。换句话说,它重新连接你的HEAD,但是在新的图形位置:

feature

原始,预复制,提交 C4 [abandoned] / ...--C1--C2--C3 <-- master \ C5--C6 <-- origin/master \ C4A <-- feature (HEAD) 会发生什么?

Git偷偷地挂了一会儿,但它已经不可见了#34;。它没有名称,您可以通过它找到它。它不再在你的任何分支机构上了!最终,保持它的东西--Git称之为 reflog条目 -expire,而Git完全通过Git调用垃圾收集来删除它。但是,有一段时间,你可以&#34;撤消&#34;如果需要,请C4

随着时间的推移,分支名称会改变,移动。提交不要。

让我们回到原始图表,即在我们运行git rebase之前回来:

git rebase origin/master

此时,如果您运行 C4 <-- feature / ...--C1--C2--C3 <-- master \ C5--C6 <-- origin/master 然后git checkout master - 或git merge origin/master,然后git checkout master,则为您运行git pull - Git将在&#34;快进&#34;中移动您的姓名git merge操作:

master

没有必要做任何其他事情,所以Git做了最少的工作,它可以逃脱。它使名称 C4 <-- feature / ...--C1--C2--C3 \ C5--C6 <-- master (HEAD), origin/master 指向提交master,就像C6一样。 (我已将origin/master标记为master,因为我们有一位HEAD主人来到这里。)

如果现在执行您之前要执行的相同类型的rebase,现在这两个名称git checkoutmaster,指向相同的提交。现在,在origin/mastergit checkout feature附加到HEAD之后,featuregit rebase master做同样的事情

请记住,rebase操作使用上游参数来查找要复制的内容放置副本的位置。所有它都使用了这个参数,所以如果两个不同的名字指向相同的提交,那么&#34;要复制的内容&#34;和&#34;在哪里复制&#34;两个名字的答案都是一样的。

当两个不同的名称指向不同的提交时,您会得到不同的结果。绿色与红色的技巧可能(或者可能不会尝试与其他图表一起使用)意味着您获得了相同的提交复制,但是&#34;在哪里拷贝&#34;根据定义,部分是不同的。

答案 1 :(得分:1)

当您的分支落后并且您需要来自master的更改时,可能需要Rebase。您也可以使用合并,但有些人更喜欢使用rebase。 (包括我自己)

  

我需要知道

的区别      

git rebase master

     

     

git rebase origin/master

不同的是对你当地的主人或原籍主人进行重新定价。 你的本地大师很可能落后于原点/主人,但也可能是前进的,甚至有不同的历史(不推荐)

如果您的masterorigin/master相同,则使用哪一个并不重要。

我们从origin/master重新定义(和分支),因此我们无需更新本地主人。 (无需在本地git pull分支上执行master

如果你在本地主人身上变基,你可以这样做:

git checkout master
git pull
git checkout myBranch
git rebase master

如果你对原点/主人进行重新定位,你可以做

git fetch
git rebase origin/master

所以要短得多。

语法缩短

对于更短的时间,你也可以使用“pull rebase”,一个很好地结合“origin rebase”:

git pull origin master --rebase

无需获取。

如果你更懒惰,你可以在拉动时默认设置rebase。

仅在需要时设置git config --global pull.rebase true

然后对于拉出的rebase,只需使用

git pull origin/master

PS:遗憾的是语法不一致(origin/master vs origin master

答案 2 :(得分:1)

编辑:我忘记添加为什么快进合并是有些人首选的,这是因为没有合并冲突,因为分支指针只是向前移动,而不是必须合并2个单独的副本代码

Rebase merge会这样做:

首先,你在你的分支上提交了

First image

合并只会将master移动到C1,一切都会好的

但如果有人添加提交,那么它看起来像这样: Second image

合并不再是快速合并。

将您的分支重新关闭C2会将其更改为: Third image

这意味着合并可以作为快进进行,确保没有冲突。

答案 3 :(得分:1)

我通常更喜欢rebase用于中小型更改,merge用于大型长期分支。

rebase的优势在于为您提供非常干净的提交历史记录。

merge的优点是可以为您提供显式的合并提交,这意味着解决合并冲突的更改会自行划分。使用merge,如果您稍后发现分支的错误或者您意识到以错误的方式修复了冲突,则更容易恢复合并提交并应用必要的修复。