1

If I do git fetch origin master doing git diff ...origin does not have the same results if I do git fetch (without specifying branch) and then do git diff ...origin (see below). Why is that? (just to note: git version 1.7.3.1.msysgit.0)

git init parent && cd parent

echo 'version1' > contents.txt
git add contents.txt
git commit -m "version1"

cd ..
git clone parent child
cd child

echo 'child' >> contents.txt
git commit -a -m "Child"

cd ../parent
echo 'parent' >> contents.txt
git commit -a -m "Parent"

cd ../child
git fetch origin master
git diff ...origin

echo Expected diff here and it wasn't there!

git fetch
git diff ...origin

echo Ok, diff appeared properly now!

1 Answer 1

3

git fetch origin master doesn't store the updated commit pointer in .git/refs/remotes/origin/master, it stores it in .git/FETCH_HEAD, as demonstrated by your example's output:

$ git fetch origin master
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /tmp/parent
* branch            master     -> FETCH_HEAD

If you want to see the diff, just issue git diff ...FETCH_HEAD:

$ git diff ...FETCH_HEAD
diff --git a/contents.txt b/contents.txt
index 5bdcfc1..1f428af 100644
--- a/contents.txt
+++ b/contents.txt
@@ -1 +1,2 @@
 version1
+parent

You can see why in the man page:

The ref names and their object names of fetched refs are stored in .git/FETCH_HEAD. 
This information is left for a later merge operation done by git merge.

When you issue git fetch origin, on the other hand, it updates all your local tracking tracking branches. From your example:

$ git fetch origin
From /tmp/parent
e23f025..4ea3d15  master     -> origin/master

From the man page again:

Update the remote-tracking branches:

       $ git fetch origin

   The above command copies all branches from the remote refs/heads/ namespace and stores them to the local refs/remotes/origin/ namespace, unless the
   branch.<name>.fetch option is used to specify a non-default refspec.
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot... that operation still doesn't seem natural now at least I know what's happening now :) Is there any way to update my local origin/master from the FETCH_HEAD?
In your example, your local "master" branch tracks origin's master branch. So you could issue git merge FETCH_HEAD to merge in the change you grabbed with git fetch origin master. Alternatively, you can fetch directly to the 'origin/master' pointer with git fetch origin master:refs/remotes/origin/master and then git merge origin/master. Frankly, in day to day operations, it doesn't matter. Either works. I use the FETCH_HEAD version from habit and laziness. You might also look into git pull, which does both the fetch and merge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.