8

This is remote Git repository on server

[aaa@web48 proj.git]$ git ls-remote .
dfca707432eb53678b37026b160a4bdc7f1ac6c3    HEAD
dfca707432eb53678b37026b160a4bdc7f1ac6c3    refs/heads/master
1e09c37443ee758644a712e3c1a8b08b18a1f50d    refs/heads/placeholder

I want to delete HEAD/master branch. How can I do it either on server or remotely? I'm using Tower client.

Pablo
  • 28,133
  • 34
  • 125
  • 215
  • `HEAD` is a symbolic reference on the remote repo that points to the default branch on the remote. I'm not sure, off the top of my head, that you can just delete it or the branch that it points to (master), but I'll need to double check that later. –  Jul 13 '14 at 09:26
  • 1
    so that's probably what I want to know - how to unassign default branch and how to switch default branch. – Pablo Jul 13 '14 at 09:29
  • I can tell you how to do that from the command line, if you want. I'm not sure if it's possible with Tower. –  Jul 13 '14 at 09:30
  • 1
    Please provide information about what is running the server. Are you using GitHub as a remote? Then you can switch the default branch in the settings of the repository and afterwards `git push origin :master` to delete the master branch (deleting from Tower should work at that time too). Deleting `HEAD` is just not possible as it is - like @Cupcake said - only a link to the latest commit. – Knut Jul 13 '14 at 09:32
  • 1
    @Cupcake I will be glad to try command line solution from server. – Pablo Jul 13 '14 at 09:33
  • 1
    @Knut I'm not using GitHub as remote. It's `Git` installed on my web hosting serving as a remote. It is strange about latest commit, because I certainly have a test repo, a test branch where I have commits, but it's not a default branch and there is no HEAD on remote. So repo may or may not have that symbolink link, right? Subquestion is how/when this symbolic link made? Second question is how to switch to other branch. Assuming once HEAD link created, there is no way to delete it. – Pablo Jul 13 '14 at 09:39
  • So how did it turn out, did my answer solve your problem? –  Jul 15 '14 at 02:38
  • @Cupcake plz give me some time to try that as I have to gain access to that server again :) – Pablo Jul 15 '14 at 07:38

2 Answers2

17

You cannot delete a remote branch if it's currently the default HEAD branch

The HEAD symbolic reference on a remote bare repo represents the default branch for that repo. Any non-bare clones of that repo will automatically checkout that branch after the clone.

Because it's the default, you can't just delete it like you normally would, Git won't let you:

$ git push origin --delete master

remote: error: By default, deleting the current branch is denied, because the next
remote: error: 'git clone' won't result in any file checked out, causing confusion.
remote: error:
remote: error: You can set 'receive.denyDeleteCurrent' configuration variable to
remote: error: 'warn' or 'ignore' in the remote repository to allow deleting the
remote: error: current branch, with or without a warning message.
remote: error:
remote: error: To squelch this message, you can set it to 'refuse'.
remote: error: refusing to delete the current branch: refs/heads/master
To c:/Users/Keoki/Documents/GitHub/bare
 ! [remote rejected] master (deletion of the current branch prohibited)
error: failed to push some refs to 'c:/Users/Keoki/Documents/GitHub/bare'

The error message above points out that you can bypass the safety checks to delete the current HEAD branch in the remote anyways, but I'm going to show you how to change what the default branch is, so that you can still keep a default branch, but delete master like you wanted to.

Changing the default HEAD branch from the command line

You can change what the default branch is in the remote repo if you have access to the remote. If you're using a hosting provider like GitHub or Bitbucket, they should allow you to change the default branch through their web interface.

So if you have access to the remote, use the following command to change which branch the symbolic reference HEAD points to:

git symbolic-ref HEAD refs/heads/<newDefaultBranch>

Changing the default HEAD branch on GitHub or Bitbucket

As I've already mentioned in the previous section, you can update the default HEAD branch in your remote repo through the web interface if you use a hosting provide like GitHub or Bitbucket.

GitHub

Go to your repo's Settings tab, and you'll see the default branch setting right at the top,

GitHub settings

Bitbucket

Got to your repo's Settings tab, and you'll see the default branch setting near the middle,

Bitbucket settings

Update your local clones' references to the default branch in the remote

Once you've updated the default branch in the remote bare repo, you'll need to update where your local clones of that repo think that the default HEAD branch in the remote points to. You can do that with

git remote set-head <remote> --auto

# Or shorter
git remote set-head <remote> -a

You can confirm that the local repo has been properly updated using

$ git branch -r
  origin/HEAD -> origin/foo
  origin/foo
  origin/master

Now you can delete the master branch on the remote

Now that you've changed the default HEAD branch on the remote to be something other than the master branch, you'll be able to delete it on the remote,

$ git push origin --delete master

To c:/Users/Keoki/Documents/GitHub/bare
 - [deleted]         master

# Older syntax
$ git push origin :master

Additional References and Documentation

Community
  • 1
  • 1
  • This indeed solved the issue and I was able to switch from master to different branch. The whole answer is very broad and useful. I have one last question - indeed I have few repos, where the HEAD branch is NOT defined. At which point this HEAD branch is created and if it's defined, how can I undefine HEAD? Thank you – Pablo Jul 18 '14 at 21:32
  • @Pablo you're better off just asking another question `;)` I'm not going to be able to give you a suitable answer at this time, I would have to do some research later that I just don't have time to do. –  Jul 18 '14 at 21:37
  • @Pablo for what it's worth, I think you might be able to use [`git symbolic-ref`](https://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html) again to delete the `HEAD` reference in a bare repo, but I'm not sure if that's a good idea off the top of my head, I don't remember if there are any negative consequences to doing so. –  Jul 18 '14 at 21:39
2

Note: while you cannot indeed delete the default HEAD branch, you could, until Git 2.11 (Q4 2016) delete HEAD itself!

symbolic-ref -d: do not allow removal of HEAD

See commit 12cfa79 (02 Sep 2016) by Junio C Hamano (gitster).
(Merged by Junio C Hamano -- gitster -- in commit d1de693, 12 Sep 2016)

"git symbolic-ref -d HEAD" happily removes the symbolic ref, but the resulting repository becomes an invalid one.
Teach the command to forbid removal of HEAD.

If you delete the symbolic-ref HEAD from a repository, Git no longer considers the repository valid, and even "git symbolic-ref HEAD refs/heads/master" would not be able to recover from that state
(although "git init" can, but that is a sure sign that you are talking about a "broken" repository).

In the spirit similar to afe5d3d ("symbolic ref: refuse non-ref targets in HEAD", 2009-01-29), forbid removal of HEAD to avoid corrupting a repository.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250