Pergunta

Eu tenho o ramo master que rastreia o ramo remoto origin/master.

Eu quero renomeá -los para master-old localmente e no controle remoto. Isso é possível? Para outros usuários que rastrearam origin/master (e quem sempre atualizou seus locais master ramificação via git pull), o que aconteceria depois que eu renomeei a filial remota? Seria o deles git pull ainda funcionar ou causaria um erro que não conseguiu encontrar origin/master não mais?

Então, mais adiante, quero criar um novo master ramificação (local e controle remoto). Novamente, depois que eu fiz isso, o que aconteceria agora se os outros usuários fizessem git pull?

Eu acho que tudo isso resultaria em muitos problemas. Existe uma maneira limpa de conseguir o que eu quero? Ou devo simplesmente sair master como é e crie um novo ramo master-new e apenas trabalhar lá mais adiante?

Foi útil?

Solução

A coisa mais próxima de renomear é excluir e depois recriar no controle remoto. Por exemplo:

git branch -m master master-old
git push remote :master         # delete master
git push remote master-old      # create master-old on remote

git checkout -b master some-ref # create a new local master
git push remote master          # create master on remote

No entanto, isso tem muitas advertências. Primeiro, nenhum caixa existente saberá sobre a renomear - o git faz não Tente rastrear renomeamentos de ramificação. Se o novo master Ainda não existe, o git pull erra. Se o novo master foi criado. A atração tentará se fundir master e master-old. Portanto, geralmente é uma má idéia, a menos que você tenha a cooperação de todos que fizeram o check -out do repositório anteriormente.

Nota: As versões mais recentes do Git não permitirão excluir a filial mestre remotamente por padrão. Você pode substituir isso definindo o receive.denyDeleteCurrent valor de configuração para warn ou ignore no controlo remoto repositório. Caso contrário, se você estiver pronto para criar um novo mestre imediatamente, pule o git push remote :master passo e passe --force para o git push remote master degrau. Observe que, se você não conseguir alterar a configuração do controle remoto, não poderá excluir completamente o ramo principal!

Esta ressalva se aplica apenas ao ramo atual (geralmente o master ramo); Qualquer outro ramo pode ser excluído e recriado como acima.

Outras dicas

Supondo que você esteja atualmente master:

git push origin master:master-old        # 1
git branch master-old origin/master-old  # 2
git reset --hard $new_master_commit      # 3
git push -f origin                       # 4
  1. Primeiro faça um master-old ramo no origin repositório, com base no master comprometer no repositório local.
  2. Crie uma nova filial local para este novo origin/master-old ramificação (que será configurada automaticamente corretamente como uma ramificação de rastreamento).
  3. Agora aponte seu local master Para qualquer comprometimento que você queira apontar.
  4. Finalmente, mudança de força master no origin repositório para refletir seu novo local master.

(Se você fizer isso de outra maneira, precisará de pelo menos mais uma etapa para garantir que master-old está configurado corretamente para rastrear origin/master-old. Nenhuma das outras soluções publicadas no momento da redação deste artigo incluem isso.)

Com o Git v1.7, acho que isso mudou um pouco. Atualizar a referência de rastreamento da filial local para o novo controle remoto agora é muito fácil.

git branch -m old_branch new_branch         # Rename branch locally    
git push origin :old_branch                 # Delete the old branch    
git push --set-upstream origin new_branch   # Push the new branch, set local branch to track the new remote
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name

Você pode ter que mudar manualmente para new-branch-name antes de excluir old-branch-name

Existem muitas maneiras de renomear o ramo, mas vou me concentrar no maior problema: "Como permitir que os clientes sejam velozes e não precisam mexer com seus ramos localmente".

Primeiro uma imagem rápida:renaming master branch and allowing clients to fast-forward

Isso é algo realmente fácil de fazer; Mas não abuse. Toda a ideia depende de cometidos de mesclagem; como eles permitem avançar rapidamente e vincular histórias de um ramo com outro.

renomear o ramo:

# rename the branch "master" to "master-old"
# this works even if you are on branch "master"
git branch -m master master-old

Criando o novo ramo "mestre":

# create master from new starting point
git branch master <new-master-start-point>

Criando uma mesclagem se compromete a ter um histórico de pai-filho:

# now we've got to fix the new branch...
git checkout master

# ... by doing a merge commit that obsoletes
# "master-old" hence the "ours" strategy.
git merge -s ours master-old

e pronto.

git push origin master

Isso funciona porque criando um merge Commit permite Avanço rápido o ramo para uma nova revisão.

Usando uma mensagem sensata de compromisso de fusão:

renamed branch "master" to "master-old" and use commit ba2f9cc as new "master"
-- this is done by doing a merge commit with "ours" strategy which obsoletes
   the branch.

these are the steps I did:

git branch -m master master-old
git branch master ba2f9cc
git checkout master
git merge -s ours master-old

Estou assumindo que você ainda está perguntando sobre a mesma situação que em seu pergunta anterior. Ou seja, o Master-New não conterá a Mestre-Old em sua história. Isso não importa Como as Você entra em um estado em que o mestre não é descendente de uma posição anterior de mestre, simplesmente que está nesse estado.

Outros usuários que tentam puxar enquanto o mestre não existem simplesmente terão suas falhas (não é esse ref em controle remoto) e, uma vez que existir novamente em um novo lugar, seus puxões terão que tentar mesclar seu mestre com o novo mestre remoto, Como se você tivesse fundido o mestre-mestre e o mestre-novo em seu repositório. Dado o que você está tentando fazer aqui, a mesclagem teria conflitos. (Se eles fossem resolvidos e o resultado foi empurrado de volta ao repositório, você estaria em um estado ainda pior - ambas as versões da história lá.)

