Search code examples
gitbranchgit-clone

How to clone a bare git repo with no commits and get the correct HEAD ref during the clone?


This answer claims that the issue was fixed in version 1.8.4.3, but I still encounter it in version 2.25.1. It appears to work as expected in version 2.32.0, so I'm not sure when it was actually fixed.

Is there a way to get the expected behavior in git version 2.25.1 using the clone subcommand (without having to checkout/switch branches after cloning)?

Here are reproduction steps:


  1. Initialize a bare repo:
BARE_DIR="$PWD/bare"
WORKING_DIR="$PWD/working"

mkdir -p $BARE_DIR/repo
cd $BARE_DIR/repo
git init --bare
  1. Change the HEAD ref:
git symbolic-ref HEAD refs/heads/very-unlikely-to-be-your-configured-default-branch
  1. Clone a working copy of the repo:
mkdir $WORKING_DIR
cd $WORKING_DIR
git clone $BARE_DIR/repo
cd repo
  1. Check the HEAD ref:
cat .git/HEAD

I expect the output to be:

ref: refs/heads/very-unlikely-to-be-your-configured-default-branch

but instead it's:

ref: refs/heads/master

Solution

  • When there are no commits, there are no branches.

    Although Git can, in modern Git, read the default branch name from the other Git, and therefore could create a new clone with the correct ref: refs/heads/name entry, Git 2.25 does not. If it did, the unborn branch in the new clone would match the unborn branch in the bare repository. This is what you'd like. But until Git 2.31.0, Git did not do that.

    If you can't upgrade, the solution is to make the repository you're cloning contain at least one commit, so that it can have an infinite number of branch names. Then create at least one branch name in that repository—though, actually, creating that first commit will create one branch name for you—and make its HEAD refer to the one desired branch name.