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

Git pushed master instead of my branch. Why?

我正在研究如何使用 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

然后我就去push给master

$ 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

我不明白为什么

您明确要求 git 推送到 origin/master。为了推送到名为 example 的新远程分支,您应该编写

git push -u origin example

-u 使您的本地示例分支跟踪新的远程示例分支。

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

$ git push <em>remote</em> <em>refspec</em>

您命名的remote是典型的,origin;这让你的 git 找到他们 git 的 URL。这部分到目前为止都很好。

你给的 refspec 出现问题,master

您可能想知道:"refspec" 到底是什么?答案是它是两部分,有时是三部分,两个分支1 名称用冒号分隔:

ours:theirs

例如2

"But wait," 你可能会说,"there's no : in master, there's only one branch name!" 这是真的,但是 git push 需要两个,所以它组成了另一个:当你给一个名字时,它会复制那个你给它,所以 master 就意味着 master:master.

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

如果您想推送当前提交 (HEAD) 并让他们的 git 将其作为他们的 master 放入,您必须3 写出来:

git push origin HEAD:master

意识到当你 git push 某事时,他们 一方不关心(甚至不知道)关于 [=69= 上的任何分支的任何事情]您的 端:您的git 将您的分支转换为原始 SHA-1 值,并将这些(原始 SHA-1)发送到远程。例如,如果您的 HEAD 映射到提交 ID 1234567,git push origin HEAD:master 让您的 git 调用他们并交付提交 1234567,然后向他们发送一条消息:"now that I've given you commit 1234567, please make your master point to that commit-ID." 他们的结局然后说 "OK"(推送成功)或 "no, I refuse"(推送失败,例如,不是快进,或被 gitolite 等脚本拒绝的权限,或其他)。因此,您使用的任何分支名称引用 您的 一侧 - localname:remotename 的左侧 - 完全由您处理,并且只有右侧的名称被传递到远程 git。这就是为什么你可以使用 HEAD:master.


1实际上,任何有效的引用都可以放在这里。标签是以 refs/tags/ 开头的引用,git 现在有 "notes" 等等;所有这些都使用引用。但是大多数人大部分时间都在使用分支机构。

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

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