当我从Git中的跟踪分支推送到另一个远程分支时会发生什么?

时间:2014-03-14 22:40:08

标签: git

假设我有一个名为devo-1的跟踪分支,它跟踪远程的devo-1分支。假设在同一个遥控器中有另一个分支,称为devo-2。我现在执行以下操作:

  1. git checkout devo-1
  2. git fetch origin
  3. git pull origin devo-2
  4. git push origin devo-2
  5. 我的问题:

    • 在第2步,这应该更新所有origin / devo- *远程跟踪分支,更正?
    • 在第3步,这应该从来源devo-2(而不是devo-1)获得更新,对吗?
    • 在第4步,这应该将devo-1中的更改​​推送到来源devo-2,对吗?

    谢谢!

4 个答案:

答案 0 :(得分:3)

简短版:1:是,2:也许,3:不。


Git的术语曲折且令人困惑。你没有推到“远程分支”,你推到遥控器上的分支。看起来像一个愚蠢的区别,但因为术语令人困惑,重要的是要确保。 (只是甚至更多令人困惑,这些“分支”都引用附加到存储库的标签,而不是从这些存储库中包含的提交图构建的数据结构;但这些结构的一部分是< em>也在不同时间称为“分支”。)

更糟糕的是,git fetchgit pullgit push也不是很对称。

我们从您自己的devo-1分支开始(因为git checkout devo-1),但在git pull调用git merge之前无关紧要。

然后,假设标准设置(不是镜子或其他):

git fetch origin

在互联网电话(或其他)上调用远程git,问他“嘿,你有什么分支标签”,复制提交和所需的,并粘贴他(本地)分支标签的副本在origin/名称空间下的(本地)“远程分支”标签中。也就是说,origin/devo-1origin/devo-2都已更新 - 我假设两者都存在于origin - 以及其他任何可能的内容,而您的git则有此机会。

(您的第一个问题的答案是“是”。)

下一个命令:

git pull origin devo-2

只运行一个shell脚本,该脚本又运行两个命令:

  • git fetch(带一些参数),然后
  • git mergegit rebase,具体取决于您的配置。我将假设前者。

第一个子部分再次在互联网电话上调用远程git。这次它只会在提供的分支中带来新内容,即devo-2的副本。很可能还没有什么新东西(你刚刚完成了一次完整的提取),但是如果有新的东西,它会将新的SHA-1放入特殊的FETCH_HEAD文件中,但不会 1 origin/devo-2更新您的“远程分支”副本。

第二个子部分运行git merge以合并其最新版本。这是做git merge origin/devo-2的道德等同 2 。现在,您的devo-1已合并到devo-2中的最新提交,如FETCH_HEAD中所记录。

(或者,如果您设置了rebase,它会改为。)

(你的第二个问题的答案是“也许,具体取决于你的意思”。)

虽然你得到任何新的提交和其他SHA-1好东西,但它们只写入FETCH_HEAD,除非你有一个新的(1.8.4或更高版本)git。 (见脚注1)。

最后,你的git push:你给了它两个额外的参数,一个遥控器和一个refspec。遥控器是origin,因此它将通过互联网电话或以前的任何方式调用。但是,refspec:devo-2 意味着devo-2:devo-2(因为我假设你有一个本地devo-2分支)意味着refs/heads/devo-2:refs/heads/devo-2

这会使您的本地devo-2 devo-1)尝试将新内容发送到遥控器(他有机会拒绝它们)并指向他的{{ 1}}分支标签到新的提示提交。

(您的第三个问题的答案是“否”。)

为了将devo-2中的内容推送到devo-1,您需要:

devo-2

这里的refspec意味着:“通过查找我的git push origin devo-1:devo-2 向你的git发送你发现的SHA-1,并让他们把它写到devo-1。”


1 除非你有git 1.8.4或更新版本,否则它 更新devo-2。幸运的是,这并不重要:即使有新内容,下一步也会使用origin/devo-2来引用它,而不是使用FETCH_HEAD

2 如果你有git 1.8.4或更新版本,那就是真正的等价物。否则,这取决于第二个origin/devo-2是否实际带来了新内容。

答案 1 :(得分:0)

  

在第2步,这应该更新所有origin / devo- *远程跟踪分支,更正?

正确。 (好吧,任何远程跟踪分支。不仅仅是那些以“devo”开头的分支)

  

在第3步,这应该只从原始devo-2(而不是devo-1)获得更新,对吗?

正确。 (好吧,远程devo-2分支将与你的HEAD合并/重新分配)。

  

在第4步,这应该将devo-1中的更改​​推送到原点devo-2,是否正确?

<强>不正确即可。 git push origin devo-1:devo-2是您正在寻找的。

git push origin devo-2基本上是说“将我的本地devo-2分支推送到远程devo-2分支”或git push origin devo-2:devo-2

答案 2 :(得分:0)

步骤2 - 是的git-fetch将更新所有远程分支(除非你提供refspec参数来限制它提取的内容)。

步骤3 - 不,git-pull与git-fetch + git-merge基本相同,并且合并操作将在当前分支上运行。所以在这个例子中,当前分支是devo-1,然后命令将devo-2合并到devo-1。

步骤4,这不会将您的本地devo-2更改推送到origin / devo-2。

答案 3 :(得分:0)

  • git fetch不仅会更新远程跟踪分支,还会更新该远程分支的所有远程分支。跟踪通常意味着本地分支属于某个远程分支,并将其视为默认分支,并提供其他状态信息。

  • git pull origin devo-2将再次获取devo-2,然后将远程分支(origin/devo-2)合并到当前分支中。因此,在您之前检查过本地devo-1分支之前,您基本上会将远程devo-2合并到该分支中。

  • git push origin devo-2将等同于git push origin devo-2:devo-2,这意味着这会将您的本地devo-2推送到远程devo-2。所以不,您当地和当前签出的分支devo-1不会用于任何目的。