xrfang
xrfang

Reputation: 2306

git: update HEAD after fetch into a bare repo

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.

Upvotes: 4

Views: 1486

Answers (2)

CodeWizard
CodeWizard

Reputation: 142074

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
    

Upvotes: 3

torek
torek

Reputation: 488143

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.

Upvotes: 1

Related Questions