FETCH_HEAD reference not updating correctly after “git fetch”

前端 未结 3 1009
予麋鹿
予麋鹿 2021-02-08 22:19

I have a local repository that pulls from a remote one. Running git pull as well as git fetch; git merge FETCH_HEAD used to perform exactly the same ac

3条回答
  •  花落未央
    2021-02-08 23:15

    Running git fetch without any options will fetch all references in the remotes and write them to the .git/FETCH_HEAD file. The contents of the file usualy looks something like this:

    37301df96597ac037f8e7e846fea6fc7df77bea5 branch 'master' of github.com:user/repo
    593539e8a98ba5980d4b645db3b0f506bb9b6a2c not-for-merge branch 'branchOne' of github.com:user/repo
    

    When you have a file like this under the .git directory, you can use it as a reference as long as the first thing in that file is either a 40 character hex number, or a shorter hex number that actualy matches to an existing commit.

    # This file can be used as a reference
    > cat .git/MAGIC_HEAD
    deadbeefdeadbeefdeadbeefdeadbeefdeadbeef lorem ipsum
    the rest does not really matter
    refrigerator
    
    # And thus it will be interpreted by many git commands like this
    > git rev-parse MAGIC_HEAD
    deadbeefdeadbeefdeadbeefdeadbeefdeadbeef
    

    Knowing this we can see that after running git fetch the reference FETCH_HEAD will resolve to is whatever happens to be in that first line

    # Assuming the already mentioned contents of .git/FETCH_HEAD
    > git rev-parse FETCH_HEAD
    37301df96597ac037f8e7e846fea6fc7df77bea5
    

    Seems like the order of the contents of .git/FETCH_HEAD is not guaranteed to contain first the reference for the current branch.

    By trying it in different repositories it seems that in some the first line is always the current branch, and thus git fetch; git merge FETCH_HEAD works as expected. On other repositories however the contents of .git/FETCH_HEAD will be ordered differently and often the first line will be a reference to the remote commit of a different branch, thus making the FETCH_HEAD reference incorrect.

    Why it behaves differently is a mystery to me.

    As a solution, if git fetch remote_name branch_name is used only this specific branch is fetched and only that single line will appear in the contents of .git/FETCH_HEAD, making the FETCH_HEAD reference always correct.

    # Will only fetch branchone
    > git fetch origin branchone
    
    # FETCH_HEAD will contain only a single line
    > cat .git/FETCH_HEAD
    593539e8a98ba5980d4b645db3b0f506bb9b6a2c branch 'branchOne' of github.com:user/repo
    

提交回复
热议问题