Atualizar ramificações Git do mestre

674

Eu sou novo no Git e agora estou nessa situação:

  • Eu tenho quatro ramos (mestre, b1, b2 e b3).
  • Depois de trabalhar no b1-b3, percebi que havia algo para mudar no mestre de ramificação que deveria estar em todas as outras ramificações.
  • Eu mudei o que eu precisava mastere ... aqui está o meu problema:

Como atualizo todas as outras ramificações com o mastercódigo da ramificação?

Ionuț Staicu
fonte
3
Encontrei minha resposta aqui: Como você mescla arquivos seletivos com o git-merge?
Wjandrea 18/10
58
Mais uma tarefa simples dificultada pelo Git. Os desenvolvedores do Git devem usar o Stack Overflow como feedback em seu loop SDLC. 300.000 pessoas devem indicar que algo está seriamente errado no fluxo de trabalho do Git. Eles precisam contratar um especialista em UX, porque claramente não conseguem fazer isso por conta própria.
JWW

Respostas:

619

Você tem duas opções:

O primeiro é uma mesclagem, mas isso cria uma confirmação extra para a mesclagem.

Faça checkout em cada filial:

git checkout b1

Em seguida, mesclar:

git merge origin/master

Em seguida, pressione:

git push origin b1

Como alternativa, você pode fazer uma nova rebase:

git fetch
git rebase origin/master
Chris Kooken
fonte
14
Eu tenho uma preocupação com essa abordagem. Quando executo o git log --graph, o gráfico mostra que o mestre está realmente mesclado à ramificação do tópico. Isso causará algum problema a longo prazo? Eu pensei que a melhor prática é sempre mesclar o ramo do tópico de volta ao mestre. Por favor comente.
Patrick
2
Procure esse problema se você estiver usando o fluxo de trabalho de mesclagem: randyfay.com/node/89
Hampus Ahlgren
22
Você está mesclando o mestre no b1. Por que você got push origin master... não faz sentido. Você não está mudando o ramo principal. Eu acho que é um erro com 119 votos anteriores: /
Yves Lange
22
Não use o método de mesclagem, usando git rebase masteré a resposta correta
Weston Ganger
6
Para aqueles de nós que lemos mais tarde - a preocupação de @Kursion sobre o erro de digitação foi abordada pela edição do autor. Além disso, a segunda resposta mais votada abaixo diz basicamente a mesma coisa que essa resposta, mas com um diagrama da estrutura da ramificação e um aviso sobre o motivo pelo qual você não gostaria de se recuperar.
beyondtheteal
494

Você tem basicamente duas opções:

  1. Você se funde. Na verdade, isso é bastante simples e uma operação perfeitamente local:

    git checkout b1
    git merge master
    # repeat for b2 and b3
    

    Isso deixa o histórico exatamente como aconteceu: você partiu do mestre, fez alterações em todos os ramos e, finalmente, incorporou as mudanças do mestre nos três ramos.

    gitPara lidar com essa situação muito bem, ele foi projetado para mesclagens acontecendo em todas as direções, ao mesmo tempo. Você pode confiar que poderá reunir todos os threads corretamente. Simplesmente não se importa se o branch b1mescla masterou mastermescla b1, o commit de mesclagem parece igual ao git. A única diferença é que ramo acaba apontando para esse commit de mesclagem.

  2. Você se rebase. Pessoas com um SVN ou experiência semelhante acham isso mais intuitivo. Os comandos são análogos ao caso de mesclagem:

    git checkout b1
    git rebase master
    # repeat for b2 and b3
    

    As pessoas gostam dessa abordagem porque ela mantém uma história linear em todos os ramos. No entanto, essa história linear é uma mentira, e você deve estar ciente de que é. Considere este gráfico de confirmação:

    A --- B --- C --- D <-- master
     \
      \-- E --- F --- G <-- b1
    

    A mesclagem resulta na história verdadeira:

    A --- B --- C --- D <-- master
     \                 \
      \-- E --- F --- G +-- H <-- b1
    

    A rebase, no entanto, fornece esse histórico:

    A --- B --- C --- D <-- master
                       \
                        \-- E' --- F' --- G' <-- b1
    

    O ponto é que os commits E', F'e G'nunca realmente existiram e provavelmente nunca foram testados. Eles podem até não ser compilados. Na verdade, é muito fácil criar confirmações sem sentido via rebase, especialmente quando as alterações mastersão importantes para o desenvolvimento b1.

    A conseqüência disso pode ser que você não consegue distinguir qual dos três commits E, Fe Grealmente introduziu uma regressão, diminuindo o valor degit bisect .

    Não estou dizendo que você não deveria usar git rebase. Tem seus usos. Mas sempre que você o usa, precisa estar ciente do fato de estar mentindo sobre a história. E você deve pelo menos compilar o teste que os novos commits.

