17

So - can someone clarify this one:

I run:

git pull origin master  
git status

And it then pulls the changes and says:

your branch is ahead of origin/master ... blahblah by 6 commits...

When I then run

git fetch
git status

It says:

# On branch master
nothing to commit (working directory clean)

So - I thought git pull does git fetch by default - so why does it says "ahead by 6 commits" without additional git fetch?

Dannyboy
  • 1,963
  • 3
  • 20
  • 37
  • In this particular case it means what it says: your branch is ahead, i.e. contains unpushed commits, which has nothing to do with the pull, it's just a heads-up for you. – bredikhin Dec 12 '13 at 17:19
  • @bredikhin But I've just pulled these commits - why in the world would they be classified as un-pushed? That's where I'm confused. Why when I pull changes from a remote branch I don't just get a message "nothing to commit (working directory clean)" right away? – Dannyboy Dec 12 '13 at 17:24
  • is it possible that before you ran `git status` the second time, you ran `git push`? – micromoses Dec 12 '13 at 17:33
  • @Dannyboy Your local commits are un-pushed, not those you have pulled. – bredikhin Dec 12 '13 at 17:33
  • @bredikhin But I don't have any local commits. And if I do `git fetch` - after `git pull` -> this message doesn't come up, I just get "nothing to commit (working directory clean)" – Dannyboy Dec 12 '13 at 17:34
  • It is also possible that your branch `master` is not tracking `origin/master`. So you get this output when you run `git pull origin master`, but not `git status`. Can you please post your `.git/config` file contents? – micromoses Dec 12 '13 at 17:36
  • @Dannyboy Because `fetch` refreshes remote branch (`origin/master`) on your local machine, and `pull` merges directly to your local `master` branch. – bredikhin Dec 12 '13 at 17:39
  • @bredikhin But from documentation: "In its default mode, `git pull` is shorthand for `git fetch` followed by `git merge FETCH_HEAD`". So pull does fetch as well - am I wrong? – Dannyboy Dec 12 '13 at 17:41
  • @micromoses http://paste.ubuntu.com/6562613/ – Dannyboy Dec 12 '13 at 18:01
  • `git remote show origin`; `git branch -u origin/master master` – Bert F Dec 12 '13 at 18:09

1 Answers1

3

The "ahead or behind by X commits" text in git status is based on the state of the tracking branch for the current branch; remotes/origin/master if you're on master, for example.

When you run git pull with both a remote and a branch specified, it fetches the new commits and merges them in to the current branch, but it does not update origin's remote tracking branches. Instead, it points to the just-fetched commits as FETCH_HEAD.

Running git fetch with no arguments specified, on the other hand, does update all of the remote tracking branches, so it makes the message go away. git pull with no arguments does the same.

A subtle gotcha that I've hit a bunch of times myself! I wish git updated all remote tracking branches on every fetch against a particular remote, instead.

Ash Wilson
  • 22,820
  • 3
  • 34
  • 45
  • Just out of curiosity, do you know *why* `git pull ` does not update the *`remote/branch`* ref? Is it just Hysterical Raisins, or is there some good reason? – torek Dec 13 '13 at 00:35
  • It turns out that it actually isn't `git pull ` at all; it's really `git pull `. A "refspec" is basically a source-destination pair separated by a colon, like `master:origin/master`; `git pull origin master:origin/master` means "go to the origin remote, give me its master branch, and update origin/master in the local repository." If you leave off the colon, the fetch won't update any local refs at all, just `FETCH_HEAD`. – Ash Wilson Dec 13 '13 at 01:11
  • Further reading: http://git-scm.com/book/en/Git-Internals-The-Refspec – Ash Wilson Dec 13 '13 at 01:12