o comando git rebase tem uma reputação de ser um GIT mágico voodoo do qual os iniciantes devem ficar longe, mas pode realmente tornar a vida muito mais fácil para uma equipa de desenvolvimento quando usado com cuidado. Neste artigo, vamos comparar git rebase com o relacionado git merge comando e identificar todas as oportunidades potenciais para incorporar rebasing no fluxo de trabalho típico do Git.,

Visão geral Conceitual

a primeira coisa A entender sobre git rebase é que ele resolve o mesmo problema, como git merge. Ambos os comandos são projetados para integrar mudanças de um branch em outro branch – eles apenas fazem isso de maneiras muito diferentes.

considere o que acontece quando você começa a trabalhar em uma nova funcionalidade em um ramo dedicado, então outro membro da equipe atualiza o master branch com novos commits. Isto resulta em uma história bifurcada, que deve ser familiar para qualquer um que tenha usado o Git como uma ferramenta de colaboração.,

Now, let’s say that the new commits inmaster are relevant to the feature that you’re working on. Para incorporar os novos commits em seu ID

branch, você tem duas opções: fundir ou refazer.,

A Opção de Mesclagem

A opção mais fácil é mesclar o master branch no ramo de funcionalidade, usando algo como o seguinte:

git checkout feature git merge master

Ou, você pode condensar isto para um one-liner:

 git merge feature master

Isto cria uma nova “série cometer” feature ramo que une as histórias de ambos os ramos, dando-lhe um ramo de estrutura que se parece com isto:

a Fusão é bom porque é uma organização não-destrutivo operação. Os ramos existentes não são alterados de forma alguma., Isto evita todas as potenciais armadilhas de rebasing (discutidas abaixo).

Por outro lado, isto também significa que o ramal

terá um commit de junção externa sempre que precisar de incorporar alterações a montante. Semasterfor muito activo, isto pode poluir bastante a história do seu ramo de recurso. Embora seja possível mitigar este problema com o avançadogit logopções, pode tornar difícil para outros desenvolvedores entender a história do projeto.,

O Rebase Opção

Como uma alternativa para mesclar, você pode alterar o feature ramo em master branch usando os seguintes comandos:

git checkout feature git rebase master

Isto move o inteiro feature ramo para começar na ponta da tag master ramo, efetivamente, a incorporação de todos os novos compromete-se em master. Mas, em vez de usar um commit merge, re-refazendo o histórico do projeto, criando commits novos para cada commit no branch original.,

o principal benefício do ajuste é que você tem um histórico de projeto muito mais limpo. Primeiro, elimina os commits desnecessários de merge exigidos por git merge. Em segundo lugar, como você pode ver no diagrama acima, o ajuste também resulta em um histórico de projeto perfeitamente linear—você pode seguir a ponta de feature todo o caminho para o início do projeto sem quaisquer garfos. Isso facilita a navegação do seu projeto com comandos como git log git bisect e gitk.,mas, há dois compromissos para este histórico de compromissos imaculados: segurança e rastreabilidade. Se você não seguir a regra de ouro de Rebasing, reescrever o histórico do projeto pode ser potencialmente catastrófico para o seu fluxo de trabalho de colaboração. E, menos importante, o rebasing perde o contexto fornecido por um merge commit—você não pode ver quando mudanças upstream foram incorporadas no recurso.

Rebasing interativo

rebasing interativo dá-lhe a oportunidade de alterar commits à medida que eles são movidos para o novo ramo., Isto é ainda mais poderoso do que um ajuste automático, uma vez que oferece controle completo sobre o histórico de commit do ramo. Tipicamente, isto é usado para limpar um histórico confuso antes de fundir um ramo de recursos em master.,

Para começar uma interativo realocação sessão, passe o i opção git rebase comando:

git checkout feature git rebase -i master

Isso vai abrir um editor de texto que lista todos os commits que está prestes a ser movido:

pick 33d5b7a Message for commit #1 pick 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

Esta lista define exatamente o que é o ramo ficará após a realocação é realizada. Ao alterar o comando pick e/ou reordenar os itens, poderá fazer com que o histórico do ramo pareça o que quiser., Por exemplo, se o 2º cometer corrige um pequeno problema na 1ª commit, você pode agrupá-los em um único commit com o fixup comando:

pick 33d5b7a Message for commit #1 fixup 9480b3d Message for commit #2 pick 5c67e61 Message for commit #3

