Git: Correct way to change Active Branch in a bare repository?
Asked Answered
J

7

242

I have a bare repository that's used as the central store for my project. All the developers do git clone <repo> to share with it. When they do the clone, they get a checkout of the master branch (unless they do git clone -n) because repo.git/HEAD contains ref: refs/heads/master, making this the Active Branch.

The question is, how do I change the Active Branch properly? I could simply hack the repo.git/HEAD file directly, but that seems nasty and, well, hacky.

I tried doing git checkout <otherbranch> in the repo .git directory, but that failed because I wasn't in a work tree.

I tried git update-ref HEAD refs/heads/otherbranch but that just updated refs/heads/master to be the same as refs/heads/otherbranch (okay, I did that one in a dummy repository, not my production one!)

I tried git update-ref --no-deref HEAD refs/heads/otherbranch and that almost worked. It updated the HEAD file, but it set it to the SHA1 of the commit pointed to by refs/heads/otherbranch.

I'm testing with git version 1.7.0.2.msysgit.0.

I'm guessing there's no way to do this through git push, as allowing all and sundry to change your default branch seems a bit unsafe (!), but surely there's a better way to do it in the repo .git directory than directly hacking the HEAD file.

Jackanapes answered 21/7, 2010 at 17:15 Comment(6)
IMO you're just fundamentally trying to do The Wrong Thing here. If you want the default branch to be something other than master, then that branch needs to be the master. Alternatively, use two different repositories.Marlinemarlinespike
How is this fundamentally trying to do the wrong thing here? A bare repository supports multiple branches. I use a bare repository as back-up to my local repository, and as such mirror the branches. I have a master on both and a development branch on both. If I want to see the log of the development branch on the bare repository, I have to hack files - seems like git is fundamentally wrong here with regard to bare repository support.Tarragona
@NicholasKnight IMHO you're fundamentally wrong here. There is nothing special about "master" as a branch name, it's just a default. In the respositories that maintain we don't have a master branch, as "master" is not meaningful to the company. Whenever we do a release we create a new maintenance branch with the new release number, and assign that as the active branch.Ander
@NicholasKnight While I appreciate where you're coming from, this is the first SO Q/A that's told me how to switch to master! I had my initial repo on a feature branch when I made my bare clone, and subsequent clones from that bare repo were defaulting to that branch instead of master.Baugh
Wow - this question just runs and runs - it's my number 1 reputation point scorer! The thing about "master" is that it's just a name, and if it doesn't make sense for your organisation, team, project, phase, whatever, then choose something that IS appropriate so that when you collaborators clone your repo they immediately switch to the branch that you, as Configuration Manager, want them to be on. I used to work with ClearCase (bletch!) so your choices were "main", "main" or "main". Yuk.Jackanapes
Does this answer your question? Change a Git remote HEAD to point to something besides masterValdovinos
H
352

If you have access to the remote bare repo, this article suggests:

git symbolic-ref HEAD refs/heads/mybranch

Which will update the HEAD file in your repository so that it contains:

ref: refs/heads/mybranch

as documented in the git-symbolic-ref


If you don't have access to the remote repo, see my previous answer.


Remember that a command like git remote set-head:

  • doesn't change the default branch of the remote repo.
    It only changes a remote tracking branch stored in your local repo as refs/remotes/<name>/HEAD

  • doesn't change HEAD itself (again, only refs/remotes/<name>/HEAD), hence the need for git symbolic-ref.

So git remote set-head is not the answer here.
git symbolic-ref HEAD is, if you have direct access to the remote repo.

