当我在一个功能分支内使用'git pull --rebase origin development'命令会发生什么?

9
假设我有一个名为FeatureA的功能分支,它与基于它的(远程)development不同步。通常情况下,我会通过调用git rebase development(自然地将我的本地开发与origin/development同步后)来变基我的分支。
今天,我做了不同的事情,从我的功能分支中调用git pull --rebase origin development。那么,这有什么区别呢?
2个回答

17

git pull --rebase origin development 是以下命令的快捷方式:

git fetch origin development
git rebase origin/development

即,获取 origin/development 分支,然后在当前分支之上进行变基。

更新

正如@torek所指出的:

是的,除了在 Git 1.8.3 或更早版本中,fetch 的两个参数版本不会更新 origin/development 分支。(变基结果相同,但 origin/development 不会移动。)


1
是的,除了在Git 1.8.3或更早版本中,fetch的两个参数版本不会更新origin/development。(变基结果相同,但origin/development不会移动。) - torek
实际上,正如我在下面的长答案中所指出的,它仍然会重新定位到正确的点,只是通过存储在“FETCH_HEAD”引用中的SHA-1 ID来完成。这很难解释,但无论如何它都会“做正确的事情”! - torek
@torek 哦,我明白了,那我就直接引用你的话,这样最准确,没有必要转述。 - janos

12

简述:如果rebase顺利完成,它就能正常工作。如果没有,它仍然能够正常工作,只是在图形化查看器中可能会有些混淆。


一如既往,git pull基本上是执行git fetch,然后……在这种情况下,使用的是git rebase而不是git merge。所以:

  • origin获取
  • 仅从development分支获取,并将其放入FETCH_HEAD
  • 然后,使用该ID的git rebase而非git merge <commit-ID-from-FETCH_HEAD>

假设您的本地树中的提交图表如下(我们将假设您在某个时候运行了git fetch以更新origin/development与他们的提交EF):

        C - D   <-- FeatureA
      /
A - B           <-- development
      \
        E - F   <-- origin/development

假设在origin上,他们的分支development现在有一个更多的提交。执行从origin获取的步骤将会捡起它并且使得FETCH_HEAD指向它,所以我们把它画成节点G

而且,假设在origin上,他们的分支development现在有一个更多的提交。执行从origin获取的步骤将会捡起它并且使得FETCH_HEAD指向它,所以我们把它画成节点G

        C - D       <-- FeatureA
      /
A - B               <-- development
      \
        E - F       <-- origin/development
              \
                G   <-- FETCH_HEAD
如果您的git足够新,1.8.4或更高版本,则此时也会更新origin/development,指向节点G。如果不是这样,则您本地存储的他们的developmentorigin/development中落后。对于rebase来说这并不重要,它只会改变您在git log --graph视图或图形提交树查看器中查看结果的方式。

现在,rebase将按照常规方法复制您FeatureA的提交,并使FeatureA指向这些副本,放弃原始提交。我们将重新命名这些提交为C'D':

        C - D       [abandoned]
      /
A - B               <-- development
      \
        E - F       <-- origin/development
              \
                G   <-- FETCH_HEAD
                  \
                    C' - D'   <-- FeatureA

如果你此时运行一个普通的git fetch,或者你拥有足够新的git版本使得origin/development已经移动;并且如果我们删除“abandoned”部分并简化绘图,它会变成:

A - B               <-- development
      \
        E - F - G   <-- origin/development
                  \
                    C' - D'   <-- FeatureA

如果你将本地分支标签development快进合并到匹配的origin/development,那么绘图会更简单(从B向下拉动曲线到E,并将developmentorigin/development放置在指向G的箭头右侧)。


谢谢!这的确解释得非常好! - M Jacobs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接