Quando você salvar e fechar o arquivo, o Git irá realizar a realocação de acordo com as suas instruções, resultando no projeto de história que se parece com o seguinte:

Eliminar insignificante compromete-se, como isto faz com que seu recurso história muito mais fácil de entender. Isto é algo que git merge simplesmente não pode fazer.,

a regra de ouro de reajustar

Uma vez que você entenda o que reajuste é, a coisa mais importante a aprender é quando não fazê-lo. A regra de ouro degit rebase é nunca usá-lo em ramos públicos.

Por exemplo, pensar sobre o que aconteceria se você realocados master para o feature agência:

O rebase move todos os commits no master na ponta do feature. O problema é que isso só aconteceu em seu repositório., Todos os outros desenvolvedores ainda estão trabalhando com o original master. Desde a alteração da base de resultados em novo compromete-se, o Git vai pensar que o master ramo da história divergiu de todo mundo.

A única maneira de sincronizar os dois master ramos é mesclar-los novamente juntos, resultando em uma mala extra de confirmação e dois conjuntos de commits que contêm as mesmas alterações (o original, e aqueles a partir de sua base alterada ramo). Escusado será dizer que esta é uma situação muito confusa.,

so, before you run git rebase, always ask yourself, ” Is any else looking at this branch?”If the answer is yes, take your hands off the keyboard and start thinking about a non-destructive way to make your changes (e.g., the git revert command). Caso contrário, podes reescrever a história o quanto quiseres.

Força Empurrando

Se você tentar empurrar a realocados master ramo de volta para um repositório remoto, o Git vai impedir você de fazer isso porque ele está em conflito com o remoto master ramo., Mas, você pode forçar o impulso para percorrer, passando o --force bandeira, assim:

# Be very careful with this command! git push --force

Este substitui o controle remoto master ramo para coincidir com o realocados um do seu repositório e torna tudo muito confuso para o resto de sua equipe. Por isso, tenham muito cuidado em usar este comando apenas quando souberem exactamente o que estão a fazer.

uma das únicas vezes em que você deve ser forçado é quando você realizou uma limpeza local depois de ter empurrado um ramo de recursos privados para um repositório remoto (por exemplo, para fins de backup)., Isto é como dizer: “Oops, eu realmente não queria empurrar essa versão original do ramo recurso. Em vez disso, leva a actual.”Mais uma vez, é importante que ninguém esteja trabalhando fora dos commits a partir da versão original do branch feature.

Workflow Walk Through

Rebasing pode ser incorporado no seu fluxo de trabalho git existente tanto ou tão pouco quanto a sua equipa está confortável com. Nesta seção, vamos dar uma olhada nos benefícios que o rebasing pode oferecer nas várias fases do desenvolvimento de um recurso.,

O primeiro passo em qualquer fluxo de trabalho que aproveita git rebase é criar um ramo dedicado para cada recurso. Isto dá-lhe a estrutura de ramos necessária para utilizar de forma segura o rebasing:

limpeza Local

uma das melhores maneiras de incorporar o rebasing no seu fluxo de trabalho é limpar as funcionalidades locais em progresso. Através da realização periódica de um ajuste interativo, você pode se certificar de que cada commit em seu recurso é focado e significativo., Isto permite—lhe escrever o seu código sem se preocupar em dividi-lo em commits isolados-você pode corrigi-lo após o fato.

ao invocar git rebase, você tem duas opções para a nova base: o ramo-mãe da funcionalidade (por exemplo, master), ou um commit anterior na sua funcionalidade. Vimos um exemplo da primeira opção na seção de ajuste interativo. A última opção é agradável quando você só precisa corrigir os últimos commits. Por exemplo, o seguinte comando começa um ajuste interativo de apenas os últimos 3 commits.,

git checkout feature git rebase -i HEAD~3

especificando HEAD~3 como uma nova base, você não está realmente mover o ramo—você está apenas interativamente re-escrever a 3 compromete-se que o seguem. Note que isto não irá incorporar alterações a montante no ramo feature.

Se você deseja re-escrever todo o recurso usando este método, o git merge-base comando pode ser útil para encontrar a base original de feature ramo., A seguir retorna a confirmação da IDENTIFICAÇÃO da base original, que você pode, em seguida, passar para git rebase:

git merge-base feature master

