Por que estou mesclando “ramificação de rastreamento remoto 'origin / develop' into develop”?

125

Eu sou o único na minha organização que está fazendo confirmações com a seguinte mensagem:

Mesclar ramo de rastreamento remoto 'origin / develop' em develop

Não tenho certeza do que estou fazendo para causá-los, mas gostaria de parar.

Qual comando estou emitindo para criar esse commit e qual é o comando adequado que devo usar para não produzi-lo?

Jordan Feldstein
fonte
1
A resposta feita por Richard Hansen é boa. Mas acho que pode ser confuso para iniciantes. Minha solução é continuar fazendo pull --rebase, mas para evitar o perigo, eu escondo minhas alterações antes do pull. Depois, depois de puxar, aplico. Eu resolvo conflitos. Finalmente eu posso comprometer e empurrar.
JohnJohn
Faz git pull --autostash --rebaseo trabalho para você @Johnjohn?
sourcedelica

Respostas:

206

git pullprovavelmente está criando o commit. Se você fizer uma confirmação local e depois executar git pulldepois que outra pessoa enviar uma confirmação para o repositório, o Git fará o download da confirmação do outro desenvolvedor e a mesclará na sua filial local.

Como evitar esses commits de mesclagem no futuro

Você pode usar git pull --rebasepara impedir que isso aconteça no futuro, mas o rebaseamento tem seus perigos, e eu recomendo evitar pullcompletamente .

Em vez disso, recomendamos que você siga este padrão de uso:

# download the latest commits
git remote update -p

# update the local branch
git merge --ff-only @{u}

# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}

Explicação

  • git remote update -pbaixa todas as confirmações nos repositórios remotos e atualiza as ramificações de rastreamento remoto (por exemplo, origin/master). NÃO toca no diretório de trabalho, índice ou ramificações locais.

    As -pameixas do argumento excluíram ramos upstream. Assim, se o fooramo for excluído no originrepositório, git remote update -pele excluirá automaticamente sua origin/fooreferência.

  • git merge --ff-only @{u}diz ao Git para mesclar a ramificação upstream (o @{u}argumento) em sua ramificação local, mas somente se sua ramificação local puder ser "encaminhada rapidamente" para a ramificação upstream (em outras palavras, se não tiver divergido).

  • git rebase -p @{u}move efetivamente os commits que você fez, mas ainda não colocou no topo da ramificação upstream, o que elimina a necessidade de criar os commits parvos de mesclagem que você está tentando evitar. Isso melhora a linearidade do histórico de desenvolvimento, facilitando a revisão.

    A -popção diz ao Git para preservar mesclagens. Isso evita que o Git linearize os commits sendo rebased. Isso é importante se, por exemplo, você mesclou uma ramificação de recurso master. Sem -p, todo commit no ramo do recurso seria duplicado mastercomo parte da linearização feita por git rebase. Isso dificultaria a revisão do histórico de desenvolvimento, não mais fácil.

    Cuidado : git rebasepode não fazer o que você espera, então revise os resultados antes de pressionar. Por exemplo:

    git log --graph --oneline --decorate --date-order --color --boundary @{u}..
    

Prefiro essa abordagem git pull --rebasepelos seguintes motivos:

  • Ele permite que você veja os commits upstream recebidos antes de modificar seu histórico para incorporá-los.
  • Ele permite que você passe a opção -p( --preserve-merges) para o git rebasecaso de precisar refazer uma mesclagem intencional (por exemplo, mesclagem de uma ramificação de recurso já enviada para master).

Taquigrafia: em git upvez degit pull

Para facilitar o procedimento acima, recomendo criar um alias chamado up:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

Agora, tudo o que você precisa fazer para atualizar sua filial é executar:

git up

em vez de git pull. Se você receber um erro porque sua filial local divergiu da filial upstream, essa é sua sugestão para refazer a ação.

Por que não git pull --rebase?

