27

I'm new to git, and I can't make sense of the following behavior:

I have a bitbucket repo that I clone locally, then I modify and commit locally, then I push to the remote repo. If I do an implicit push, or 'push origin', there's no issue. If I push using explicit remote url, I get the status message 'Your branch is ahead of 'origin/master' by 1 commit'.

It seems that git does not recognize the explicit address as being the same as origin, so what exactly is going on. If I do another implicit push, it does nothing, but it does clear the said message.

Here's a sample session:

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)
Basel Shishani
  • 7,735
  • 6
  • 50
  • 67
  • This question was probably closed incorrectly as a duplicate of the wrong question. As soon as I'm finished getting a dupe hammer for Git, I'll start reopening and properly closing questions like this as duplicates of [other Your branch is ahead of 'origin/master' questions](https://www.google.com/search?q=Your+branch+is+ahead+of+%27origin%2Fmaster%27). –  Jul 21 '14 at 15:10

4 Answers4

20

When the status says Your branch is ahead of 'origin/master' by 1 commit, it actually does mean origin/master. That is, there is pointer named origin/master in your repo pointing to the commit which is the HEAD of that remote branch, and your master is ahead of this commit.

For all the remotes that your repo recognizes, it creates a <remote>/<branchname> pointer in the repo, if you pull/push/fetch. Its just a pointer to the commit, and if you try to checkout that branch, you'd only be in a detached state.

Apparently, this pointer gets updated when you do git push or git push origin master, but explicitly pushing to a url would not update that pointer, and hence the status.

If you just do git fetch or git pull after pushing to the url, the status message will also disappear in that case.

NOTE: If you have multiple remotes, and you set your branch to track some other remote branch, like say upstream master, your status message will in this case be, for example, Your branch is ahead of 'upstream/master' by 1 commit. So its only the tracked remote branch that the comparison is done. See git config to see what remote branch your current branch is tracking.

Borealid
  • 95,191
  • 9
  • 106
  • 122
Sailesh
  • 25,517
  • 4
  • 34
  • 47
19

I believe you need to pull the change back in before git will realize that the remote end has been updated. You can do this via a quick git pull (or, as you show in your example, a git push to the tracked origin).

You could also manually change the commit to which refs/remotes/origin points.

It's not fair to expect the content tracker to recognize arbitrary remote synonyms for repositories; imagine if you had five different URLs which all were the same server-side repository. When you push to repo A, does that mean that your changes have been committed to repo B (the origin of your branch)? git has no way to know. Instead, it only updates the remote-head reference in two cases: a pull, and a push to the default destination.

Borealid
  • 95,191
  • 9
  • 106
  • 122
  • I agree with what you're saying about a repo having different synonyms, but if we are using the exact same url that git is already aware of (and is reported by 'remote show origin'), then why shouldn't it recognize the fact. After all, a url points to a unique resource. On the other hand if the user is using a different synonym they would be aware of that and won't expect git to recognize its pointing to the same resource. – Basel Shishani Jan 29 '12 at 05:25
  • @BaselShishani That's a slippery slope. If you did what you suggest, and compared the exact string of the URLs (so easy!), then pushing `https://shishani@bitbucket.org/shishani/dirasi.git` would update the head and `http://shishani@bitbucket.org/shishani/dirasi.git` would not. Ditto query strings, different protocols, extra slashes, capitalization... You're welcome to submit a feature request to the git people, they're nice! – Borealid Jan 29 '12 at 05:28
8

Yes, you will have to do a git fetch or git fetch origin in that case. Git doesn't care where you push to, only the remote (and remote tracking branches) is all that matters when reporting the status of how many commits you are ahead etc.

manojlds
  • 290,304
  • 63
  • 469
  • 417
0

Note that, since git1.8.1rc1 (December 2012), Git will include hint messages:

if (advice_status_hints)
+      strbuf_addf(sb,
+        _("  (use \"git push\" to publish your local commits)\n"));

When "git checkout" checks out a branch, it tells the user how far behind (or ahead) the new branch is relative to the remote tracking branch it builds upon.
The message now also advises how to sync them up by pushing or pulling.

This can be disabled with the advice.statusHints configuration variable.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250