我有两个分支(本地和远程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 / )绝不会造成任何伤害。
为什么会这样?当我指定完整的分支名称时,它不能工作吗?
答案 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/BranchA
和refs/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就不会尝试同样的猜测。