如果我尝试对已经推送到开发分支的提交进行变基会发生什么

What happens if I try to rebase a commit that is already pushed to a development branch

用例如下

然后我从开发分支拉出来 我做了一些代码更改然后推送

几天后我回来做了 git 状态,这表明我领先 master 分支 1 commit,显然我已经几天没有从 master 上拉下来了

现在,在我进行更改之前,我决定做一个 git pull with rebase ,git pull --rebase origin master

问题是:我在本地 repo 分支中的提交会在 master 之上,还是因为我已经推送了它,所以我会简单地到达全局 master/remote 分支的顶端?

我对变基的概念很陌生,所以请帮忙解释一下。

让我们考虑以下问题。

          D---E---F origin/master
         /
A---B---C---X master
        ^
        origin/master in your repository

几天前,您的本地 master 和 origin/master 都同步并且每个都有提交 ABC。在某些时候,您在本地 master 中提交了 X。同时其他人将提交 DEF 推送到 origin/master.

此时,如果您 运行 git pull --rebase origin master,将按原样从 origin/master 中提取所有提交,并且提交 X 将在 [= 之上重播21=] 并且将生成一个新的提交 ID X'.

新的提交图将如下所示:

                     origin/master
                    /
A---B---C---D---E---F---X' master
                    ^
                    origin/master in your repository

所以是的,旧提交 X 将作为提交 X'.

在本地 master 的顶部重新定位

编辑:

the question in this use case what if I had pushed X and then D,E,F were made, how will my local branch look asfter i execute the pull with rebase now?

在这种情况下,在推送您的提交 X 后,您的本地存储库和 origin/master 将同步。


             origin/master
            /
A---B---C---X master
            ^
            origin/master in your repository

几天后,提交 DEF 被其他人推送到 origin/master。提交图将如下所示:

             D---E---F origin/master
            /
A---B---C---X master
            ^
            origin/master in your repository

现在如果你 运行 git pull --rebase origin master 它会给出与 git pull origin master 命令相同的结果,因为没有什么可以变基的。您在 origin/master 之前没有任何提交。在此命令结束时,您的图表将如下所示:

                          origin/master
                         /
A---B---C---X---D---E---F master
                        ^
                        origin/master in your repository

由于您的提交 X 已经在 origin/master 中,因此不会在 DEF 之上重播。

The question is: will the commit that I had in my local repo branch go on top of the master or since I had already pushed it I will simply get to the tip of the global master/remote branch?

如果您所说的“全球”是指“远程”,那么是的,您的本地分支机构将在 origin/master 的基础上重新定位。请参阅下面的详细说明。


根据您的问题,您的存储库开始时看起来像这样:

o---o--------------o
    ^              ^   
    master         development
    origin/master  origin/development
    

您的本地 master 分支与远程 origin/master 分支同步;此外,您有一个包含 1 次提交的本地 development 分支,您将其推送到远程存储库,从而创建 origin/development.

现在,假设您当前的分支是 development,如果您 运行

git pull --rebase origin master

Git 将从 origin 远程获取任何新对象并更新您的远程跟踪分支 origin/master:

                  origin/master
                  ⌄
          o---o---o
         /
    o---o--------------o
        ^              ^   
        master         development
                       origin/development

然后,它将 rebase 你当前的分支(在本例中 development)在更新的 origin/master 分支之上:

                  origin/master  development
                  ⌄              ⌄
          o---o---o--------------o'
         /         
    o---o--------------o
        ^              ^   
        master         origin/development

请注意,您的本地 master 分支仍指向与之前相同的提交——那是因为 git pull 的第二部分(合并或变基)始终在 当前分支,在你的情况下development

现在,如果您要在拉取操作完成后推送本地 development 分支,您将更新 origin/development 远程跟踪分支以指向 rebase 提交:

                                 origin/development
                  origin/master  development
                  ⌄              ⌄
          o---o---o--------------o'
         /         
    o---o
        ^                 
        master

同样,您的本地 master 在您执行以下操作之前不会发生变化:

git checkout master && git merge origin/master

git pull 命令是一个复杂的野兽,因为根据调用它时所在的分支以及传递给它的参数,它会做截然不同的事情。

这是文档中关于 the form with three arguments 的内容:

Merge into the current branch the remote branch next:

$ git pull origin next

This leaves a copy of next temporarily in FETCH_HEAD, and updates the remote-tracking branch origin/next.

我还建议阅读 this answer 以更详细地解释 git pull 在不同情况下的行为方式。