【问题标题】:Reusing git branch names重用 git 分支名称
【发布时间】:2014-02-07 05:47:49
【问题描述】:

我想知道如果我在 git 中创建一个与远程分支同名的分支会发生什么。一旦我推送我的分支,第一个分支会停止存在于远程存储库中吗?例如,假设我克隆了以下裸存储库

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

然后我继续从 master 创建一个名为 mybranch 的分支并生成一些提交。我知道如果我签出 mybranch 会创建一个跟踪分支,但是如果我创建一个分支 (git branch mybranch),一旦我决定推送 mybranch 会发生什么?我做了几个例子,但我无法弄清楚发生了什么。谢谢。

【问题讨论】:

  • 你试过将分支推送到远程吗?

标签: git branch reusability


【解决方案1】:

因此,在您的特定示例中,您将基于提交 C 创建提交 F 并让本地分支 mybranch 指向该提交,从而创建以下情况:

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

如果您尝试将该分支/提交推送到上游的 mybranch,Git 将拒绝推送,因为这将是 mybranch的非快进更新>.

您的本地分支恰好与上游分支同名这一事实在这里没有发挥作用。上游 Git 并不关心或知道您的本地分支名称(如果甚至有名称;被推送的可能是一个无名的分离头)。

【讨论】:

  • 我再次完成了这个例子,我当然收到了来自 git 的警告。伟大的!不知道我第一次尝试时发生了什么。
【解决方案2】:

"TL;DR" 总结:它确实有效,但它会让感到困惑,所以你可能应该在某个时候重新排列你的分支名称。以下是Magnus Bäck's answer 的扩展版本。


这里涉及两个实体(如果您有多个遥控器,则更多,但让我们坚持使用两个 :-),您的和 origin):

  • 您自己的存储库,并且
  • “那个”遥控器。

有一个模棱两可的refname(见gitrevisions影响“你自己的仓库”,因为遥控器有自己的名字,在它自己的@987654329 @ 目录。此外,当你输入 refname 并让你的 git 命令解析它时,它会根据gitrevisions 中列出的规则进行解析。1

这仍然不是一个很好的情况,因为它可能会混淆。另外,“只影响你”可能是夸大其词或者是“善意的谎言”,因为当你使用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 设置。2 如果设置为currentmatchingsimple,git 真的希望你的名字与遥控器的名字相匹配。如果设置为nothing,git 要求您每次都提供“另一端名称”。如果设置为upstream,git 使用“上游”名称,3 不需要匹配本地名称。

因此,upstreampush.default 设置几乎适用于这种情况:不一定是一个模棱两可的名称,但在任何情况下,您的名称 mybranch 与遥控器上的名字,newbranch

(还有一个问题是 git fetch 会发生什么。请参阅脚注 3 下面的额外信息。)


1出于历史原因,或者可能只是为了令人讨厌,git checkout 命令使用不同的规则解析分支名称。我实际上不知道为什么,但我们有点坚持,至少在可预见的未来是这样。

2使用git config 设置/更改/检查设置。 push 命令还会检查 remote.origin.push(如果已设置),甚至检查 branch.mybranch.pushremote(如果 that 已设置)。如果您配置了很多配置设置,这会变得非常混乱!假设您没有在这里将自己配置成奇怪的角落。

3“上游”是通过组合branch.<em>name</em>.remotebranch.<em>name</em>.merge 找到的。例如,您可以将branch.mybranch.remote 设置为origin,将branch.mybranch.merge 设置为newbranch。那么mybranch 的“上游”名称是origin/newbranch。因此,push.defaultupstream 设置让git push 自动计算出mybranch 在远程origin 上推送到newbranch。同样的“上游”配置自动与git fetch 一起工作。

因为涉及到两个实体,当git fetch 带来origin 的分支名称时,它需要将它们与您自己的分支名称分开。这样做的方法是从远程仓库中获取所有分支名称,然后在它们前面插入文本:远程origin 上的分支master 变为本地引用名称refs/remotes/origin/master你的分支进入refs/heads/<em>name</em>他们的分支进入refs/remotes/origin/<em>name</em>;并且保证这两个命名空间不会冲突,因为heads/remotes/ 是不同的。

有一个配置条目——除非您知道自己在做什么,否则不要更改这个特定的条目;它真的就在那里,所以镜子可以以不同的方式工作——也就是说:

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

这样做。这就是origin 上的mybranch 首先变成origin/mybranch 的方式,当您输入名称origin/mybranch 时,再次由于gitrevisions 中的规则,这将转换为完整的、永不含糊的名称@987654388 @,然后命名所需的提交。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-04
    • 2015-01-12
    • 2019-11-20
    • 2010-09-06
    • 2019-11-09
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多