Se houver um repositório ao qual eu tenha git://acesso apenas (e normalmente apenas pressione + puxe), existe uma maneira de renomear ramificações nesse repositório da mesma maneira que faria localmente git branch -m?
A pergunta "duplicada" vinculada pede para renomear um ramo "local e remoto". Essa pergunta, no entanto, pergunta apenas como renomear ramificações remotamente, o que permite uma simplificação. Isto é o que eu faço para mudar o nome de uma filial no servidor sem a necessidade de checkout e / ou criar uma filial local: git push origin origin/old_name:refs/heads/new_name && git push origin :old_name.
sschuberth
1
@sschuberth: você pode dar os dois comandos de uma só vez. E essa realmente deve ser a resposta para essa pergunta.
Joachim Breitner
2
@JoachimBreitner Você está certo, eu já fiz essa otimização neste script meu.
precisa saber é o seguinte
1
@sschuberth, você deve postar seu comentário como resposta, já que eu gosto mais do que os outros abaixo.
Então, para ver o antigo nome da filial, cada cliente do repositório teria que fazer:
$ git fetch origin
$ git remote prune origin
NOTA: Se o seu ramo antigo é o ramo principal, você deve alterar as configurações principais do ramo. Caso contrário, ao executar $ git push origin :old-branch-name, você receberá o erro "exclusão da ramificação atual proibida" .
Bem, se os nomes antigos e novos são os mesmos, significa que você não precisa renomear a ramificação; portanto, não há sentido em executar o comando em primeiro lugar ;-)
Sylvain Defresne
9
Certo. Quero apenas dizer que, se você está chamando isso de forma automatizada (como parte de algum outro script), é possível que não faça a coisa errada se puder evitá-la.
Mysterious Dan
9
O jeito de Dan: reordene os comandos para que eles sempre funcionem. Maneira do Earth Engine: lembre-se sempre de verificar ou você perde dados. Eu sei qual escolheria.
Doradus 27/10
2
Os usuários podem simplesmente executar: git fetch origin --prune(para buscar efetivamente as novas ramificações e também se livrar das referências que não estão mais no controle remoto).
DolphinDream 19/02
2
Pode usar -dou em --deletevez de :nas versões mais recentes do git.
Zitrax
285
Se você realmente deseja renomear ramificações remotamente, sem renomear nenhuma ramificação local ao mesmo tempo , faça isso com um único comando:
Eu escrevi este script ( git-rename-remote-branch ) que fornece um atalho útil para fazer o que foi dito facilmente.
Como uma função bash:
git-rename-remote-branch(){if[ $# -ne 3 ]; then
echo "Rationale : Rename a branch on the server without checking it out."
echo "Usage : $(basename $0) <remote> <old name> <new name>"
echo "Example : $(basename $0) origin master release"
exit 1fi
git push $1 $1/$2:refs/heads/$3 :$2
}
Para integrar o comentário do @ ksrb : O que isso basicamente faz são dois toques em um único comando, primeiro git push <remote> <remote>/<old_name>:refs/heads/<new_name>para enviar uma nova ramificação remota com base na ramificação de rastreamento remoto antiga e depois git push <remote> :<old_name>excluir a ramificação remota antiga.
Para aqueles que desejam um apelido para esse comando: rename = "! F () {origem do git push origin / $ 1: refs / heads / $ 2: $ 1;}; f" isso pode ser usado como> git rename <old_name> < new_name>
Jonathan Schmidt
33
Para aqueles curiosos sobre o que esse comando realmente significa, basicamente, são 2 git push <remote>/<old_name>:refs/heads/<new_name>git push [space]:<old_name>
pushs
3
Por que você precisa usar refs/heads/name? Você não pode simplesmente usar namediretamente, fazendo o primeiro comando git push <remote> <remote>/<old_name>:<new_name>?
Drew Noakes
6
Não, porque a ramificação remota <new_name>ainda não existe. Se a ramificação não existir, o Git exigirá que você use o nome completo, caso contrário, <new_name>também poderá se referir a um nome de tag.
sschuberth
3
Usamos essa abordagem em nosso sistema de compilação. A única ressalva que encontramos é se refs/heads/<new_name> já existe. A exclusão ainda é bem-sucedida, resultando <remote>/<old_name>apenas na exclusão. Algumas verificações antes da mão podem facilmente evitar isso.
Apeiron
172
Primeiro faça o checkout no ramo que você deseja renomear:
Ao enviar o ramo renomeado (new_branch) para remoto (origem), você também deve configurá-lo para rastrear o ramo com o novo nome (por exemplo git push -u origin new_branch), caso contrário, o ramo renomeado (new_branch) continuará a rastrear o origin / old_branch. E depois que você excluir o old_branch remoto, o new_branch ainda rastreará a origem / old_branch, embora agora que a ramificação se foi.
DolphinDream 19/02
@ DolphinDream Editei a resposta para incluir sua alteração útil no upstream.
MVChr 15/09/16
10
Certo. Apenas renomeie a ramificação localmente, envie a nova ramificação e exclua a antiga.
O único problema real é que outros usuários do repositório não terão as ramificações de rastreamento local renomeadas.
então, ao tentar excluir o master, tentei o clone $ git ../src $ cd src $ filial git notmaster $ git checkout notmaster $ filial git -d mestre $ git push ../src: master Mas reclama: O destino refspec não corresponde a uma referência existente no controle remoto nem começa com refs /, e não podemos adivinhar um prefixo com base na fonte ref. erro: falha ao enviar algumas referências para '../alpha/' O controle remoto realmente tem uma ramificação chamada master
kdt
2
TL; DR
"Renomear" uma ramificação remota é na verdade um processo de duas etapas (não necessariamente solicitado):
exclusão da ramificação remota antiga ( git push [space]:<old_name>como o ksrb explicou );
envie para uma nova ramificação remota (diferença entre alguns comandos de respostas abaixo).
Excluindo
Eu uso o TortoiseGit e quando tentei excluir o ramo pela linha de comando, obtive o seguinte:
$ git push origin :in
fatal: 'origin' não parece ser um repositório git
fatal: Não foi possível ler do repositório remoto.
Verifique se você possui os direitos de acesso corretos e se o repositório existe.
Isso provavelmente ocorreu devido ao concurso não ter a chave privada carregada (que o TortoiseGit carrega automaticamente no concurso ). Além disso, notei que os comandos do TortoiseGit não possuem a originreferência neles (por exemplo git.exe push --progress "my_project" interesting_local:interesting).
Também estou usando o Bitbucket e, como outros gerenciadores de git on-line baseados na Web (GitHub, GitLab), pude excluir a ramificação remota diretamente através de sua interface (página de ramificações):
No entanto, no TortoiseGit, você também pode excluir ramificações remotas através de Browse References :
Ao clicar com o botão direito do mouse em uma ramificação remota (lista de controles remotos), a opção Excluir ramificação remota é exibida:
Empurrando
Após excluir a ramificação remota antiga, enviei diretamente para uma nova ramificação remota através do TortoiseGit, apenas digitando o novo nome no campo Remote: da janela Push e essa ramificação foi criada e visível automaticamente no Bitbucket .
No entanto, se você ainda preferir fazê-lo manualmente, um ponto que ainda não foi mencionado neste segmento é que -u= --set-upstream.
git push origin -u new_branch= git push -u new_branch
da descrição do documento :
Se a configuração estiver ausente, o padrão será origin.
No final, eu não digitei manualmente ou usei nenhum dos comandos sugeridos pelas outras respostas aqui, então talvez isso possa ser útil para outras pessoas em uma situação semelhante.
o problema é que seu controle remoto não é chamado origin. Você precisa nomear o seu controle remoto ao executá-lo git remote. O Git funciona com o sshque implica que você está usando chaves públicas + privadas. Eu assumo que oAutoload Putty keys TortoiseGit esteja apenas carregando automaticamente as chaves necessárias para que você faça qualquer coisa com sua referência remota. A última coisa é que git push -unão é um alias para enviar para uma ramificação remota, é um alias para enviar para uma ramificação remota que foi criada localmente e sua referência remota ainda não tem essa ramificação .
juanecabellob
1
@juancab -ué um pseudônimo de --set-upstream"se a configuração estiver ausente, o padrão seráorigin ". Sylvain e Shashank usam isso para enviar para um ramo remoto recém-criado . O principal problema pode ter sido devido ao concurso não ter carregado quando tentei git push origin :inno shell. Portanto, não entendo seu voto negativo, apenas apontei os meus e os detalhes não endereçados em outras respostas, expliquei-os e resolvi-os.
CPHPython
Você está afirmando coisas erradas e grande parte dessa resposta não tem relação com a pergunta em si. Se você está apontando o que funcionou para você, encorajo-o a limitar a resposta ao que funcionou e se você realmente deseja dar uma explicação, informe-se melhor. Btw: -ué um apelido para, --set-upstreammas não um apelido para enviar para um ramo remoto, como você disse. Para entrar em uma ramificação remota, você precisa exclusivamente git push <remote>e, se ainda não estiver na remota, adicione git push -u <remote>. Portanto, -ué usado para criar uma referência da ramificação no controle remoto.
juanecabellob
1
@juancab talvez o que você considera errado foi principalmente o apelido fraseado ou escolha de palavras. Reestruturei minha resposta e reformulei-a para fornecer uma explicação completa das soluções que encontrei para renomear uma filial remota.
CPHPython
Eu reformularia ainda mais. Faz mais sentido agora, mas ainda é muito longo. Eu seria mais específico ao problema, ou seja, afirmo que para os usuários do TortoiseGit as soluções propostas não funcionarão. Você está contando uma história, isso é confuso e faz com que os usuários evitem ler. Vou editar sua resposta com uma proposta.
juanecabellob
1
Não sei por que, mas a resposta de @Sylvain Defresne não funciona para mim.
Não sei se isso está certo ou errado, mas coloquei o "nome antigo" do ramo no "novo nome" do ramo e excluí o ramo antigo inteiramente com as duas linhas a seguir:
Além das respostas já fornecidas, aqui está uma versão que primeiro verifica se o novo ramo já existe (para que você possa usá-lo com segurança em um script)
if git ls-remote --heads "$remote" \
| cut -f2 \
| sed 's:refs/heads/::' \
| grep -q ^"$newname"$; then
echo "Error: $newname already exists"
exit 1
fi
git push "$oldname" "$remote/$oldname:refs/heads/$newname" ":$oldname"
git push origin origin/old_name:refs/heads/new_name && git push origin :old_name
.Respostas:
Você só precisa criar uma nova ramificação local com o nome desejado, enviá-la para o controle remoto e excluir a ramificação remota antiga:
Então, para ver o antigo nome da filial, cada cliente do repositório teria que fazer:
NOTA: Se o seu ramo antigo é o ramo principal, você deve alterar as configurações principais do ramo. Caso contrário, ao executar
$ git push origin :old-branch-name
, você receberá o erro "exclusão da ramificação atual proibida" .fonte
git fetch origin --prune
(para buscar efetivamente as novas ramificações e também se livrar das referências que não estão mais no controle remoto).-d
ou em--delete
vez de:
nas versões mais recentes do git.Se você realmente deseja renomear ramificações remotamente, sem renomear nenhuma ramificação local ao mesmo tempo , faça isso com um único comando:
Eu escrevi este script ( git-rename-remote-branch ) que fornece um atalho útil para fazer o que foi dito facilmente.
Como uma função bash:
Para integrar o comentário do @ ksrb : O que isso basicamente faz são dois toques em um único comando, primeiro
git push <remote> <remote>/<old_name>:refs/heads/<new_name>
para enviar uma nova ramificação remota com base na ramificação de rastreamento remoto antiga e depoisgit push <remote> :<old_name>
excluir a ramificação remota antiga.fonte
git push <remote>/<old_name>:refs/heads/<new_name>
git push [space]:<old_name>
refs/heads/name
? Você não pode simplesmente usarname
diretamente, fazendo o primeiro comandogit push <remote> <remote>/<old_name>:<new_name>
?<new_name>
ainda não existe. Se a ramificação não existir, o Git exigirá que você use o nome completo, caso contrário,<new_name>
também poderá se referir a um nome de tag.refs/heads/<new_name>
já existe. A exclusão ainda é bem-sucedida, resultando<remote>/<old_name>
apenas na exclusão. Algumas verificações antes da mão podem facilmente evitar isso.Primeiro faça o checkout no ramo que você deseja renomear:
Para remover uma ramificação antiga de
remote
:fonte
git push -u origin new_branch
), caso contrário, o ramo renomeado (new_branch) continuará a rastrear o origin / old_branch. E depois que você excluir o old_branch remoto, o new_branch ainda rastreará a origem / old_branch, embora agora que a ramificação se foi.Certo. Apenas renomeie a ramificação localmente, envie a nova ramificação e exclua a antiga.
O único problema real é que outros usuários do repositório não terão as ramificações de rastreamento local renomeadas.
fonte
TL; DR
"Renomear" uma ramificação remota é na verdade um processo de duas etapas (não necessariamente solicitado):
git push [space]:<old_name>
como o ksrb explicou );Excluindo
Eu uso o TortoiseGit e quando tentei excluir o ramo pela linha de comando, obtive o seguinte:
Isso provavelmente ocorreu devido ao concurso não ter a chave privada carregada (que o TortoiseGit carrega automaticamente no concurso ). Além disso, notei que os comandos do TortoiseGit não possuem a
origin
referência neles (por exemplogit.exe push --progress "my_project" interesting_local:interesting
).Também estou usando o Bitbucket e, como outros gerenciadores de git on-line baseados na Web (GitHub, GitLab), pude excluir a ramificação remota diretamente através de sua interface (página de ramificações):
No entanto, no TortoiseGit, você também pode excluir ramificações remotas através de Browse References :
Ao clicar com o botão direito do mouse em uma ramificação remota (lista de controles remotos), a opção Excluir ramificação remota é exibida:
Empurrando
Após excluir a ramificação remota antiga, enviei diretamente para uma nova ramificação remota através do TortoiseGit, apenas digitando o novo nome no campo Remote: da janela Push e essa ramificação foi criada e visível automaticamente no Bitbucket .
No entanto, se você ainda preferir fazê-lo manualmente, um ponto que ainda não foi mencionado neste segmento é que
-u
=--set-upstream
.Nos
git push
documentos ,-u
é apenas um alias de--set-upstream
, portanto, os comandos nas respostas de Sylvain (-set-upstream new-branch
) e Shashank (-u origin new_branch
) são equivalentes, já que a referência remota é padronizada comoorigin
se nenhuma outra referência foi definida anteriormente:git push origin -u new_branch
=git push -u new_branch
da descrição do documento :No final, eu não digitei manualmente ou usei nenhum dos comandos sugeridos pelas outras respostas aqui, então talvez isso possa ser útil para outras pessoas em uma situação semelhante.
fonte
origin
. Você precisa nomear o seu controle remoto ao executá-logit remote
. O Git funciona com ossh
que implica que você está usando chaves públicas + privadas. Eu assumo que oAutoload Putty keys
TortoiseGit esteja apenas carregando automaticamente as chaves necessárias para que você faça qualquer coisa com sua referência remota. A última coisa é quegit push -u
não é um alias para enviar para uma ramificação remota, é um alias para enviar para uma ramificação remota que foi criada localmente e sua referência remota ainda não tem essa ramificação .-u
é um pseudônimo de--set-upstream
"se a configuração estiver ausente, o padrão seráorigin
". Sylvain e Shashank usam isso para enviar para um ramo remoto recém-criado . O principal problema pode ter sido devido ao concurso não ter carregado quando tenteigit push origin :in
no shell. Portanto, não entendo seu voto negativo, apenas apontei os meus e os detalhes não endereçados em outras respostas, expliquei-os e resolvi-os.-u
é um apelido para,--set-upstream
mas não um apelido para enviar para um ramo remoto, como você disse. Para entrar em uma ramificação remota, você precisa exclusivamentegit push <remote>
e, se ainda não estiver na remota, adicionegit push -u <remote>
. Portanto,-u
é usado para criar uma referência da ramificação no controle remoto.Não sei por que, mas a resposta de @Sylvain Defresne não funciona para mim.
Eu tenho que desconfigurar o upstream e então posso definir o stream novamente. A seguir, é como eu fiz isso.
fonte
Não sei se isso está certo ou errado, mas coloquei o "nome antigo" do ramo no "novo nome" do ramo e excluí o ramo antigo inteiramente com as duas linhas a seguir:
fonte
Você pode criar uma nova ramificação com base na ramificação de nome antigo. Assim, exclua a ramificação antiga !!!
fonte
Além das respostas já fornecidas, aqui está uma versão que primeiro verifica se o novo ramo já existe (para que você possa usá-lo com segurança em um script)
(a verificação é desta resposta )
fonte
git show-ref --quiet --verify -- refs/heads/$new_name
vez dels-remote | cut | sed | grep
.