Change a Git remote HEAD to point to something besides master

GitGit BranchGit Remote

Git Problem Overview


How do I set a Git remote's HEAD reference to point to something besides "master"?

My project has a policy not to use a "master" branch (all branches are to have meaningful names). Furthermore, the canonical master repository is only accessible via ssh://, with no shell access (like GitHub or Unfuddle).

My problem is that the remote repository still has a HEAD reference to refs/heads/master, but I need it to point to a different branch. This is causing two problems:

  1. When cloning the repo, there this,

> warning: remote HEAD refers to nonexistent ref, unable to checkout.

That's confusing and inconvenient.

  1. The web-based code browser depends on HEAD as a basis for browsing the tree. I need HEAD to point to a valid branch, then.

Git Solutions


Solution 1 - Git

There was almost the same question on GitHub a year ago.

The idea was to rename the master branch:

git branch -m master development
git branch -m published master
git push -f origin master 

> Making master have what you want people to use, and do all other work in branches.

(a "git-symbolic-ref HEAD refs/head/published" would not be propagated to the remote repo)

This is similar to "How do I delete origin/master in Git".


As said in this thread: (emphasis mine)

> "git clone" creates only a single local branch.
To do that, it looks at the HEAD ref of the remote repo, and creates a local branch with the same name as the remote branch referenced by it. > > So to wrap that up, you have repo A and clone it: > > - HEAD references refs/heads/master and that exists
> -> you get a local branch called master, starting from origin/master > > - HEAD references refs/heads/anotherBranch and that exists
> -> you get a local branch called anotherBranch, starting from origin/anotherBranch > > - HEAD references refs/heads/master and that doesn't exist
> -> "git clone" complains > > Not sure if there's any way to directly modify the HEAD ref in a repo.

(which is the all point of your question, I know ;) )


Maybe the only way would be a "publication for the poor", where you:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

But that would involve write access to the server, which is not always possible.


As I explain in "Git: Correct way to change Active Branch in a bare repository?", git remote set-head wouldn't change anything on the remote repo.

It would only change the remote tracking branch stored locally in your local repo, in remotes/<name>/HEAD.


With Git 2.29 (Q4 2020), "git remote set-head(man)" that failed still said something that hints the operation went through, which was misleading.

See commit 5a07c6c (17 Sep 2020) by Christian Schlack (cschlack).
(Merged by Junio C Hamano -- gitster -- in commit 39149df, 22 Sep 2020)

> ## remote: don't show success message when set-head fails
> Signed-off-by: Christian Schlack

> Suppress the message 'origin/HEAD set to master' in case of an error.
> > $ git remote set-head origin -a > error: Not a valid ref: refs/remotes/origin/master > origin/HEAD set to master

Solution 2 - Git

Update: This only works for the local copy of the repository (the "client"). Please see others' comments below.

With a recent version of git (Feb 2014), the correct procedure would be:

So for example, switching the head on remote origin to branch develop would be:

Solution 3 - Git

Since you mention GitHub, to do it on their site simply go into your project, then...

admin > Default Branch > (choose something)

Done.

Solution 4 - Git

See: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

This sets the default branch in the git repository. You can run this in bare or mirrored repositories.

Usage:

$ git symbolic-ref HEAD refs/heads/<branch name>

Solution 5 - Git

(There was already basically the same question "create a git symbolic ref in remote repository", which received no universal answer.)

But there are a specific answers for various git "farms" (where multiple users can manage git repos through a restricted interface: via http and ssh): <http://Github.com>;, <http://Gitorious.org>;, <http://repo.or.cz>;, Girar (<http://git.altlinux.org>;).

These specific answers might be useful for those reading this page and thinking about these specific services.

$ ssh git.alt help | fgrep branch
default-branch <path to git repository> [<branch>]
$ 

for example ssh git.alt default-branch packages/autosshd.git sisyphus to change the HEAD in the remote repo autosshd.git to point to the sisyphus branch.

Solution 6 - Git

If you have access to the remote repo from a shell, just go into the .git (or the main dir if its a bare repo) and change the HEAD file to point to the correct head. For example, by default it always contains 'refs: refs/heads/master', but if you need foo to be the HEAD instead, just edit the HEAD file and change the contents to 'refs: refs/heads/foo'.

Solution 7 - Git

You can create a detached master branch using only porcelain Git commands:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

That gives us a master branch with a rude message (you may want to be more polite). Now we create our "real" branch (let's call it trunk in honour of SVN) and divorce it from master:

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

Hey, presto! gitk --all will show master and trunk with no link between them.

The "magic" here is that --amend causes git commit to create a new commit with the same parent as the current HEAD, then make HEAD point to it. But the current HEAD doesn't have a parent as it's the initial commit in the repository, so the new HEAD doesn't get one either, making them detached from each other.

The old HEAD commit doesn't get deleted by git-gc because refs/heads/master still points to it.

The --allow-empty flag is only needed because we're committing an empty tree. If there were some git add's after the git rm then it wouldn't be necessary.

In truth, you can create a detached branch at any time by branching the initial commit in the repository, deleting its tree, adding your detached tree, then doing git commit --amend.

I know this doesn't answer the question of how to modify the default branch on the remote repository, but it gives a clean answer on how to create a detached branch.

Solution 8 - Git

Related to the question, I ended up here when searching for:

How do I make a local repo aware of a changed default branch on GitHub

For completeness, adding the answer:

git remote set-head origin -a

Solution 9 - Git

First, create the new branch you would like to set as your default, for example:

$>git branch main

Next, push that branch to the origin:

$>git push origin main

Now when you login to your GitHub account, you can go to your repository and choose Settings>Default Branch and choose "main."

Then, if you so choose, you can delete the master branch:

$>git push origin :master

Solution 10 - Git

For gitolite people, gitolite supports a command called -- wait for it -- symbolic-ref. It allows you to run that command remotely if you have W (write) permission to the repo.

Solution 11 - Git

Simple just log into your GitHub account and on the far right side in the navigation menu choose Settings, in the Settings Tab choose Default Branch and return back to main page of your repository that did the trick for me.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJasonSmithView Question on Stackoverflow
Solution 1 - GitVonCView Answer on Stackoverflow
Solution 2 - Gitjrhorn424View Answer on Stackoverflow
Solution 3 - GitsrcspiderView Answer on Stackoverflow
Solution 4 - Gitmani-freshView Answer on Stackoverflow
Solution 5 - Gitimz -- Ivan ZakharyaschevView Answer on Stackoverflow
Solution 6 - GitsqueegeeView Answer on Stackoverflow
Solution 7 - GitkbroView Answer on Stackoverflow
Solution 8 - GitfriederbluemleView Answer on Stackoverflow
Solution 9 - Git4mnes7yView Answer on Stackoverflow
Solution 10 - GitsitaramView Answer on Stackoverflow
Solution 11 - GitMatijaView Answer on Stackoverflow