Para responder sua pergunta simplesmente: você deve aceitar que às vezes haverá erros em sua história. Esta certo. Isso acontece com todos. Existem commits revertidos no repositório git.git. O importante é que, uma vez que publicamos a história, é algo que todos podem confiar.

*Se o fizesse, isso seria equivalente a empurrar algumas alterações no mestre e, em seguida, criar um novo ramo onde costumava estar. Sem problemas.

o resposta selecionada falhou quando eu tentei. Ele lança um erro: refusing to delete the current branch: refs/heads/master. Acho que vou postar o que funciona para mim:

git checkout master             # if not in master already

git branch placeholder          # create placeholder branch
git checkout placeholder        # checkout to placeholder
git push remote placeholder     # push placeholder to remote repository

git branch -d master            # remove master in local repository
git push remote :master         # remove master from remote repository.

O truque é fazer o check -out para o espaço reservado antes de empurrá -lo para o repositório remoto. O resto é auto -explicativo, excluir o ramo principal e empurrá -lo ao repositório remoto deve funcionar agora. Extraído de aqui.

Bom. Meus 2 centavos. Que tal fazer login no servidor, ir ao diretório Git e renomear a ramificação no repositório nu. Isso não tem todos os problemas associados à reuppliação do mesmo ramo. Na verdade, os 'clientes' reconhecerão automaticamente o nome modificado e alterarão sua referência remota. Depois (ou antes), você também pode modificar o nome local da filial.

A respeito:

git checkout old-branch-name
git push remote-name new-branch-name
git push remote-name :old-branch-name
git branch -m new-branch-name

Esta é a maneira mais simples e mais 'legível' que conheço:

Filial Local 'Move' usando -m

git branch -m my_old_branch_name my_new_branch_name

Empurre o ramo 'movido' para o controle remoto, configurado 'upstream' usando -u

git push origin -u my_new_branch_name

(Configurando 'Upstream' essencialmente 'conecta' sua filial local ao controle remoto, para que coisas como buscar, puxar e empurrar funcionarão)

Exclua o ramo antigo do controle remoto

git push origin -D <old_name>

(Sua filial local já se foi, porque você 'moveu' na 1ª etapa)

Você pode fazer o seguinte:

git -m master master-old #rename current master
git checkout -b master   #create a new branch master
git push -f origin master #force push to master

Mas a força de força é uma má idéia se outras pessoas estiverem compartilhando esse repositório. Force Push fará com que seu histórico de revisão entre em conflito com o novo.

OK, renomeando um ramo ambos localmente e em o remoto é muito fácil! ...

Se você estiver no ramo, poderá fazer facilmente:

git branch -m <branch>

Ou se não, você precisa fazer:

git branch -m <your_old_branch> <your_new_branch>

Em seguida, empurre a exclusão para o controle remoto assim:

git push origin <your_old_branch>

Agora você terminou, se você receber um erro rio acima enquanto tenta pressionar, basta fazer:

git push --set-upstream origin <your_new_branch>

Eu também crio a imagem abaixo para mostrar as etapas na linha de comando real, basta seguir as etapas e você seria bom:

enter image description here

O seguinte pode ser salvo no script do shell para fazer o trabalho:

Por exemplo:

remote="origin"

if [ "$#" -eq 0 ] # if there are no arguments, just quit
then
    echo "Usage: $0 oldName newName or $0 newName" >&2
    exit 1
elif
    [ "$#" -eq 1 ] # if only one argument is given, rename current branch
then 
    oldBranchName="$(git branch | grep \* | cut -d ' ' -f2)" #save current branch name
    newBranchName=$1
else
    oldBranchName=$1
    newBranchName=$2
fi

git branch -m $oldBranchName $newBranchName

git push $remote :$oldBranchName #delete old branch on remote
git push --set-upstream $remote $newBranchName # add new branch name on remote and track it

Observe que aqui o nome remoto padrão "Origin" é codificado, você pode estender o script para fazer se configurável!

Em seguida, esse script pode ser usado com aliases do Bash, aliases git ou, por exemplo, ações personalizadas de Sourcetree.

Eu acredito que a chave é a percepção de que você está realizando um em dobro Renomear: master para master-old e também master-new para master.

De todas as outras respostas, sintetizei o seguinte:

doublerename master-new master master-old

onde primeiro temos que definir o doublerename Função Bash:

# doublerename NEW CURRENT OLD
#   - arguments are branch names
#   - see COMMIT_MESSAGE below
#   - the result is pushed to origin, with upstream tracking info updated
doublerename() {
  local NEW=$1
  local CUR=$2
  local OLD=$3
  local COMMIT_MESSAGE="Double rename: $NEW -> $CUR -> $OLD.

This commit replaces the contents of '$CUR' with the contents of '$NEW'.
The old contents of '$CUR' now lives in '$OLD'.
The name '$NEW' will be deleted.

This way the public history of '$CUR' is not rewritten and clients do not have
to perform a Rebase Recovery.
"

  git branch --move $CUR $OLD
  git branch --move $NEW $CUR

  git checkout $CUR
  git merge -s ours $OLD -m $COMMIT_MESSAGE

  git push --set-upstream --atomic origin $OLD $CUR :$NEW
}

Isso é semelhante a uma mudança de história git rebase na medida em que o conteúdo da filial é bem diferente, mas difere para que os clientes ainda possam avançar com segurança com git pull master.

git update-ref newref oldref
git update-ref -d oldref newref
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top