Voltar ao blog

Git cherry-pick: vários commits, branches e conflitos

12 de setembro de 2026

TL;DR: git cherry-pick <sha> copia um commit de qualquer branch para a sua branch atual — mesmo patch, SHA novo, nenhum histórico movido. Para vários commits, liste os SHAs ou use um intervalo (git cherry-pick A..B); note que o intervalo exclui A, então escreva A^..B para incluí-lo. Se ele parar num conflito, resolva, git add, depois git cherry-pick --continue. Cherry-pick é para mover um fix específico — quando você quer tudo da outra branch, use merge ou rebase.

O que o git cherry-pick faz de verdade?

O cherry-pick pega um commit existente e aplica o diff dele como um novo commit na sua branch atual. O commit original fica onde está; a cópia ganha um SHA fresco. O git não “move” nada — quem depois se pergunta por que o commit ainda aparece na branch antiga está vendo exatamente isso.

Esse modelo de copiar-e-não-mover decide quando o cherry-pick é a ferramenta certa:

  • Você precisa de um fix de uma feature branch no main agora, sem mergear o resto.
  • Um hotfix commitado na branch errada precisa chegar à certa.
  • Um patch precisa ser reaplicado numa release branch que nunca mergear do main.

A habilidade complementar é saber desfazer um commit que se revelou errado — a mecânica disso está coberta em git undo last commit: mantendo as mudanças.

Como faço cherry-pick de um commit de outra branch?

Ache o SHA, troque para a branch alvo, pick:

# 1. Localize o commit na branch de origem
git log feature/payment-fix --oneline -5

# 2. Troque para a branch que deve recebê-lo
git switch main

# 3. Copie para cá
git cherry-pick 1a2b3c4

Duas conveniências que valem conhecer:

  • git cherry-pick <branch> pega o commit da ponta da branch — útil, mas fácil de fazer por acidente com um modelo mental desatualizado do que “a ponta” é.
  • Depois do pick, git log -1 --stat confirma o que entrou. Um segundo de leitura, economiza um revert.

Os commits ficam na feature/payment-fix; apague a branch quando quiser — a cópia escolhida no main tem SHA próprio e nenhuma dependência da antiga.

Como faço cherry-pick de vários commits?

Três formas, na ordem de quanto você vai querer cada uma:

# 1. Lista explícita — aplicados na ordem em que você os lista
git cherry-pick 1a2b3c4 5d6e7f8

# 2. Intervalo — tudo depois de A até B, inclusive
git cherry-pick A..B

# 3. Intervalo incluindo A
git cherry-pick A^..B

A distinção A..B vs A^..B é a surpresa clássica: A..B exclui A. Se você visualiza o intervalo a partir do git log e faz pick de oldest..newest, você pula o commit mais antigo em silêncio. Quando o objetivo é “os commits mais antigos, em ordem”, escreva oldest^..newest e o off-by-one desaparece.

Para juntar vários picks num commit só em vez de três, aplique sem commitar com -n / --no-commit, e commite uma vez:

git cherry-pick -n 1a2b3c4 5d6e7f8
git commit -m "Backport: payment retry fixes"

Por que o git cherry-pick não está funcionando?

Quatro causas reais, por ordem de frequência:

1. Um conflito parou o pick. O git aplica o patch, encontra uma linha que mudou nas duas branches e pausa no meio da sequência:

# resolva os arquivos, depois:
git add <resolved-files>
git cherry-pick --continue   # ou --abort para voltar ao estado pré-pick

O --continue não é opcional nem implícito — até rodá-lo, você está dentro de uma sequência de cherry-pick pausada e o git status vai continuar dizendo isso.

2. O pick está vazio (“The previous cherry-pick is now empty”). A mudança já existe nesta branch, geralmente de um pick anterior ou de um merge com squash. Pule com git cherry-pick --skip, ou force um commit vazio com --allow-empty se você genuinamente precisa do marcador.

3. O commit é um merge commit. Um merge tem dois pais, então “aplicar este diff” é ambíguo — o git recusa em vez de adivinhar. Diga contra qual pai você está diferenciando:

git cherry-pick -m 1 <merge-sha>   # pai 1 = a branch para a qual você fez o merge

4. Working tree errada ou detached HEAD. O pick aterrissa onde o HEAD aponta. Rode git branch --show-current antes do pick; se não imprimir nada, você está em detached HEAD e o commit vai ficar órfão quando você trocar de branch.

Cherry-pick vs merge vs rebase: quando usar cada um?

ComandoO que chega ao alvoHistóricoUse quando
git cherry-pick <sha>Só o(s) commit(s) nomeado(s)Cópia, SHAs novosUm fix específico precisa se mover agora
git merge <branch>Tudo da branchMerge commit ou fast-forwardVocê quer a branch inteira, divergência visível
git rebase <base>Todos os commits da branch, reaplicadosLinear, SHAs reescritosVocê quer a branch como uma fila linear limpa
git revert <sha>Inverso de um commitAdiciona um commit de undoUm commit já aplicado precisa ser desfeito em histórico compartilhado

A regra de uma linha: o cherry-pick move uma seleção; merge e rebase movem tudo. Recorrer ao cherry-pick para “sincronizar” com uma branch é sinal de que você quer, na verdade, um merge — e se a comparação é o main do seu fork contra o upstream, a rotina completa está em sincronize um fork com o upstream, passo a passo.

Um hábito para evitar: cherry-picar o mesmo commit para várias branches a longo prazo. Cada fix futuro na branch de origem pede outro pick, e eventualmente as branches divergem. Backport para release branches é um padrão normal; um universo paralelo permanente, não.

O fluxo do cherry-pick, resumido

git log <source-branch> --oneline -5   # encontre o(s) SHA(s)
git switch <target-branch>             # chegue no lugar certo
git cherry-pick A^..B                  # intervalo, lista ou SHA único
# em conflito: resolva → git add → git cherry-pick --continue
git log -1 --stat                      # confirme o que entrou

Ache, troque, pick, verifique. O comando tem uma fama de perigo que não merece — ou o diff se aplica, ou ele para e diz por quê. O único erro genuinamente destrutivo é picar na branch errada, e um git log -1 antes do push torna esse difícil de não notar.

— mrsaynothing

Get the next one by email

One email per post. No spam, no algorithms.

self-hosted · no third parties · one-click unsubscribe

what is this?

Cron vs timers do systemd: qual usar?

Gostou dos artigos? É assim que eu construo profissionalmente. me contrate