Esse uso interativo da realocação é uma ótima maneira de introduzir git rebase em seu fluxo de trabalho, como ela afeta somente filiais locais. A única coisa que outros desenvolvedores vão ver é o seu produto acabado,que deve ser um limpo, fácil de seguir o histórico de Branch recurso.

mas, mais uma vez, isso só funciona para filiais de recursos privados., Se você está colaborando com outros desenvolvedores através do mesmo ramo de recursos, esse ramo é público, e você não está autorizado a reescrever seu histórico.

não existe git merge alternativa para a limpeza de commits locais com um ajuste interativo.

a Incorporação de Mudanças Upstream Em um Recurso

Na Visão geral Conceitual seção, vimos como um ramo de funcionalidade, pode incorporar mudanças upstream, a partir de master usando git merge ou git rebase., A junção é uma opção segura que preserva todo o histórico do seu repositório, enquanto o ajuste cria um histórico linear, movendo o seu ramo de funcionalidades para a ponta de master.

Esta utilização de git rebaseé semelhante a uma limpeza local (e pode ser realizada simultaneamente), mas no processo incorpora aqueles commits upstream demaster.

tenha em mente que é perfeitamente legal se ajustar a um ramo remoto em vez de master., Isso pode acontecer ao colaborar no mesmo recurso com outro desenvolvedor e você precisa incorporar suas alterações em seu repositório.,

Por exemplo, se você e um outro desenvolvedor chamado John adicionado compromete-se a feature ramo, seu repositório pode parecer o seguinte após buscar remoto feature ramo de João do repositório:

Você pode resolver esse garfo da mesma maneira como você a integrar alterações a montante, a partir de master: mesclar seu local feature com john/feature dou de seu local feature na ponta do john/feature.,

Note que este rebase não viola a regra de ouro do Rebasing porque apenas o seu ID local

commits estão a ser movidos—tudo antes de ser intocado. Isto é como dizer: “adicione minhas mudanças ao que João já fez.”Na maioria das circunstâncias, isso é mais intuitivo do que sincronizar com o ramo remoto através de um commit merge.

Por omissão, o comando git pull realiza uma junção, mas você pode forçá-lo a integrar o ramo remoto com um rebase, passando-o pela opção --rebase.,

revendo uma funcionalidade com um pedido de Pull

Se você usar pedidos de pull como parte do seu processo de revisão de código, você precisa evitar o uso de git rebase depois de criar o pedido de pull. Assim que você fizer o pedido pull, outros desenvolvedores estarão olhando para seus commits, o que significa que é um ramo público. Reescrever sua história vai tornar impossível para o Git e seus companheiros de equipe para rastrear qualquer commits de acompanhamento adicionado ao recurso.

quaisquer alterações de outros desenvolvedores precisam ser incorporadas com git merge em vez de git rebase.,

Por esta razão, é geralmente uma boa ideia limpar o seu código com um ajuste interativo antes de enviar o seu pedido de puxar.

a Integração de um Recurso Aprovado

Depois de um recurso foi aprovado por sua equipe, você tem a opção de realocação o recurso na ponta de master ramo antes de usar git merge para integrar a característica principal base de código.,

Esta é uma situação semelhante à incorporação de mudanças upstream em um ramo de funcionalidade, mas desde que você não tem permissão para re-escrever compromete-se master ramo, você tem que, eventualmente, use git merge para integrar a funcionalidade. No entanto, ao realizar um rebase antes da junção, você tem certeza de que a junção será rápida-encaminhada, resultando em um histórico perfeitamente linear. Isso também lhe dá a chance de eliminar qualquer commits de acompanhamento adicionados durante um pedido de pull.,

Se não estiver inteiramente confortável com git rebase, pode sempre efectuar o ajuste de base num ramo temporário. Dessa forma, se você acidentalmente estragar a história do seu recurso, você pode verificar o ramo original e tentar novamente. Por exemplo:

git checkout feature git checkout -b temporary-branch git rebase -i master # git checkout master git merge temporary-branch

resumo

e isso é tudo o que você realmente precisa saber para começar a ajustar seus ramos., Se preferir um histórico limpo e linear livre de commits de junção desnecessários, deverá alcançar git rebase em vez de git merge ao integrar alterações de outro ramo.por outro lado, se quiser preservar o histórico completo do seu projecto e evitar o risco de reescrever os commits públicos, pode ficar com git merge. Qualquer uma das opções é perfeitamente válida, mas pelo menos agora você tem a opção de alavancar os benefícios de git rebase.