Alterar um HEIT remoto do Git para apontar para algo além do mestre


124

Como faço para definir a referência HEAD de um controle remoto do Git para apontar para algo além de "master"?

Meu projeto tem uma política para não usar uma ramificação "principal" (todas as ramificações devem ter nomes significativos). Além disso, o repositório principal canônico é acessível apenas via ssh: //, sem acesso ao shell (como GitHub ou Unfuddle).

Meu problema é que o repositório remoto ainda tem uma referência HEAD para refs / heads / master, mas preciso que aponte para um ramo diferente. Isso está causando dois problemas:

  1. Ao clonar o repositório, aí está,

    aviso: HEAD remoto refere-se a referência inexistente, incapaz de efetuar o checkout.

    Isso é confuso e inconveniente.

  2. O navegador de código baseado na Web depende do HEAD como base para navegar na árvore. Preciso HEAD para apontar para um ramo válido, então.


Acabei de adicionar uma possibilidade para o registro, mas não é adequado para o seu caso.
VonC 28/09/09

Truque "nenhum ancestral comum": interessante. Você pode publicá-la como uma resposta detalhada e selecioná-la como a oficial, se a encontrar funcionando.
VonC 28/09/09

12
FWIW, desde que você mencionou o GitHub na pergunta - se você deseja alterar a referência HEAD no GitHub, basta ir para a tela "Admin" do repositório e alterar o menu suspenso "Default Branch" para qualquer ramo que você deseja que o HEAD aponte.
31512 Joe


Respostas:


63

Havia quase a mesma pergunta no GitHub há um ano.

A ideia era renomear o ramo principal:

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

Tornar o mestre o que você quer que as pessoas usem e fazer todo o trabalho nas filiais.

(um " git-symbolic-ref HEAD refs/head/published" não seria propagado para o repositório remoto)

É semelhante a " Como faço para excluir a origem / mestre no Git ".


Como dito neste tópico : (ênfase minha)

" git clone" cria apenas uma única ramificação local.
Para fazer isso, ele analisa o HEAD refrepositório remoto e cria uma filial local com o mesmo nome da filial remota referenciada por ele.

Então, para finalizar, você repo A e clona:

  • HEADreferências refs/heads/mastere que existe
    -> você obtém uma ramificação local chamada mestre, iniciando na origem / mestre

  • Referências HEAD refs/heads/anotherBranche que existem
    -> você recebe um ramo local chamado anotherBranch, começando emorigin/anotherBranch

  • Referências HEAD refs/heads/mastere isso não existe
    -> "git clone" reclama

Não tenho certeza se há alguma maneira de modificar diretamente a HEADref em um repo .

(qual é o ponto principal da sua pergunta, eu sei;))


Talvez a única maneira seja uma "publicação para os pobres" , onde você:

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

Mas isso envolveria acesso de gravação ao servidor, o que nem sempre é possível.


Como explico em " Git: maneira correta de alterar o Active Branch em um repositório vazio? ", git remote set-headNão mudaria nada no repositório remoto.

Somente alteraria a filial de rastreamento remoto armazenada localmente em seu repositório local, em remotes/<name>/HEAD.


Obrigado, VonC. Eu li isso antes de postar aqui. Mas como você pode ver, um ramo chamado "mestre" não é bem-vindo neste projeto por razões técnicas e políticas.
28909 JasonSmith

Em seguida, você pode impor essa política, proibindo qualquer atualização na ramificação mestre por meio de um gancho de pré-confirmação.
VonC 28/09/09

Sim, se não houver como fazer o que quero, farei exatamente isso e aceitarei sua resposta. Obrigado por acompanhar!
28409 JasonSmith

Obrigado pela atualização. No momento, usei o truque "não-ancestral comum" para criar um ramo principal com apenas um commit. (Ou seja: git branch -D master; ref echo: refs / heads / master> .git / HEAD; rm *). Depois, toquei em um arquivo chamado GO_AWAY e a mensagem de confirmação explica a situação. Isso vai funcionar por enquanto. Posso verificar a fonte e rastrear onde o lado receptor define HEAD para uma resposta final.
28909 JasonSmith

