Change a Git remote HEAD to point to something besides master
Asked Answered
L

12

138

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.

  2. 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.

Lubricate answered 28/9, 2009 at 5:42 Comment(6)
Just added one possibility for the record, but not suitable for your case.Jackal
"no-common-ancestor" trick: interesting. You could post it as a detailed answer and select it as the official one if you find it working.Jackal
FWIW, since you mentioned GitHub in the question -- if you want to change the HEAD ref on GitHub, just go to the repository's "Admin" screen, and change the "Default Branch" dropdown to whatever branch you want HEAD to point to.Assumed
See also help.github.com/articles/…Shluh
possible duplicate of create a git symbolic ref in remote repositoryCop
A better asked question with a very good accepted answer is Git: Correct way to change Active Branch in a bare repository?, if you are on a repo where you have command-line access. For a repo on a hosting service, see https://mcmap.net/q/12020/-change-a-git-remote-head-to-point-to-something-besides-master below.Cageling
J
69

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 all besides the 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
Jackal answered 28/9, 2009 at 5:49 Comment(6)
Thanks, VonC. I read that before posting here. But as you can see, a branch called "master" is unwelcome in this project for technical and policy reasons.Lubricate
You could then enforce that policy by disallowing any update on master branch through a pre-commit hook.Jackal
Yes, if it turns out that there is no way to do what I want then I will do exactly that and accept your answer. Thanks for following up!Lubricate
Thanks for the update. For the moment, I used the "no-common-ancestor" trick to make a master branch with only one commit. (I.e.: git branch -D master; echo ref: refs/heads/master > .git/HEAD; rm *). Then I just touched a file called GO_AWAY, and commit message explains the situation. That will work for now. I may check through the source and track down where the receiving side sets HEAD for a final answer.Lubricate
This gave me a 'non-fast-forward' error. The only way I was able to do it was using the answer here: superuser.com/a/749412/399381Debonair
@Debonair That is simply because I forgot the -f (--force) option. I have edited the answer accordingly. Then answer you reference does use that same option.Jackal
F
54

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:

git remote set-head $REMOTE_NAME $BRANCH

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

git remote set-head origin develop

Flotation answered 1/3, 2014 at 2:34 Comment(3)
Does this feature need recent version of git on the server or is it enough if client machine has recent git installed?Dextral
@Totor is terse but right; this answer should be downvoted. Git has this somewhat confusing concept of a "local, default branch for the remote". It lets you type "origin" instead of "origin/defaultbranch" and is a pure client-side thing. Long story at git-scm.com/docs/git-remote #set-headUnderstandable
to confirm what @MarchH is talking about: run git checkout -b default; git push origin HEAD; git remote set-head origin default. You can then inspect the local changes with cat .git/refs/remotes/origin/HEAD (it should be ref: refs/remotes/origin/default), and the lack of remote changes with git remote show origin (it will still be whatever it was before you added the default branch).Monoploid
T
36

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

admin > Default Branch > (choose something)

Done.

Touchwood answered 22/6, 2012 at 6:30 Comment(4)
Excellent! That was the last missing bit.Antilebanon
My origin/HEAD already points to a feature branch instead of master. I tried changing "main branch" back and forth, but it did not affect the HEAD... Any suggestions?Cirone
Settings > Branches > Default BranchRoseannroseanna
Changing the default branch in Gitlab/Github, does NOT change the remotes/origin/HEAD -> origin/master pointerSkuld
E
24

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>
Encephalo answered 9/11, 2010 at 13:48 Comment(2)
$ git symbolic-ref HEAD refs/heads/name-of-branchTrefor
I did this in my remote repo and it fixed my problems cloning where for some reason the head was another branch name and therefore trying to clone master would result in an error whilst trying to close master in composer, this might be very specific to this scenario, but others might be in that position and wondering what to doSclerometer
G
11

(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.

Gustaf answered 3/6, 2010 at 1:8 Comment(1)
Now they have a drop-down menu for selecting the HEAD branch at repo.or.cz (example: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) and gitorious.org , too. Great!Gustaf
O
8

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'.

Octopus answered 3/10, 2011 at 16:24 Comment(2)
I have admin rights on Git server and i did exactly the same. We use Gitolite and i went to the repository which i created. The directory name is myrepo.git. The content of HEAD file in the given directory was changed from ref: refs/heads/master to ref: refs/heads/mainline. Now, when i try to clone the repository on my local box, it still points to master. I ran git clone ssh://[email protected]/myrepo command. Any idea for such behaviour?Lovelovebird
Git server version: git version 1.7.1 & Git client version: git version 1.9.4.msysgit.2Lovelovebird
P
6

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.

Piperonal answered 22/7, 2010 at 14:14 Comment(1)
You can create a detached branch easier by fetching an unrelated branch from another repo and giving it a name. For example, git fetch git:[email protected]:foo remote-branch-name && git checkout -b detached-branch FETCH_HEAD will add new branch detached-branch that matches the branch remote-branch-name in remote git:[email protected]:foo. Of course, the "remote" can be a repository in local file system you have previously prepared.Dextral
W
6

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
Wade answered 13/9, 2019 at 6:23 Comment(1)
git remote set-head origin <branch>Mcginnis
E
2

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

Exenterate answered 21/12, 2012 at 18:5 Comment(1)
The key point to understand is that if you hosting provider (GitHub in this example) does not provide a method for modifying default branch, you're out of luck. Git protocol does not provide a feature to modify the remote default branch; you would need to be able to run git symbolic-ref on the remote shell or otherwise able to modify text file called HEAD in the remote repository root directory.Dextral
P
0

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.

Paronychia answered 30/11, 2012 at 3:55 Comment(0)
D
0

The best and straight-forward way to change git remote HEAD is to run

git remote set-head origin DEV

origin is usually the remote name DEV the remote branch name

Dermoid answered 21/5, 2022 at 22:40 Comment(0)
B
-1

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.

Buttock answered 27/1, 2013 at 18:44 Comment(1)
While it shows the new branch as the default in the GitHub interface, when doing a git clone [repo], I'm not getting that branch. i.e. .git/HEAD contains the wrong ref.Liddie

© 2022 - 2024 — McMap. All rights reserved.