Featured image of post Rebase Git mais fácil de branches bagunçadas

Rebase Git mais fácil de branches bagunçadas

Como resolver conflitos git apenas uma vez ao fazer rebase

Introdução Link to this section

Mesmo ao trabalhar com branches de curta duração, repositórios com mudanças constantes podem causar muitos conflitos e resultar em branches desatualizadas difíceis de fazer rebase.

Neste post, mostrarei uma maneira de fazer rebase dessas branches com muito menos esforço.

Branches de rebase bagunçadas Link to this section

Neste exemplo, tentar fazer rebase de branch-to-rebase em origin/main resultará em conflitos:

> git rebase origin/main

Auto-merging SomeFile.cs

CONFLICT (content): Merge conflict in SomeFile.cs
error: could not apply 57511bd... Change SomeFile
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <arquivos_em_conflito>", then run "git rebase --continue".

hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 57511bd... Change SomeFile

Se executarmos git status, podemos ver que o conflito está no primeiro de 16 commits:

> git status

interactive rebase in progress; onto 066147e

Last command done (1 command done):

   pick 57511bd Change SomeFile

Next commands to do (16 remaining commands):

   pick 2fcd87b Other Commit

   pick 7ffc7f5 Change other file

  (use "git rebase --edit-todo" to view and edit)

You are currently rebasing branch 'branch-to-rebase' on '066147e'.

  (fix conflicts and then run "git rebase --continue")

  (use "git rebase --skip" to skip this patch)

  (use "git rebase --abort" to check out the original branch)

Este pode ser um conflito apenas no primeiro commit, mas, em geral, esses conflitos ocorrem na maioria dos commits, e o rebase pedirá que você os resolva para cada um dos commits, o que é impraticável.

Como fazer rebase facilmente de branches bagunçadas Link to this section

Primeiro, fazemos checkout da branch que queremos fazer rebase e buscamos todas as branches:

> git checkout branch-to-rebase

> git fetch --all

Em seguida, temos que identificar o último commit anterior às mudanças na branch.

Para encontrá-lo, usamos o comando merge-base, passando a branch que faremos rebase (branch-to-rebase) e a branch para fazer rebase em (origin/main):

> git merge-base branch-to-rebase origin/main

Com o commit em mãos, fazemos um git reset para esse commit. Isso definirá o índice da branch para ser igual ao índice do commit:

> git reset f9fb326cb6cd58e0f31b433389b4a76f60319db1

Unstaged changes after reset:
M       SomeFile.cs
...

Isso significa que todas as diferenças da branch para o commit serão removidas do stage.

Agora, podemos stashear as mudanças e fazer rebase da branch. Isso não produzirá conflitos, porque não há mudanças na branch (todas as mudanças estarão no stash):

> git stash

Saved working directory and index state WIP on branch-to-rebase: d8dd56f ...

> git rebase origin/main

Successfully rebased and updated refs/heads/branch-to-rebase

⚠️ Em vez de um rebase, podemos criar uma nova branch para manter a branch-to-rebase como um backup.

Isso pode ser alcançado usando git checkout -b clean-branch origin/main em vez de git rebase origin/main.

O próximo passo é extrair as mudanças do stash e resolver os conflitos, mas agora só precisamos resolver os conflitos uma vez (de nossas mudanças stashed para origin/main)

git stash pop

# Resolva os conflitos

Finalmente, basta commitar e enviar a branch para o repositório remoto.

git commit

git push --force

ℹ️ Um benefício bônus é que isso terá o efeito de um squash rebase, porque produzirá apenas um commit.

Git Alias Link to this section

Neste post, expliquei como os aliases do Git são úteis.

Para tornar este fluxo de trabalho para rebase mais fácil, criei dois aliases:

1 - git mb Link to this section

Este alias obtém o nome da branch com checkout e o passa para merge-base.

Uso:

> git mb origin/main

f2732648ef5b6804a63d44f1b498f19ddf01eeb6

Configuração:

mb = "!f() { git branch --show-current | xargs git merge-base $1; }; f"

2 - git reset-base Link to this section

Este alias obtém a base comum para a branch e a branch de destino do rebase usando o alias mb definido acima e o passa para reset.

Uso:

> git reset-to-base origin/main

Successfully rebased and updated refs/heads/branch-to-rebase

Configuração:

reset-to-base = "!f() { git mb $1 | xargs git reset; }; f"
💬 Like or have something to add? Leave a comment below.
Ko-fi
GitHub Sponsor
Licensed under CC BY-NC-SA 4.0
Criado com Hugo
Tema Stack desenvolvido por Jimmy