Question

Maybe I'm missing something about remotes, but this just puzzled me: I have a git repo with a remote, the remote is in fact my USB stick. On my remote, there is one commit more than in my local repo, so

 local-dir> git rev-list master -3

gives me

941eba8b82233f5daceb41a57e10ff2d6d893fb9 
8b386974a1976142912c41cc7e270e69ad5ecbd5
dd09efc70c029ea79fcfc455068df3788d4e193a

and

remote-dir> git rev-list master -4

gives me

28aaf69aafa9f21ad52c874d2e753bfd8e1b1f65                                   
941eba8b82233f5daceb41a57e10ff2d6d893fb9
8b386974a1976142912c41cc7e270e69ad5ecbd5
dd09efc70c029ea79fcfc455068df3788d4e193a

So far so good.

My remote is called stick. When I do

 local-dir> git rev-list stick/master -4

I get

a0e2cf2a389647768384259e3e8f5a7b310740d4
243a8b06b3df1f232dafb9385eab8336dea23f25
c316830bb4c5a27d29e01bbd734ab46f3d90a24e
bfd1dc912ab3c9f9d9bc5b10303b580305f68ac4  

where further investigations reveals that "this way" I'm about 10 commits behind. A git fetch stick master will not change the situation.

I had expected that remote-dir> git rev-list master -4 and local-dir> git rev-list stick/master -4 yield the same, at least after a fetch. Seems I'm missing something. Can someone explain what?

Was it helpful?

Solution

The command:

git fetch stick master

acts differently in older gits than in the very newest ones.

It tells git to:

  1. Look up the name stick as a remote (which finds the path to the USB stick).
  2. Consult the remote—usually this would be over a network, but in this case, just go look in the other repository—to see what branches it has.
  3. If the remote has a branch named master (which it does), gather up any commits and other objects required.
  4. Finally (this is where the newest gits differ), write those only under the name FETCH_HEAD in the local repository; do not update the "remote-branch" information in refs/remotes/stick/master.

It's this last step that is causing confusion.

If you run instead:

git fetch stick

this will follow the first two steps, but for steps 3 and 4, it brings over all the branches and does update all the remote-branch information. Then git rev-list stick/master -4 will behave the way you expected it to.

If you upgrade to git 1.8.4 or newer, git fetch will update the remote-branch information in step 4 even with the two-argument git fetch form, and again it will behave the way you expected.

Here's what the release notes for 1.8.4 have to say about this:

  • "git fetch origin master" unlike "git fetch origin" or "git fetch" did not update "refs/remotes/origin/master"; this was an early design decision to keep the update of remote tracking branches predictable, but in practice it turns out that people find it more convenient to opportunistically update them whenever we have a chance, and we have been updating them when we run "git push" which already breaks the original "predictability" anyway.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top