git cherry-pick
Aplicar as mudanças de commits específicos na branch atual
O comando 'git cherry-pick' aplica as mudanças introduzidas por um ou mais commits existentes na branch atual, criando um commit novo para cada um. Diferente de merge ou rebase, que trabalham com branches inteiras, o cherry-pick permite copiar commits específicos de forma seletiva. É valioso para levar hotfixes a branches de release, recuperar commits perdidos ou trazer funcionalidades específicas de uma branch para outra sem mesclar tudo. Cada commit copiado ganha um SHA novo - é uma cópia, não uma mudança de lugar. O cherry-pick é cirúrgico e preciso, dando controle fino sobre quais mudanças chegam à sua branch.
Sinopse
git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] [-S[<keyid>]] <commit>...
git cherry-pick (--continue | --skip | --abort | --quit)Opções
Escolhendo a opção certa
Comparando git cherry-pick com comandos parecidos
Entender quando usar cherry-pick em vez de merge, rebase ou revert
| Comando | Aspecto | Cherry-pick | Outro comando |
|---|---|---|---|
Scope | Só commits específicos | Merge: branch inteira / Rebase: branch toda | |
Creates new commits | Sim - SHA novo, mesmo conteúdo | Merge: commit de merge / Rebase: reescreve tudo | |
Original stays | Sim - original intocado | Merge: sim / Rebase: órfão | |
Use case | Backport, portar seletivamente | Integrar branches completas | |
History effect | Cria mudanças duplicadas | Preserva ou deixa linear | |
Conflicts | Por commit durante o pick | No ponto de merge ou por commit do rebase |
Exemplos de fluxos de trabalho
git checkout release-1.0Trocar para a branch de release
git log main --onelineAchar o hash do commit da correção
git cherry-pick -x abc123Aplicar a correção com a referência de origem
git push origin release-1.0Enviar a correção portada
git checkout mainTrocar para a branch main
git log feature --onelineRevisar os commits da branch de funcionalidade
git cherry-pick abc123 def456Escolher só os commits prontos
git push origin mainEnviar os commits escolhidos
git reflogAchar o hash do commit no reflog
git checkout mainTrocar para a branch de destino
git cherry-pick abc123Aplicar o commit órfão
git checkout target-branchTrocar para a branch de destino
git cherry-pick A^..CAplicar os commits de A a C (inclusive)
git log --onelineConferir que os commits foram aplicados
Solução de problemas
"commit is a merge but no -m option was given"
Causa: Você está tentando fazer cherry-pick de um commit de merge sem dizer qual pai
Use -m 1 ou -m 2 para indicar o pai da linha principal
git cherry-pick -m 1 <merge-commit>Conflitos durante o cherry-pick
Causa: As mudanças conflitam com a sua branch atual
Resolva os conflitos nos arquivos, faça git add e depois git cherry-pick --continue. Ou cancele com --abort
git add <resolved-files> && git cherry-pick --continue"The previous cherry-pick is now empty"
Causa: As mudanças do commit já existem na sua branch
Rode 'git commit --allow-empty' para registrá-lo mesmo assim, ou 'git cherry-pick --skip' para pulá-lo
git cherry-pick --skipO cherry-pick criou commits duplicados
Causa: As mesmas mudanças agora existem como commits diferentes em branches diferentes
Esse é o comportamento esperado. Use a opção -x para documentar a relação
git cherry-pick -x <commit>Foi feito cherry-pick do commit errado
Causa: Você escolheu o SHA de commit errado
Se não foi enviado: git reset --hard HEAD~1. Se foi enviado: faça git revert do commit copiado
git reset --hard HEAD~1O cherry-pick parece não ter efeito
Causa: O commit pode estar vazio ou as mudanças já foram aplicadas
Confira git diff HEAD~1 para ver as mudanças reais
git diff HEAD~1Dicas e armadilhas
Boas práticas
- ✓Use -x em backports para adicionar a referência '(cherry picked from commit ...)' à mensagem do commit
- ✓Faça cherry-pick em ordem cronológica - commits dependentes devem ser aplicados do mais antigo ao mais novo para evitar conflitos
- ✓Prefira merge em branches compartilhadas - cherry-pick cria commits duplicados, enquanto merge preserva o histórico
- ✓Teste depois do cherry-pick - o commit pode funcionar no contexto original e falhar no novo
- ✓Documente os cherry-picks nas mensagens com a opção -e, explicando por que o commit foi copiado
- ✓Use --no-commit para juntar picks relacionados em um único commit mais limpo
- ✓Considere usar git cherry em vez de log para achar commits que ainda não foram aplicados
- ✓Em backports, sempre inclua o hash do commit original na mensagem para rastreabilidade
Erros comuns
- ✗Esquecer o -m em commits de merge. Fazer cherry-pick de um commit de merge sem '-m 1' ou '-m 2' falha - é preciso dizer em relação a qual pai calcular o diff.
- ✗Não preparar os arquivos resolvidos antes do --continue. Você precisa rodar 'git add' nos arquivos resolvidos antes de 'git cherry-pick --continue'.
- ✗Esperar o mesmo hash de commit. O cherry-pick cria commits NOVOS com SHAs novos - ele copia mudanças, não move commits.
- ✗Fazer cherry-pick de commits já aplicados. Isso causa conflitos ou commits vazios - confira antes com 'git log'.
- ✗Escolher commits na ordem errada. Commits dependentes devem ser escolhidos do mais antigo ao mais novo, senão aparecem conflitos.
- ✗Usar cherry-pick em branches públicas cria commits duplicados quando outras pessoas têm o original - prefira merge em branches compartilhadas.
Perguntas frequentes
Não. O cherry-pick cria um commit NOVO com as mesmas mudanças, mas com outro SHA. O commit original fica onde estava.
O hash de um commit no Git depende do conteúdo, do pai, do autor, da data e da mensagem. O cherry-pick mantém o autor e a data de autoria, mas o pai e a data do committer mudam, então o hash muda mesmo que as mudanças sejam idênticas.
Sim! Liste-os: git cherry-pick A B C, ou use intervalos: git cherry-pick A^..C (inclui A e C).
Use a opção -m: git cherry-pick -m 1 <merge-commit>. O número indica qual pai é a linha principal (normalmente 1).
A..B exclui A (commits depois de A até B). A^..B inclui A (commits de A até B, inclusive).
Se não foi enviado: git reset --hard HEAD~1. Se foi enviado: git revert <commit> para criar um commit que desfaz.
Cherry-pick para commits específicos. Rebase para mover branches inteiras. Se você precisa da maioria dos commits de uma branch, o rebase é mais limpo.