Git推送完全refspec无法正常工作

时间:2018-01-24 12:08:00

标签: git github push refspec

我有两个分支(本地和远程github)。我将其称为BranchA和BranchB。 我有BranchA提交c1,c2和c3。 我的BranchB只有commit c1。 两个分支都用github完全更新,我可以检查BranchA是否有c1,c2和c3,而BranchB只有c1。

我想从本地BranchA推送到远程BranchB。要做到这一点,我尝试:

git push origin refs/heads/BranchA:refs/remotes/origin/BranchB

当我这样做时,我得到一个奇怪的输出:

Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/<username>/<repo>.git
   <hash>  BranchA -> origin/BranchB

当我去github时,我看到BranchB没有更新,仍然只有c1。 然后,如果我再次运行该命令,它将返回所有内容都是最新的。

这让我感到困惑,但是当我尝试执行命令而没有完整参考时,情况变得更糟,如下所示:

git push origin BranchA:BranchB

......它奏效了。

我很困惑。我搜索了它,我认为使用完整的参考(例如 / refs / heads / )绝不会造成任何伤害。

为什么会这样?当我指定完整的分支名称时,它不能工作吗?

1 个答案:

答案 0 :(得分:2)

作为prahlad venkata commented,遥控器上的引用为refs/heads/BranchB,而不是refs/heads/remotes/BranchB

请注意,在使用git push或其对应的git fetch时,会有两个 Gits和两个存储库。我们称之为你的(matovski's)和GitHub's。

您的Git有一个名为BranchA的分支,其全名为refs/heads/BranchA。此名称存储(单个)哈希ID。

他们的Git有一个名为BranchB的分支,其全名为refs/heads/BranchB。他们的Git可能还有一个名为BranchA的分支。这些名称还存储哈希ID(每个名称)。

当你的Git与GitHub的Git交谈时,你的Git会看到他们的refs/heads/BranchA和他们的refs/heads/BranchB。您的Git想要记住这两个名称和ID对,但如果您的Git将它们存储为refs/heads/BranchArefs/heads/BranchB,那么您的Git将覆盖您自己的分支。因此,您的Git会重命名其分支名称,将refs/heads/替换为refs/remotes/origin/

换句话说,refs/remotes/origin/BranchB你的 Git对他们的 Git refs/heads/BranchB的记忆。但是当你的Git与他们的Git交谈时,你的Git必须告诉他们的Git:请设置你的refs/heads/BranchB 。如果你的Git要求他们的Git设置他们的refs/heads/origin/BranchB,这将设置他们的Git记忆的第三个Git的refs/heads/BranchB(正如你刚才看到的那样,有时候是允许的! - 只是没有任何有用的效果这种情况,因为GitHub的Git repos不会自己使用这些。)

当您使用简写语法git push origin BranchA:BranchB时,您的Git会向Git发送设置BranchB的请求。根据这个要求,他们的Git计算出你可能想要设置他们的refs/heads/BranchB,并且做你认为的意思,而不是你所要求的。这个特殊的技巧只有在他们已经拥有refs/heads/BranchB时才有效,因为如果他们还有一个,他们的Git就不会尝试同样的猜测。