Git 推送 master 而不是我的分支。为什么?

K E*_*gle 1 git git-push git-branch

我正在想办法在 git 中使用分支。当时我在 master 中有不相关的提交,我还没有准备好推送,但我不得不做一个错误修复。我不想创建一个新的 repo 只是为了做一个小错误修复,所以我创建了一个基于 origin/master 的分支

git checkout -b example origin/master

根据我的理解,这会创建一个基于 origin/master 分支的分支,并切换到示例分支。

然后我去做了我的修复,提交并测试了它。

$ git status
On branch example
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean
Run Code Online (Sandbox Code Playgroud)

然后我去把它推给主人。

$ git push origin master

但是我没有在示例分支中推送提交,而是找到了这个

    $ git status
    On branch example
    Your branch and 'origin/master' have diverged,
    and have 1 and 3 different commits each, respectively.
        (use "git pull" to merge the remote branch into yours)

    nothing to commit, working directory clean
Run Code Online (Sandbox Code Playgroud)

我不明白为什么

tor*_*rek 6

的语法git push有点晦涩,但很容易解释您正在使用的特定情况:

$ git push remote refspec

remote你被点名是典型的一个,origin; 这可以让你的 git 找到他们 git 的 URL。到目前为止,这部分都很好。

问题出现在refspec您提供的master.

您可能想知道:无论如何,“refspec”到底是什么?答案是它是两部分——有时是三部分——的东西,两个分支1名称用冒号分隔:

ours:theirs
Run Code Online (Sandbox Code Playgroud)

例如。2

“但是等等,”您可能会说,“没有:in master,只有一个分支名称!” 这是真的,但git push需要两个,所以它组成了另一个:当你给一个名字时,它会复制你给它的名字,所以这master只是意味着master:master

这告诉git push你推动你的当前master,另一方面,要求他们的 git 也更新他们的master

如果你想推送你当前的提交 ( HEAD) 并让他们的 git 把它作为他们的master,你必须3写出来:

git push origin HEAD:master
Run Code Online (Sandbox Code Playgroud)

意识到当你git push做某事时,他们这边并不关心(甚至不知道)这边的任何分支的任何事情可能会有所帮助:你的 git 将你的分支转换为原始 SHA-1 值,然后发送这些 - 原始 SHA-1 ——远方。HEAD例如,如果你映射到 commit-ID 1234567,让git push origin HEAD:master你的 git 调用他们的并交付 commit 1234567,然后给他们发送一条消息:“现在我已经给了你 commit 1234567,请master指出那个 commit-ID。 ” 然后他们的结尾说“OK”(推送成功)或“不,我拒绝”(推送失败,例如,不是快进,或者被像 gitolite 之类的脚本拒绝的许可,或其他什么)。因此,您使用的任何分支名称都指的是您的一侧 - 左侧localname:remotename— 完全由您处理,只有右侧的名称会传递给远程 git。这就是为什么您可以使用HEAD:master.


1实际上,任何有效的参考都可以到这里。标签是以 开头的引用refs/tags/,而 git 现在有“注释”之类的;所有这些都使用引用。但是分支是大多数人大部分时间使用的分支。

2可选的第三部分是前导加号,用于强制更新, a la git push -f。另外,请注意,也git fetch使用 refspecs,但在这种情况下,名称是颠倒的:theirs:ours,并且您通常会将它们提取master到您的remotes/origin/master,例如(强制更新,因此使用前导+)。

3与 git 一样,您可以设置一个配置旋钮来更改默认值。在这种情况下,有多种设置,但要考虑的主要设置是push.default. 请参阅git config文档的详细信息。