17

So here's the situation:

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by [x] commits.
#

There are several questions about this on SO already, but none seem to specifically address the type of scenario I have. This answer to one of the questions comes closest, but doesn't go into detail.

I'll just quote it verbatim:

If you get this message after doing a "git pull remote branch", try following it up with a "git fetch".

Fetch seems to update the local representation of the remote branch, which doesn't necessarily happen when you do a "git pull remote branch".

That tip does indeed work. But "doesn't necessarily happen?" Why not? I need to understand this. What is pull not doing?

I don't want to take over that question, so here's my scenario in detail:

Three computers involved. The Mac on which I develop, my home server where the git repo (i.e. origin/master) lives and a Webfaction account that pulls from that server.

I do commits and git push origin master only on the Mac. The only command that ever gets run on Webfaction as part of the normal workflow is git pull origin master (as part of a Fabric deployment script). I don't modify code there. I'm a lone developer, so neither does anyone else.

Every now and then I log in to Webfaction and check on things, including a git status. Inevitably, I always get the "Your branch is ahead..." message. Running git fetch makes the message go away.

I'm about to add git fetch to the Fabric script to be done with this issue, but I want to know why that needs to be done, especially on a pull-only clone of origin/master. I'm not deeply versed in Git though I use the basic functionality daily, so a newbie-friendly explanation would be appreciated.

Update as requested, the relevant bits from config:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = git@[server_address]:[path/to/repo.git]
[branch "master"]
    remote = origin
    merge = refs/heads/master
Community
  • 1
  • 1
JK Laiho
  • 3,538
  • 6
  • 35
  • 42
  • Can you post the "origin" part of your git config from the Webfaction server in the question? I have a feeling it might have something to do with it. – Nic Sep 09 '11 at 17:50
  • Note that I haven't modified that config file in any way. It was created with a standard `git clone` from the origin repo. – JK Laiho Sep 09 '11 at 18:23
  • Note that at the time this question was posted, the *current* version of Git was 1.7.10. – torek May 11 '20 at 19:11

5 Answers5

11

Ok, so from the outset, you're doing everything correctly. I think the comment you added previously is a pretty good explanation:

In the simplest terms, "git pull" does a "git fetch" followed by a "git merge"

That's how I think of it. So you shouldn't have to call a git fetch after a straight up git pull - but, I can almost guarantee you, this works perfectly fine on anything EXCEPT the master branch.

In one of the linked posts, it said to remove the following line:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/* <--- Remove this

And it should fix this issue - however, I cannot provide an explanation as to why this works. It's very hard to research, but I think that when you call fetch, your git config actually specifies what exactly to grab. When you're running pull, I'm not sure that it thinks the master is synced.

I can guarantee you that if you did this from another non-master branch, you wouldn't see this problem. Hopefully one of the git gurus can explain the fetch line in config in detail.

Furthermore, I would recommend running the following command instead which sets the HEAD for the remote repository to ensure it is in sync with your local one: git push -u origin master


Here's another interesting question:

Having a hard time understanding git-fetch


Ok, so I tested this on one of my workflows and found the following.

When you execute a git pull origin master on your remote server, there's a file in the .git/ directory that references where your HEAD is at. Two files to take note of:

ORIG_HEAD

FETCH_HEAD

You'll notice that your FETCH_HEAD is correct, but the ORIG_HEAD shows the old commit, hence the reason you're getting the Ahead by x. When you run git fetch, you'll actually correct the reference in ORIG_HEAD and everything is back to normal. I'm looking into how to change the fetch line in the config to fix this behavior.

Community
  • 1
  • 1
Nic
  • 13,287
  • 7
  • 40
  • 42
  • Marked as accepted. Looking at the other questions on this topic, I doubt I would even understand any more technical explanations (since among other things, I don't really understand what "refspecs" and tracking branches often mentioned in other Git-related questions actually are...) – JK Laiho Sep 10 '11 at 20:44
  • I just had to do a git fetch on my master for some reason. – Chris Bier Nov 17 '13 at 00:37
  • I've had the same problem on non-master remote tracking branches, and at the level of git fetch rather than git pull. git fetch remote branch does not seem to update the ORIG_HEAD as this answer indicates, and git fetch does. @Nic - did you find a better fetch line for the config file to cause the long form command to also update ORIG_HEAD? – Anatortoise House Dec 03 '14 at 20:36
  • I have both ORIG_HEAD and FETCH_HEAD point to the same commit and still got this error.... – Dani Nov 16 '16 at 18:58
8

If you run a git pull origin instead of a git pull origin master, there won't be the issue with the Your branch is ahead of 'origin/master' by ... commits. message.

tomvodi
  • 5,577
  • 2
  • 27
  • 38
  • Yeah, this is interesting. When I "pull origin master" it seems to grab only HEAD of origin/master (` * branch master -> FETCH_HEAD`), but "pull origin" grabs the entire branch (` 647e59e..e1d6c02 master -> origin/master`). – jarvisteve Aug 19 '16 at 18:07
  • THIS is what I needed. Thank you! – JohnK Mar 13 '19 at 17:16
2

Note: this question was recently linked-to from Git: unable to get remote and local/server the same. Note that the date on the original question is September 2011; the then-most-current version of Git was 1.7.10. Git is now at version 2.26.2.

In versions of Git predating Git 1.8.4, running git pull origin master suppresses updating the local name origin/master. (So does running git fetch origin master.)

Running git fetch, with no additional arguments, causes all versions of Git—before and after 1.8.4—to update all remote-tracking names, including origin/master. So that's the real explanation behind this mystery.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Hah, a blast from the past :D thanks for clearing it up after all these years. It’s still bizarre to me why it did that, but it is what is is. (Or rather, it was what it was...) Switched this to be the accepted answer. – JK Laiho May 12 '20 at 21:02
  • 1
    The [1.8.4 release notes](https://github.com/git/git/blob/b994622632154fc3b17fb40a38819ad954a5fb88/Documentation/RelNotes/1.8.4.txt#L226-L232) explain why they thought this was a good idea, then changed their minds. Well, *explains* is too strong... it at least *says* they thought it was a good idea. :-) – torek May 12 '20 at 21:07
1

See this question: What is the difference between 'git pull' and 'git fetch'?

AFAIK a git pull will look at the branch on origin and pull down the changes. But the local index of the branch is not up-to-date. git fetch will update the index of the branch so it understands what should be there. (basically what was referenced in the answer you linked to)

I always do a git fetch before a git pull. Really I do a git fetch anytime I am going to be doing anything with remote branches.

Also linked on the above question is this very good description of git fetch, pull and merge. http://longair.net/blog/2009/04/16/git-fetch-and-merge/

Community
  • 1
  • 1
jhanifen
  • 4,441
  • 7
  • 43
  • 67
  • The accepted answer to that question says: 'In the simplest terms, "git pull" does a "git fetch" followed by a "git merge".' I'm still confused as to when that is actually the case and when a separate git fetch is needed. – JK Laiho Sep 09 '11 at 18:14
  • melee explained this above. I also would love to know why the master branch is treated differently then other branches. – jhanifen Sep 09 '11 at 19:00
0

In my case - I had two branches in Origin and everytime i pulled a git pull it showed that i was ahead of origin/master by x. Even after hard reseting it to the origin/master like shown in Reset local repository branch to be just like remote repository HEAD.

The solution occured when i simply ran git fetch and it brought my development branch onto my production server.

Community
  • 1
  • 1
Ulad Kasach
  • 11,558
  • 11
  • 61
  • 87