Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git: update HEAD after fetch into a bare repo

Tags:

git

I have a bare repo at, say, /var/lib/repos/myrepo.git, I try to update it by doing:

$ cd /var/lib/repos/myrepo.git
$ git fetch

I get the latest commits from remote, however, the HEAD pointer is NOT updated. If I do

$ git log

it just show me the log message BEFORE the update, if I do

$ git log FETCH_HEAD

I can see the latest commits.

I want to either update HEAD to point to the sha1 of FETCH_HEAD, or to let me clone the bare repo to another directory at FETCH_HEAD. However, the FETCH_HEAD reference is NOT available in the working directory.

like image 635
xrfang Avatar asked Oct 29 '25 07:10

xrfang


2 Answers

I have a bare repo

In a bare repository, you do not have a file system so you don't have any ref to update.

... want to either update HEAD to point to the sha1 of FETCH_HEAD,


How to update the HEAD (which will be the default branch when cloning)

In a bare repo if you wish to set the default branch use this command:

git symbolic-ref HEAD refs/heads/<branch_name>

On a "regular" git repository you can do the following:

  • Update your current branch to the desired commit:

    git reset FETCH_HEAD --hard
    
  • Verify that the commit is fetched and exist in your local .git repo.
    Since you mentioned you can see the log of the commit so it should be in your repo

    git show FETCH_HEAD
    
like image 109
CodeWizard Avatar answered Oct 31 '25 00:10

CodeWizard


A clone made with git clone --bare has a default empty fetch refspec. This means that when you run git fetch, you are effectively running git fetch with no refspec. This is ... not a good plan. A regular --bare repository is meant to be pushed to, and nothing else.

As CodeWizard said, a bare clone has no work-tree, but this is something of a red herring. A bare clone still does have a HEAD reference, which is a symbolic reference pointing to one of its branch names.

You probably want a clone made with git clone --mirror. This is the same as a bare clone except that its default fetch refspec is +refs/*:refs/*. This means that running git fetch in such a clone updates all of its references to match the upstream repository, unconditionally.

Note that this kind of clone is not meant for receiving git push requests, because running git fetch within it will replace all of its branch name to hash-ID mappings with whatever is set in its origin.

If, however, you want a bare clone that updates whichever branch its HEAD maps to, you can:

  • find out which branch its HEAD is a symbolic ref to, using git branch --symbolic-ref HEAD
  • run git fetch origin +refs/heads/name:refs/heads/name to update that one reference.

Or if you won't re-assign HEAD in this repository, you could run:

git config remote.origin.fetch +refs/heads/master:refs/heads/master

(assuming the HEAD name resolves to master), after which a plain git fetch will update just the master branch.

like image 20
torek Avatar answered Oct 31 '25 00:10

torek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!