Rebase Git: tudo o que você precisa saber

Laptop em um fundo azul mostrando um prompt de comando do Linux.

O comando Git rebasecombina duas ramificações do código-fonte em uma. O comando Git mergetambém faz isso. Explicamos o que rebasefaz, como é usado e quando usar merge.

A explosão do Git

Frustrado com outros sistemas de controle de versão e suas atualizações e commits lentos, Linus Torvalds , famoso pelo kernel Linux, reservou um mês em 2005 para escrever o seu próprio. Ele o chamou de Git.

Sites como GitHubGitLabBitBucket  promoveram e se beneficiaram simbioticamente do Git. Hoje, o Git é usado globalmente, com  98% dos 71 mil entrevistados  em uma pesquisa de 2022 usando o Git como sistema de controle de versão.

Uma das principais decisões de design do Git foi a velocidade. Em particular, o trabalho com filiais tinha que ser o mais rápido possível. As ramificações são uma parte fundamental dos sistemas de controle de versão. Um repositório de projeto terá um branch principal ou master. É aqui que fica a base de código do projeto. O desenvolvimento, como novos recursos, ocorre em ramificações laterais segregadas. Isso evita que o trabalho realizado nas ramificações atrapalhe a ramificação master e permite que o desenvolvimento simultâneo aconteça em diferentes partes da base de código.

À medida que os desenvolvimentos nas ramificações laterais são concluídos, as alterações são transferidas para a ramificação master, mesclando a ramificação de desenvolvimento na ramificação master. Em outros sistemas de controle de versão, trabalhar com ramificações era difícil e caro do ponto de vista computacional. Trabalhar com ramificações no Git é muito rápido e leve. O que antes era um exercício tedioso e muitas vezes evitado em outros sistemas, tornou-se trivial no Git.

O comando Git rebaseé outra maneira de transferir as alterações de uma ramificação para outra. Os comandos mergee rebasetêm objetivos semelhantes, mas atingem seus fins de maneiras diferentes e produzem resultados ligeiramente diferentes.

O que é a mesclagem do Git?

Então, para que serve o comando Gitmerge ? Digamos que você criou um branch chamado dev-branchpara trabalhar em um novo recurso.

Um diagrama de um branch master e um branch não mesclado chamado dev-branch

Você faz alguns commits e testa seu novo recurso. Tudo funciona bem. Agora você deseja enviar seu novo recurso para a masterfilial. Você deve estar no masterbranch para mesclar outro a ele.

Recomendado:  Como escolher quais extensões aparecem na barra de ferramentas do Edge

Podemos garantir que estamos no master branch verificando-o explicitamente antes da fusão.

mestre de checkout git

Agora podemos dizer ao Git para mesclar o dev-branchbranch atual, que é o masterbranch.

git merge dev-branch

Mesclando o branch dev-branch com o branch master

Nosso mergeestá concluído para nós. Se você fizer check-out do masterbranch e compilá-lo, ele conterá o recurso recém-desenvolvido. O que o Git realmente realizou foi uma fusão de três vias. ele compara os commits mais recentes nas masterramificações dev-branche e o commit na masterramificação imediatamente antes de dev-branchser criado. Em seguida, ele executa um commit no masterbranch.

As mesclagens são consideradas não destrutivas porque não excluem nada e não alteram nada do histórico do Git. O dev-branchainda existe e nenhum dos commits anteriores foi alterado. É criado um novo commit que captura os resultados da mesclagem de três vias.

Após a fusão, nosso repositório Git se parece com uma linha do tempo com uma linha alternativa se ramificando e retornando à linha do tempo principal.

O branch dev-branch foi mesclado com o branch master

A dev-branchfilial foi incorporada à masterfilial.

Se você tiver muitas ramificações em um projeto, o histórico do projeto poderá se tornar confuso. Este é frequentemente o caso se um projeto tiver muitos colaboradores. Dado que o esforço de desenvolvimento se divide em muitos caminhos diferentes, a história do desenvolvimento não é linear. Desembaraçar o histórico de commits torna-se ainda mais difícil se as ramificações tiverem suas próprias ramificações.

Observe que se você tiver alterações não confirmadas no masterbranch, precisará fazer algo com essas alterações antes de poder mesclar qualquer coisa a ele. Você poderia criar uma nova ramificação e confirmar as alterações lá, e então fazer a mesclagem. Você precisaria então mesclar seu branch temporário de volta ao branch master.

Isso funciona, mas o Git tem um comando que faz a mesma coisa, sem a necessidade de criar novas ramificações. O stashcomando armazena suas alterações não confirmadas para você e permite chamá-las de volta com stash pop.

Você os usaria assim:

esconderijo

git merge dev-branch

esconderijo

O resultado final é uma ramificação mesclada, com as alterações não salvas restauradas.

O que é rebase do Git?

rebaseO comando Git atinge seus objetivos de uma maneira completamente diferente. Ele pega todos os commits do branch que você vai fazer o rebase e os reproduz no final do branch que você está fazendo o rebase.

Recomendado:  O que é uma extensão de arquivo?