Hyphenated answered 21/7, 2010 at 17:22 Comment(8)
Thanks! I do have direct access to the remote bare repo so git-symbolic-ref will do the job. I like the no-common-ancestor trick mentioned on the other thread, though - definitely one for the bottom drawer. I spent ages Googling for this but couldn't find your previous answer, yet "git remote head master" finds it as the second-highest ranked hit, just below git-remote(1). Bizarre. Just goes to show how hard it is to find something when you don't know exactly what you're looking for.Jackanapes
git symbolic-ref HEAD refs/heads/mybranch worked just fine for me! THANKS! ;)Degreeday
I really appreciate this question, because I accidentally checked out a different branch than master and now I had to fix that.Panter
This doesn't work for me. Oddly, even though the remote HEAD in the bare repo now shows the correct branch, git STILL defaults me to a different branch when I clone from it!Trait
@Trait that would be a good question of its own to ask in a new page.Hyphenated
@Hyphenated good idea. #26897394Trait
This answer was very helpful to me, but one thing wasn't clear: After changing the HEAD on my bare remote with git symbolic-ref, how do I update clones to reflect the bare remote's new HEAD? If I create a new clone of the bare remote, its default checkout and history correctly reflects the new HEAD. But existing clones' git log output still show the remote's old HEAD, even after various tries with git fetch and git pull.Obligate
@NickWilliams Good question, not sure actually, beside changing locally origin/HEAD.Hyphenated
M
9

To change the branch you need to change HEAD reference to the branch you want to use.

First list all the references in the bare repository by doing

$find ref

Then find the reference for your branch, the format will be as follows refs/heads/<my_branch>. So next step is to check current reference, just type:

$git symbolic-ref HEAD

so you know which is the current branch then update it as needed.

$git symbolic-ref HEAD refs/heads/<my_branch>

That's it. Enjoy.

Mercerize answered 6/10, 2016 at 1:39 Comment(0)
S
4

How to change the Active Branch properly ?

  • status: git checkout in the repo .git directory returns fatal: This operation must be run in a work tree

  • tips: just add the --work-tree argument

detailed example : assumptions: bare git on remote server:

~/bare_git_repository.git detached work tree: /var/www/myappremote

on local server: create branch version.1.7 (our otherbranch)

git branch version.1.7

git push origin version.1.7

on the remote server with git bare repo:

$ cd ~/bare_git_repository.git

$ git branch

  • master
    version.1.7

As stated,following command

git checkout version.1.7

return

fatal: This operation must be run in a work tree

Using the following command

git --work-tree=/var/www/myappremote checkout version.1.7

successfully change the Active Branch propely

$ git branch

master

  • version.1.7

check the results with the following

ll /var/www/myappremote

hope it will help

Syllabus answered 30/12, 2019 at 22:39 Comment(1)
This very simple solution worked for me, thanks! One note: I had to create an empty work-tree directory by hand for the command to execute successfully.Multure
E
1

At least at v.2.35.3, git symbolic-ref HEAD refs/heads/otherbranch no longer results in a file refs/heads/otherbranch. Instead it is silently added to .packed-refs and if there are no commits, to HEAD.git symbolic-ref HEAD will report silently from all.

See git help pack-refs

Epicedium answered 30/7, 2022 at 18:10 Comment(0)
S
-1

Also, if you don't have access to the bare repository, by doing a git remote set-head and you are done

See this previous response

Szymanski answered 20/3, 2014 at 4:19 Comment(0)
S
-3

I compared two directories before and after applying

git symbolic-ref HEAD refs/heads/mybranch

and it appears that only repo.git/HEAD file was changed so probably it is quite safe just to "hack" the file.

Silvester answered 16/4, 2011 at 6:58 Comment(4)
There are subtle breaking problems that can be introduced by directly editing Git ref files. I highly recommend against that. The plumbing commands are easier and safer than directly editing refs.Visual
What's the advantage of this @boryn?Ribonuclease
Git keeps track of a lot of things in the background like a history of refs. If you manually change the file then it won't get logged. It is true that it probably won't matter. But if you lose track of some commits and want to find them, you'll be happier if you didn't just "hack" the file.Reentry
I used the command. But this answer was helpful to understand how it works, and, in partucular, to understand that refs/heads is something internal and I should not change it, only the last part of the "path". So, I voted up because I think it was valuable information after all.Warfare
F
-3

I also have a bare repo on our server and was able to successfully retrieve files using

git clone //server/repo/directory -b branch_name

into a new local repository even though the manpage says this is only for non-bare repositories.

Firepower answered 18/12, 2015 at 21:3 Comment(1)
While what you say is true, the fact that you're using -b to select a particular branch breaks your answer in the context of my question, which is how do you set the DEFAULT branch.Jackanapes

© 2022 - 2024 — McMap. All rights reserved.