Number945
Number945

Reputation: 4940

git FETCH_HEAD short lived reference

  1. I read here that git FETCH_HEAD is a short lived reference . What is the life of git FETCH_HEAD reference ?

  2. When I do git fetch origin , in such cases many remote tracking branch are updated. Where will FETCH_HEAD point to ?

Upvotes: 3

Views: 2155

Answers (2)

ElpieKay
ElpieKay

Reputation: 30868

As it says in gitrevisions,

FETCH_HEAD records the branch which you fetched from a remote repository with your last git fetch invocation.

FETCH_HEAD is created by the first git fetch and will be updated by git fetch. By git fetch, it also means git pull because git pull can be git fetch + git merge or git fetch + git rebase.

For git fetch origin foo, undoubtedly FETCH_HEAD points to the tip of foo. foo is a valid ref that can be fetched from the remote repository. In some rare cases, foo can be the hash of a specific object (commit, tree, blob or tag) if uploadpack.allowTipSHA1InWant is set true in the remote repository, and then FETCH_HEAD will point to the object.

It becomes complicated when it comes to git fetch or git fetch origin. What will FETCH_HEAD be updated to? There are many cases. For example, the local repository is in detached HEAD, on a specific branch that has an upstream, on a branch that doesn't have an upstream, or in some other cases. If not digging that deep, we can know the result from the output of git fetch. Here is a sample,

remote: Counting objects: 11, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 11 (delta 7), reused 0 (delta 0)
Unpacking objects: 100% (11/11), done.
From D:/hello
   ca2d63e..38d365c  ost        -> origin/ost
 * [new branch]      a          -> origin/a
   8fe4b12..db5a0d9  aaa        -> origin/aaa
   36ca690..e00229b  haha       -> origin/haha
   c96b459..5ab6097  master     -> origin/master
   283a081..004375e  mist       -> origin/mist

We can see the output says which refs are updated by git fetch. FETCH_HEAD always points to the first ref's tip. In this sample, FETCH_HEAD is origin/ost's tip, 38d365c. It's also true when fetching only one ref or one object.

If a git fetch process fails, FETCH_HEAD will become an unknown revision. The file .git/FETCH_HEAD still exists and it's just empty.

Upvotes: 2

Edward Thomson
Edward Thomson

Reputation: 78673

  1. It's not really a true reference at all; a reference is a pointer to a single commit (or, in the case of HEAD, a branch name). FETCH_HEAD instead is git metadata about the branches that were last fetched. It lives until it's rewritten by another fetch

  2. It's not a true reference, and contains all the information about the remote tracking information that was fetched.

When you run git merge FETCH_HEAD (or do so implicitly, by running git pull), git treats this specially, and not like a normal reference. Instead, the FETCH_HEAD file will be consulted, and git will look for a branch that does not have the special token not-for-merge given to it. That branch will be the one used for the merge. (Git determined this branch based on the remote tracking branch corresponding to your git fetch invocation or the branch that you were on when you ran it.)

Note that in FETCH_HEAD, the details about the remote branch are also included, which allows git to create a message for the merge commit that details where that branch came from. (eg, "Merge of branch 'master' of https://my.visualstudio.com/my/repository").

FETCH_HEAD, like much of the git repository metadata, is just a text file; reading it to see how it changes after each fetch is incredibly illuminating. (You can see, for example, that the answer that you link to is terribly incorrect, and that FETCH_HEAD does not contain a single branch's information, it contains all the branches on the remote.) 😃

Upvotes: 6

Related Questions