Tomando nosso exemplo anterior, antes de realizarmos qualquer ação, nosso repositório Git se parece com isto. Temos um branch chamado dev-branche queremos mover essas alterações para o masterbranch.

Um diagrama de um branch master e um branch não mesclado chamado dev-branch

Depois do rebase, parece uma linha do tempo única e completamente linear de mudanças.

O branch master com o branch dev rebaseado nele

O dev-branchfoi removido e os commits no dev-branchforam adicionados ao branch master. O resultado final é o mesmo como se os commits no dev-branchtivessem sido realmente confirmados diretamente no masterbranch em primeiro lugar. Os commits não são apenas colados no masterbranch, eles são “repetidos” e adicionados de novo.

É por isso que o rebasecomando é considerado destrutivo. O branch rebaseado não existe mais como um branch separado e o histórico Git do seu projeto foi reescrito. Você não pode determinar posteriormente quais commits foram feitos originalmente no arquivo dev-branch.

No entanto, isso deixa você com um histórico simplificado e linear. Comparado a um repositório com dezenas ou até centenas de ramificações e mesclagens, lendo o log do Git ou usando uma GUI gráfica do git para visualizar um gráfico do repositório, um repositório rebaseado é fácil de entender.

Como fazer o rebase em outra ramificação

Vamos tentar um git rebase exemplo. Temos um projeto com um branch chamado new-feature. Colocaríamos rebase aquele galho em mastergalho assim.

Primeiramente, verificamos se a masterfilial não possui alterações pendentes.

status do git

Verificamos a new-featurefilial.

git checkout novo recurso

Dizemos ao Git para rebaseo branch atual no branch master.

mestre de rebase git

Podemos ver que ainda temos duas filiais.

ramo git

Trocamos de volta para a masterfilial

mestre de checkout git

Mesclamos o branch com novos recursos no branch atual, que no nosso caso é o masterbranch.

git merge novo recurso

O branch master com o novo recurso baseado nele

Curiosamente, ainda temos duas ramificações após a fusão final.

Usando o comando Git branch para listar as ramificações no repositório git

A diferença é que agora o cabeçalho do new-featurebranch e o cabeçalho do masterbranch estão configurados para apontar para o mesmo commit, e o histórico do Git não mostra que costumava haver um new-featurebranch separado, além do rótulo do branch.

O branch master com o branch dev rebaseado nele

Git Rebase vs. Merge: qual você deve usar?

Não é um caso de rebasevs. mergeAmbos são comandos poderosos e você provavelmente usará os dois. Dito isto, há casos de uso em que rebasenão funciona muito bem. Erros de remoção causados ​​por erros de uso mergesão desagradáveis, mas erros de remoção causados ​​por erros rebasesão infernais.

Recomendado:  Logitech tem novos teclados mecânicos para trabalho de produtividade

Se você é o único desenvolvedor que usa um repositório, há menos chances de você fazer algo rebasedesastroso. Você ainda pode rebaseestar na direção errada, por exemplo, e rebaseseu branch master em seu new-featurebranch. Para masterrecuperar sua filial, você precisará fazer isso rebasenovamente, desta vez de new-featurefilial em masterfilial. Isso restauraria sua masterfilial, embora com uma história estranha.

Não use rebaseem filiais compartilhadas onde outras pessoas provavelmente trabalharão. Suas alterações em seu repositório causarão problemas para muitas pessoas quando você enviar seu código rebaseado para seu repositório remoto.

Se o seu projeto tiver vários contribuidores, a coisa segura a fazer é usar apenas rebaseno seu repositório local, e não em ramificações públicas. Da mesma forma, se solicitações pull fizerem parte de suas revisões de código, não use rebase. Ou pelo menos não use rebasedepois de criar a solicitação pull. É provável que outros desenvolvedores estejam analisando seus commits, o que significa que essas alterações estão em um branch público, mesmo que não estejam no masterbranch.

O perigo é que você faça rebasecommits que já foram enviados para um repositório remoto, e outros desenvolvedores podem já ter baseado o trabalho nesses commits. Seu local rebasefará com que os commits existentes desapareçam. Se você enviar essas alterações para o repositório, você não será popular.

Outros contribuidores terão que passar por uma confusão mergepara que seu trabalho seja enviado de volta ao repositório. Se você puxar as alterações de volta para o repositório local, terá que desfazer uma confusão de alterações duplicadas.

Rebasear ou não rebasear?

Rebasepode ser proibido em seu projeto. Pode haver objeções locais e culturais. Alguns projetos ou organizações consideram rebaseisso uma forma de heresia e um ato de profanação. Algumas pessoas acreditam que a história do Git deveria ser um registro inviolável e permanente do que aconteceu. Então, rebasepode estar fora de questão.

Mas, usado localmente, em agências privadas, rebaseé uma ferramenta útil.

Faça push depois de fazer o rebase e restrinja-o às filiais onde você é o único desenvolvedor. Ou pelo menos onde todo o desenvolvimento parou e ninguém mais baseou qualquer outro trabalho nos commits do seu branch.

Faça isso e você evitará quaisquer problemas.