1
@ctn Isso é simplesmente porque eu esqueci a opção -f( --force). Eu editei a resposta de acordo. Então, a resposta que você faz referência usa a mesma opção.
VonC

42

Atualização: Isso funciona apenas para a cópia local do repositório (o "cliente"). Veja os comentários de outras pessoas abaixo.

Com uma versão recente do git (fevereiro de 2014), o procedimento correto seria:

git remote set-head $REMOTE_NAME $BRANCH

Por exemplo, alternar a cabeça do controle remoto originpara o ramo developseria:

git remote set-head origin develop


Esse recurso precisa da versão recente do git no servidor ou é suficiente se a máquina cliente tiver o git recente instalado?
Mikko Rantalainen

3
@ Motor é conciso, mas certo; esta resposta deve ser reduzida. O Git tem esse conceito um tanto confuso de "ramificação local padrão para o controle remoto". Ele permite que você digite "origin" em vez de "origin / defaultbranch" e é uma coisa pura do lado do cliente . Longa história em git-scm.com/docs/git-remote # set-head
MarcH

1
para confirmar do que @MarchH está falando: execute git checkout -b default; git push origin HEAD; git remote set-head origin default. Você pode inspecionar as alterações locais com cat .git/refs/remotes/origin/HEAD(deveria ser ref: refs/remotes/origin/default) e a falta de alterações remotas com git remote show origin(ainda será o que era antes de você adicionar a ramificação padrão).
De Novo

37

Desde que você mencionou o GitHub, para fazê-lo no site deles simplesmente entre no seu projeto, então ...

admin > Default Branch > (choose something)

Feito.


1
Excelente! Essa foi a última parte que faltava.
Berkus

Minha origem / HEAD já aponta para um ramo de recurso em vez de mestre. Tentei mudar o "ramo principal" para frente e para trás, mas isso não afetou a CABEÇA ... Alguma sugestão?
Daniil Shevelev

3
Configurações> Ramos> Poder Padrão
Chun Yang

12

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

Isso define a ramificação padrão no repositório git. Você pode executar isso em repositórios vazios ou espelhados.

Uso:

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

6
$ Git simbólico-ref refs cabeça / cabeça / nome-de-branch
Lamy

Fiz isso no meu repositório remoto e corrigi meus problemas de clonagem, onde por algum motivo o cabeçalho era outro nome de filial e, portanto, tentar clonar o mestre resultaria em um erro ao tentar fechar o mestre no compositor, isso pode ser muito específico para esse cenário , mas outros podem estar nessa posição e se perguntando o que fazer
Christopher Thomas

10

(Já havia basicamente a mesma pergunta " criar uma referência simbólica git no repositório remoto ", que não recebeu resposta universal.)

Mas existem respostas específicas para vários "farms" do git (onde vários usuários podem gerenciar repositórios git através de uma interface restrita: via http e ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org ).

Essas respostas específicas podem ser úteis para quem lê esta página e pensa sobre esses serviços específicos.


4
Agora eles têm um menu suspenso para selecionar a ramificação HEAD em repo.or.cz (exemplo: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) e gitorious.org , também. Ótimo!
imz - Ivan Zakharyaschev

7

Se você tiver acesso ao repositório remoto a partir de um shell, basta acessar o .git (ou o diretório principal, se for um repositório simples) e alterar o arquivo HEAD para apontar para o cabeçalho correto. Por exemplo, por padrão, ele sempre contém 'refs: refs / heads / master', mas se você precisar que foo seja o HEAD, basta editar o arquivo HEAD e alterar o conteúdo para 'refs: refs / heads / foo'.


