在显式推送时,“您的分支领先于'origin/master' 1次提交”。

27

我是git的新手,对以下情况感到困惑:

我有一个bitbucket仓库,我在本地克隆它,然后修改并提交,最后推送到远程仓库。如果我进行隐式推送或“push origin”,就没有问题。但如果使用显式的远程地址推送,我会得到状态消息“Your branch is ahead of 'origin/master' by 1 commit”。

看起来Git不认为显式地址和origin是相同的,那么究竟发生了什么呢?如果我再做一次隐式推送,它什么也不会做,但会清除上述消息。

以下是一个示例操作过程:

baz@bhost:/more/coding/git-tests/ask1$ git --version
git version 1.7.2.5

baz@bhost:/more/coding/git-tests$ git clone https://shishani@bitbucket.org/shishani/dirasi.git ask1
Cloning into ask1...
Password: 
remote: Counting objects: 24054, done.
remote: Compressing objects: 100% (6300/6300), done.
remote: Total 24054 (delta 17124), reused 24024 (delta 17106)
Receiving objects: 100% (24054/24054), 11.83 MiB | 251 KiB/s, done.
Resolving deltas: 100% (17124/17124), done.

baz@bhost:/more/coding/git-tests$ cd ask1

baz@bhost:/more/coding/git-tests/ask1$ jed setup.py

baz@bhost:/more/coding/git-tests/ask1$ git commit -a
[master a053f28]    modified:   setup.py
 1 files changed, 1 insertions(+), 0 deletions(-)

baz@bhost:/more/coding/git-tests/ask1$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

baz@bhost:/more/coding/git-tests/ask1$ git remote show origin
Password: 
* remote origin
  Fetch URL: https://shishani@bitbucket.org/shishani/dirasi.git
  Push  URL: https://shishani@bitbucket.org/shishani/dirasi.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (fast-forwardable)

baz@bhost:/more/coding/git-tests/ask1$ git push
Password: 
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 314 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: bb/acl: shishani is allowed. accepted payload.
To https://shishani@bitbucket.org/shishani/dirasi.git
   5e9ffd1..a053f28  master -> master

baz@bhost:/more/coding/git-tests/ask1$ git status
# On branch master
nothing to commit (working directory clean)

baz@bhost:/more/coding/git-tests/ask1$ jed setup.py

baz@bhost:/more/coding/git-tests/ask1$ git commit -a
[master 6d0e236]    modified:   setup.py
 1 files changed, 1 insertions(+), 0 deletions(-)

baz@bhost:/more/coding/git-tests/ask1$ git push https://shishani@bitbucket.org/shishani/dirasi.git master
Password: 
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 298 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: bb/acl: shishani is allowed. accepted payload.
To https://shishani@bitbucket.org/shishani/dirasi.git
   a053f28..6d0e236  master -> master

baz@bhost:/more/coding/git-tests/ask1$ git status
# On branch master
**# Your branch is ahead of 'origin/master' by 1 commit.** <-- this does not reflect current state
#
nothing to commit (working directory clean)

baz@bhost:/more/coding/git-tests/ask1$ git push
Password: 
Everything up-to-date

baz@bhost:/more/coding/git-tests/ask1$ git status
# On branch master
nothing to commit (working directory clean)

这个问题很可能被错误地关闭为另一个问题的重复。一旦我完成了 Git 的 dupe hammer,我将开始重新打开并正确地将此类问题标记为 other Your branch is ahead of 'origin/master' questions 的重复。 - user456814
4个回答

20
当状态显示为Your branch is ahead of 'origin/master' by 1 commit时,实际上指的是origin/master。也就是说,在您的存储库中有一个名为origin/master的指针,指向作为该远程分支HEAD的提交,并且您的master比此提交要新。
对于所有您的存储库识别的远程服务,如果您进行拉取/推送/获取操作,则在存储库中创建一个<remote>/<branchname>指针。它只是指向提交的指针,如果尝试checkout该分支,则会进入分离状态。
显然,当执行git pushgit push origin master时,此指针将得到更新,但是显式地推送到URL将不会更新该指针,因此状态也不会更新。
如果您在推送到URL后只执行git fetchgit pull,则状态消息也会消失。
注意:如果您有多个远程服务器,并且您将自己的分支设置为跟踪某个其他的远程分支,例如upstream master,则在这种情况下,您的状态消息将如Your branch is ahead of 'upstream/master' by 1 commit所示。因此,只有跟踪的远程分支才进行比较。请参见git config以查看当前分支正在跟踪哪个远程分支。

19

我认为在 git 意识到远程端已更新之前,您需要将更改拉回来。您可以通过快速执行 git pull (或者如您在示例中所示,对跟踪的源进行 git push )完成此操作。

您还可以手动更改 refs/remotes/origin 指向的提交。

期望内容跟踪器识别存储库的任意远程同义词是不公平的;想象一下,如果您有五个不同的 URL,它们都是同一个服务器端存储库。当您推送到 repo A 时,这是否意味着您的更改已提交到 repo B(分支的来源)?git 没有办法知道。相反,它仅在两种情况下更新远程-head 引用:拉取和推送到默认目标。


我同意你关于仓库有不同的同义词的说法,但是如果我们使用与git已经知道的完全相同的url(并且由'remote show origin'报告),那么为什么它不应该认识到这一事实呢?毕竟,一个url指向一个唯一的资源。另一方面,如果用户使用了不同的同义词,他们会意识到这一点,并且不会期望git能够识别它指向相同的资源。 - Basel Shishani
@BaselShishani 这是一个很棘手的问题。如果你按照你所建议的那样比较URL的确切字符串(非常容易!),那么推送 https://shishani@bitbucket.org/shishani/dirasi.git 将更新head而 http://shishani@bitbucket.org/shishani/dirasi.git 不会更新。同样适用于查询字符串、不同的协议、额外的斜杠、大小写等等...你可以向git的开发人员提交一个功能需求,他们会很友善! - Borealid

8

是的,在这种情况下,您将需要执行git fetchgit fetch origin。Git不关心您推送到哪里,只有远程(和远程跟踪分支)在报告您超前多少次提交时才有意义。


0
请注意,自git1.8.1rc1(2012年12月)以来,Git 将包括提示信息
if (advice_status_hints)
+      strbuf_addf(sb,
+        _("  (use \"git push\" to publish your local commits)\n"));

当“git checkout”检出一个分支时,它会告诉用户新分支相对于其构建的远程跟踪分支落后(或领先)多少。
现在该消息还会建议通过推送或拉取来同步它们。
可以通过配置变量“advice.statusHints”来禁用此功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接