Fabio Zadrozny
Fabio Zadrozny

Reputation: 25332

Why git fetch specifying branch does not match fetch without specifying branch (for diffing purposes)

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!

Upvotes: 1

Views: 220

Answers (1)

Christopher
Christopher

Reputation: 44234

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.

Upvotes: 3

Related Questions