我想知道如果我在git中创建一个与远程分支同名的分支会发生什么。一旦推动我的分支,第一个分支是否会停止存在于远程存储库中?例如,假设我克隆了以下裸存储库
master A----B---C
\
mybranch D---E
然后我继续从 master 创建一个名为 mybranch 的分支,并生成一些提交。我知道如果我签出mybranch会创建一个跟踪分支但是如果我创建了一个分支( git branch mybranch ),一旦我决定推送 mybranch 会发生什么?我做了一些例子,但我无法弄清楚发生了什么。感谢。
答案 0 :(得分:1)
因此,在您的特定示例中,您将基于提交C创建提交F并使本地分支 mybranch 指向该提交,从而产生以下情况:
mybranch F
/
master A----B---C
\
origin/mybranch D---E
如果您尝试将该分支/提交推送到上游的 mybranch ,Git会拒绝推送,因为它将是 mybranch
您的本地分支恰好与上游分支同名的事实不会在这里发挥作用。上游Git不关心或了解您的本地分支名称(如果有名称的话;被推送的内容可能是无名的分离头)。
答案 1 :(得分:1)
“TL; DR”摘要:它确实有效,但它可能会混淆你,所以你可能应该在某个时候重新安排你的分支名称。以下是Magnus Bäck's answer的扩展版本。
这里涉及两个实体(或者如果你有多个遥控器,或者更多,我们坚持使用两个:-),你的和origin
):
含糊不清的 refname
(请参阅gitrevisions)仅影响“您自己的回购”,因为遥控器有自己的名称,它自己的.git
目录。此外,当您键入 refname
并让您的git命令解决它时,它会根据gitrevisions中列出的规则解决。 1 < / p>
这仍然不是一个好的情况,因为它可能会混淆你。此外,“只影响你”可能是夸张或“白谎”,因为当你使用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 push
或git push origin
查找push.default
设置。 2
如果设置为current
,matching
或simple
,git确实希望您的名称与遥控器的名称相匹配。如果它设置为nothing
,git要求您每次都提供“其他边名”。如果它设置为upstream
,git使用“上游”名称 3 ,不需要匹配本地名称。
因此,push.default
的{{1}}设置几乎适用于这种情况:不一定是不明确的名称,但任何情况下你的名字都是{{} 1}},与远程名称upstream
不同。
(还有mybranch
会发生什么的问题。请参阅脚注3下面的额外信息。)
1 由于历史原因,或者只是令人讨厌,newbranch
命令解析具有不同规则的分支名称。我实际上并不知道为什么,但至少在可预见的将来,我们会坚持下去。
2 使用git config
设置/更改/检查设置。 git fetch
命令还检查git checkout
,如果已设置,甚至push
,如果 的设置。如果您配置了许多配置设置,这会非常混乱!我们假设你没有把自己配置成奇怪的角落。
3 通过组合remote.origin.push
和branch.mybranch.pushremote
找到“上游”。例如,您可以将branch.name.remote
设置为branch.name.merge
,将branch.mybranch.remote
设置为origin
。然后branch.mybranch.merge
的“上游”名称为newbranch
。因此,mybranch
的{{1}}设置允许origin/newbranch
自动计算upstream
推送到push.default
上的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
时,再次因为gitrevisions中的规则而转换进入完整的,永不模糊的名称origin
,然后命名所需的提交。