Eu tenho direitos de administrador no servidor Git e fiz exatamente o mesmo. Nós usamos o Gitolite e eu fui ao repositório que eu criei. O nome do diretório é myrepo.git. O conteúdo do arquivo HEAD no diretório especificado foi alterado de ref: refs/heads/masterpara ref: refs/heads/mainline. Agora, quando tento clonar o repositório na minha caixa local, ele ainda aponta para o mestre. Eu executei o git clone ssh://gitolite@git.server/myrepocomando. Alguma idéia para esse comportamento?
Technext

Versão do servidor Git: git version 1.7.1& versão do cliente Git:git version 1.9.4.msysgit.2
Technext

5

Você pode criar uma ramificação principal desanexada usando apenas comandos Git em porcelana:

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

Isso nos dá uma ramificação principal com uma mensagem rude (você pode ser mais educado). Agora criamos nosso ramo "real" (vamos chamá-lo de tronco em homenagem ao SVN) e o divorciamos do mestre :

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

Ei, pronto! gitk --all mostrará mestre e tronco sem nenhum link entre eles.

A "mágica" aqui é que --amend faz com que o git commit crie um novo commit com o mesmo pai que o HEAD atual e faça HEAD apontar para ele. Mas o HEAD atual não tem um pai, pois é o commit inicial no repositório, portanto, o novo HEAD também não recebe um, tornando-os separados um do outro.

O commit antigo HEAD não é excluído pelo git-gc porque refs / heads / master ainda aponta para ele.

O sinalizador --allow-empty é necessário apenas porque estamos comprometendo uma árvore vazia. Se houvesse algum add do git após o git rm , não seria necessário.

Na verdade, você pode criar uma ramificação desanexada a qualquer momento, ramificando o commit inicial no repositório, excluindo sua árvore, adicionando sua árvore desanexada e executando o git commit --amend .

Sei que isso não responde à pergunta de como modificar a ramificação padrão no repositório remoto, mas fornece uma resposta clara sobre como criar uma ramificação desanexada.


1
Você pode criar uma ramificação desanexada mais facilmente, buscando uma ramificação não relacionada de outro repositório e dando um nome a ela. Por exemplo, git fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADadicionará uma nova ramificação detached-branchque corresponda à ramificação remote-branch-nameno controle remoto git:user@example.com:foo. Obviamente, o "remoto" pode ser um repositório no sistema de arquivos local que você preparou anteriormente.
Mikko Rantalainen 26/03

2

Primeiro, crie o novo ramo que você deseja definir como padrão, por exemplo:

$>git branch main

Em seguida, empurre esse ramo para a origem :

$>git push origin main

Agora, quando você faz login na sua conta do GitHub, pode ir ao seu repositório e escolher Configurações> Filial Padrão e escolher " principal ".

Então, se você escolher, poderá excluir o ramo principal:

$>git push origin :master


O ponto principal a entender é que, se o provedor de hospedagem (GitHub neste exemplo) não fornecer um método para modificar a ramificação padrão, você estará sem sorte. O protocolo Git não fornece um recurso para modificar a ramificação padrão remota; você precisaria executar git symbolic-refno shell remoto ou modificar o arquivo de texto chamado HEADno diretório raiz do repositório remoto.
Mikko Rantalainen 26/03

2

Relacionado à pergunta, acabei aqui ao pesquisar:

Como informar um repositório local sobre uma ramificação padrão alterada no GitHub

Para completar, adicione a resposta:

git remote set-head origin -a

0

Para pessoas gitolitas, o gitolita suporta um comando chamado - aguarde - symbolic-ref. Ele permite que você execute esse comando remotamente se você tiver permissão W (gravação) no repositório.


-1

Simples, basta acessar sua conta do GitHub e, no lado direito do menu de navegação, escolher Configurações , na guia Configurações, escolha Filial padrão e retornar à página principal do seu repositório que fez o truque para mim.


1
Embora ele mostre o novo ramo como padrão na interface do GitHub, ao fazer um clone do git [repo], não estou obtendo esse ramo. ie .git / HEAD contém a referência incorreta.
Joseph Sheedy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.