cmaster - restabelece monica
fonte
Eu estava fundindo outro ramo fonte (não master) e medidas adicionais para adicionar a esta resposta agradável foi para atualizá-lo no meu repo local antes da fusão (para ter a última versão do código localmente): git checkout <source branch> git pull. Continuando com o acima: git checkout b1...
Rod
3
Como usuário de longa data do SVN, prefiro a opção de mesclagem do que rebase: usando qualquer controle de versão, é muito, muito importante manter registros precisos das alterações feitas e por quê. Eu posso ver o apelo da rebase para simplificar o histórico aparente, mas você deve voltar e adicionar aos comentários de confirmação de E ', F', G '- e, de preferência, adicionar a rebase automaticamente a esses comentários. Caso contrário, se o processo de compilação / teste / implantação de teste for interrompido, você precisará descobrir por que as alterações foram feitas sem informações completas.
achou
12
A história é uma mentira
piratemurray
Obrigado, eu uso "git merge any-branch-name" para mesclar um código de filial para outra filial. Localmente eu posso testar o código de ramo 1, enquanto eu estou no ramo 2
Priti
1
@blamb Os conflitos de mesclagem acontecem com ambos git mergee git rebase. Não há como evitar isso. git rebasetem a vantagem de permitir ocultar vários estágios de rebaseamento (ou seja, rebaseando o mesmo ramo em vários commits diferentes em sequência para reduzir a quantidade de conflitos em cada estágio). No entanto, o simples fato de uma rebase estar mentindo sobre a história torna muito mais fácil foder bem em uma rebase de vários estágios ... É por isso que eu sempre prefiro a mesclagem, mesmo quando isso significa que eu preciso desordenar a história com vários commits de mesclagem .
cmaster - reinstate monica
238

git rebase masteré a maneira correta de fazer isso. A mesclagem significaria que uma consolidação seria criada para a mesclagem, enquanto a reestruturação não seria.

Michael J. Gray
fonte
52
E quando você já tiver empurrado para a origem, se você fizer uma nova reformulação, reescreverá o histórico de consolidação e isso entrará em conflito com sua ramificação remota. Eu acho que o rebase só deve ser usado em um pull ou quando você não for enviado para um ramo remoto.
Matt Smith
6
Se você é o único que trabalha na ramificação remota, pode executar o recurso de origem git push --force para atualizar sua ramificação remota com ramificação local rebaseada. stackoverflow.com/questions/8939977/…
stormwild 15/07/2013
7
rebase e mesclar ambos os trabalhos, o rebase é melhor para ramificações privadas, porque fornece um gráfico de histórico mais limpo. esta resposta é a melhor
Junchen Liu
5
Precisa ser mais claro sobre o compromisso entre clareza (ideal para um usuário ou equipe pequena) ou verdade confusa (para ramos de código com vários contribuidores - necessários para manutenção (na minha experiência - YMMV)).
WillC
1
re "e se você já empurrou?" -> A regra de ouro do git rebase é nunca usá-lo em agências públicas .
Trevor Boyd Smith
53

Se você estiver trabalhando em uma ramificação de vez em quando, ou muita coisa aconteceu em outras ramificações enquanto estiver trabalhando em alguma coisa, é melhor refazer sua ramificação para mestre. Isso mantém a história organizada e facilita muito o acompanhamento.

git checkout master
git pull
git checkout local_branch_name
git rebase master
git push --force # force required if you've already pushed

Notas:

  • Não rebase as ramificações nas quais você colaborou com outras pessoas.
  • Você deve refazer a ramificação na qual você estará mesclando, que nem sempre é mestre.

Há um capítulo sobre rebasing em http://git-scm.com/book/ch3-6.html e muitos outros recursos disponíveis na web.

Simon Bingham
fonte
Obrigado pela solução simples
outro Tall guy
18

A @cmaster fez a melhor resposta elaborada. Em resumo:

git checkout master #
git pull # update local master from remote master
git checkout <your_branch>
git merge master # solve merge conflicts if you have`

Você não deve reescrever o histórico da ramificação, mas mantê-los no estado real para referências futuras. Ao mesclar para o mestre, ele cria um commit extra, mas isso é barato. Confirma não custa.

lua Azul
fonte
13

Para atualizar outras ramificações como (backup) com sua cópia da ramificação principal. Você pode seguir de qualquer maneira (rebase ou mesclagem) ...

  1. Faça o rebase (não haverá nenhuma confirmação extra feita na ramificação de backup).
  2. Mesclar ramificações (haverá uma confirmação extra automaticamente na ramificação de backup).

    Nota: Rebase nada mais é do que estabelecer uma nova base (uma nova cópia)

git checkout backup
git merge master
git push

(Repita para outras ramificações, se houver, como backup2 & etc ..,)

git checkout backup
git rebase master
git push

(Repita para outras ramificações, se houver, como backup2 & etc ..,)

Sundar Gsv
fonte
9

Você pode mesclar ou aplicar confirmações individuais nas ramificações usando git cherry-pick .

Brian Agnew
fonte
1

Existem duas opções para esse problema.

1) git rebase

2) fusão do git

Somente diff acima de ambos em caso de mesclagem, terá confirmação extra no histórico

1) ramo de verificação geral do git (b1, b2, b3)

2) origem / mestre do git rebase (no caso de conflitos serem resolvidos localmente, fazendo o git rebase --continue)

3) git push

Como alternativa, a opção git merge é semelhante

1) git checkout "your_branch" (b1, b2, b3)

2) mestre de mesclagem git

3) git push

kris
fonte
0

para atualizar sua filial do mestre:

  git checkout master
  git pull
  git checkout your_branch
  git merge master
D_Oghli
fonte