First, there's no such concept of "local tracking" branches, only "remote tracking" branches. So origin/master is a remote tracking branch for master in the origin repo.
Typically you do git fetch $remote
which updates all your remote tracking branches, and creates new ones if needed.
However, you can also specify a refspec, but that will not touch your remote tracking branches, instead, it will fetch the branch you specified and save it on FETCH_HEAD
, unless you specify a destination. In general you don't want to mess with this.
Finally:
fetch = +refs/heads/*:refs/remotes/origin/*
That means if you do
git fetch origin
It will actually do:
git fetch origin +refs/heads/*:refs/remotes/origin/*
Which means a remote heads/foobar will be the local remotes/origin/foobar, and the plus sign means they'll be updated even if it's non-fast-forward.
So your local origin/foobar will always be the same as foobar on the origin remote (after running git fetch
). And origin/master will obviously be the same as master on the origin remote. So will all the other remote tracking branches.
You can think of the HEAD as the "current branch". When you switch branches with git checkout
, the HEAD revision changes to point to the tip of the new branch.
You can see what HEAD points to by doing:
cat .git/HEAD
In my case, the output is:
$ cat .git/HEAD
ref: refs/heads/master
It is possible for HEAD to refer to a specific revision that is not associated with a branch name. This situation is called a detached HEAD.
Best Answer
FETCH_HEAD
is a short-lived ref, to keep track of what has just been fetched from the remote repository.git pull
first invokesgit fetch
, in normal cases fetching a branch from the remote;FETCH_HEAD
points to the tip of this branch (it stores the SHA1 of the commit, just as branches do).git pull
then invokesgit merge
, mergingFETCH_HEAD
into the current branch.The result is exactly what you'd expect: the commit at the tip of the appropriate remote branch is merged into the commit at the tip of your current branch.
This is a bit like doing
git fetch
without arguments (orgit remote update
), updating all your remote branches, then runninggit merge origin/<branch>
, but usingFETCH_HEAD
internally instead to refer to whatever single ref was fetched, instead of needing to name things.