Corrida git pull --rebaseé equivalente a corrida git fetchseguida por git rebase. Isso tenta avançar rapidamente para as novas confirmações upstream, mas se isso não for possível, ele rebase suas confirmações locais para as novas confirmações upstream. Isso geralmente é bom, mas tenha cuidado:

  • Rebase é um tópico avançado e você deve entender as implicações antes de rebasear.
  • git pull --rebasenão lhe dá a oportunidade de examinar os commits antes de incorporá-los. Dependendo do que a montante mudou, é bem possível que rebase é a operação de um erro rebase --onto, merge, resetou push -fpode ser mais apropriado do que uma planície rebase.
  • Não é (atualmente) possível passar --preserve-mergespara a operação de rebase, portanto, qualquer mesclagem intencional de uma ramificação de recurso será linearizada, reproduzindo (e, portanto, duplicando) todas as confirmações de ramificação de característica.

"Corrigindo" uma consolidação de mesclagem existente criada por git pull

Se você ainda não enviou uma confirmação de mesclagem criada por git pull, é possível recuperar novamente a confirmação de mesclagem. Supondo que você não tenha feito nenhuma fusão intencional (por exemplo, mesclando uma ramificação de recurso já enviada à sua ramificação atual), faça o seguinte:

git rebase @{u}

O comando acima informa ao Git para selecionar todos os commits de não mesclagem alcançáveis HEAD(o commit atual), menos todos os commits alcançáveis @{u}(que é uma abreviação de "o ramo upstream", isto é, origin/masterse HEADhouver master), reproduzir novamente (cherry-pick ) na parte superior da ramificação upstream e, em seguida, mova a referência da ramificação atual para apontar para o resultado da reprodução das confirmações. Isso efetivamente move as confirmações de não mesclagem para a confirmação upstream mais recente, o que elimina a mesclagem criada por git pull.

Se você tem uma consolidação intencional de mesclagem, não deseja executar, git rebase @{u}porque ela reproduzirá tudo da outra ramificação. Lidar com esse caso é substancialmente mais complicado, e é por isso que é bom usar git upe evitar git pullcompletamente. Você provavelmente precisará usar resetpara desfazer a mesclagem criada por pulle depois fazer git rebase -p @{u}. O -pargumento git rebasenão funcionou de maneira confiável para mim; portanto, você pode acabar tendo que resetdesfazer a mesclagem intencional, atualizar sua ramificação local @{u}e depois refazer a mesclagem intencional (que é uma dor se houver muitas mesclagens peludas conflitos).

Richard Hansen
fonte
+1 para discutir --preserve-mescla, exceto que você realmente não documentou isso nos comandos que você disse para ele executar, então -1 para isso.
Seth Robertson
@ Seth: Obrigado pelo comentário; Eu atualizei a resposta para recomendar -p. Evitei recomendá-lo antes porque não é necessário com muita frequência e seu comportamento não está bem documentado.
Richard Hansen
3
Qual a diferença entre git remote update -pe git fetch?
Eckes
3
@ Checkes: git remote update -pé o mesmo que git fetch --all -p. Eu tinha o hábito de usar de git remote update -pvolta quando fetchnão tinha a -popção.
Richard Hansen
1
@ user1914692: Quando a mesclagem estiver concluída, o Git atualizará a ramificação local para apontar para a consolidação de mesclagem recém-criada, não para a mesma consolidação da ramificação remota. Esse novo commit de mesclagem é o problema, principalmente quando enviado por push.
Richard Hansen
18
git fetch
git rebase origin/master

Isso deve resolver. Ou se você quiser continuar usando pull

git pull --rebase

Você também pode configurar essa ramificação na sua configuração para se recuperar automaticamente, ou ser configurada dessa maneira automaticamente para quaisquer outras ramificações de rastreamento futuras que você criar. Então você pode voltar a usar apenas

git pull

Mais sobre isso na seção "puxar com rebase em vez de mesclar" desta página:

http://mislav.uniqpath.com/2010/07/git-tips/

Adam Dymitruk
fonte