2014-01-17 56 views
2

我想知道如果我创建的Git分支具有相同的名称作为一个远程分支会发生什么。一旦我推动我的分支,第一个分支会停止在远程存储库中存在吗?例如,可以说我克隆纯仓库以下重用的Git分支名称

master A----B---C 
       \ 
mybranch   D---E 

然后我继续创建一个从称为mybranch分支,产生了几提交。我知道,如果我签mybranch跟踪分支将被创建,但如果我创建一个分支(的Git分支mybranch),一旦我决定要推mybranch会发生什么?我做了一些例子,但我无法弄清楚发生了什么。谢谢。

+0

你有没有试过将分支推送到远程? – Miller

回答

1

所以在您的特定例子中,你会基于凯明C上创建一个提交F和具有本地分支mybranch指向该承诺,创造了以下情况:

mybranch     F 
         /
master   A----B---C 
         \ 
origin/mybranch   D---E 

如果您想尝试推该分支/提交到在上游mybranch,GIT中会拒绝推因为它是mybranch的非快进更新。

您当地的分行恰好具有相同的名称作为上游分支不来这里发挥作用的事实。上游的Git不关心或不了解你的本地分支名称(如果有的话,甚至有一个名字;推动什么可能是一个无名的分离头)。

+0

我再次完成了这个例子,我肯定从git那里得到了一个警告。大!不知道第一次尝试时发生了什么。 – rjss

1

“TL; DR”总结:它确实有效,但它可能会混淆,所以你可能应该重新安排你的分支名称。下面是Magnus Bäck's answer的扩展版本。


这里涉及两个实体(或更多,如果你有一个以上的远程,但我们坚持两个:-),你和origin):

  • 自己的回购和
  • “the”remote。

有暧昧refname(见gitrevisions影响“自己回购”,因为远程都有自己的名字,在自己的.git目录。此外,当你在一个refname型,让你的Git命令解决这个问题,它根据gitrevisions列出这些规则解决。

这仍然不是一个伟大的情况,因为它可以混淆挫折感的。此外,“只会影响你”也许是夸张或“善意的谎言”,因为当你使用git push,有很多的选择:

  • 你可以git push origin mybranch:newbranch。这告诉你的git查找名称mybranch(用通常的解决方法,在Magnus Bäck's answer中获取提交F),然后联系origin并要求它更新或甚至在其一侧创建名为newbranch的分支。

  • 您可以git push origin mybranch。这会告诉你的git像往常一样查找名称mybranch,但是请联系origin并要求它更新或创建一个名为mybranch的分支,该分支(如前所述)不会快进,并且会被拒绝。

  • 您可以git pushgit push origin,它会查找您的push.default设置。 如果设置为currentmatchingsimple,git确实希望您的名字与远程名称相匹配。如果它设置为nothing,git要求您每次提供“其他方名称”。如果设置为upstream,那么git使用“上游”名称,它不需要匹配本地名称。

因此,upstreampush.default设置几乎意味着这种情况:不一定是暧昧的名字,但如果你的名字,mybranch,从名称不同的遥控器上的任何情况下,newbranch

(还有什么用git fetch发生的问题。见下文脚注3.额外信息)


由于历史的原因,或者只是被讨厌的git checkout命令解析分支名称用不同的规则。我实际上并不知道为什么,但至少在可预见的将来,我们会坚持下去。

设置设置/更改/检查git configpush命令还检查remote.origin.push,如果设置的话,甚至branch.mybranch.pushremote,如果的设置。如果你配置了很多配置设置,这会非常混乱!假设您不要将自己设置为怪异的角落。

“上游”通过组合branch.name.remotebranch.name.merge找到。例如,您可以将branch.mybranch.remote设置为originbranch.mybranch.mergenewbranch。那么mybranch的“上游”名称是origin/newbranch。因此,push.defaultupstream设置让git push自动解决,mybranch推到newbranch在远程origin。这个相同的“上游”配置自动与git fetch一起工作。

因为涉及到两个实体,所以当git fetch超过origin的分支名称时,需要将它们从您自己的分支名称中分离出来。这样做的方式是从远程仓库获取所有分支名称,然后在它们前面插入文本:分支master在远程origin上成为本地参考名称refs/remotes/origin/master您的分行进入refs/heads/name; 他们的分支进入refs/remotes/origin/name;并且这两个名称空间保证不会相互碰撞,因为heads/remotes/是不同的。

有一个配置条目 - 不要改变这个特定的一个,除非你知道你在做什么;它真的只是在那里,使镜子可以工作不同 - 说:

remote.origin.fetch = +refs/heads/*:refs/remotes/origin/* 

这样做。这就是上的mybranch首先变为origin/mybranch,并且当您输入名称origin/mybranch(同样是因为gitrevisions中的规则),该规则将翻译成完整的,从不含糊的名称refs/remotes/origin/mybranch,然后名称为期望的提交。