Git Cherry-Pick: Como Selecionar e Aplicar Commits Específicos

Trabalhar com ramificações em ambientes de desenvolvimento de software colaborativo é essencial para isolar recursos, correções de bugs ou experimentos. No entanto, há momentos em que você precisa pegar alterações específicas de uma ramificação e aplicá-las a outra sem mesclar toda a ramificação. É aqui que git cherry-pick se torna inestimável.

O objetivo deste tutorial é fornecer um guia abrangente sobre como usar git cherry-pick de forma eficaz. Você aprenderá a sintaxe do comando, entenderá como lidar com conflitos e explorará as melhores práticas e armadilhas comuns a evitar. Vamos lá!

O que é Git Cherry-Pick?

O comando git cherry-pick é um comando fundamental do Git que oferece aos desenvolvedores controle granular sobre seu código-fonte.

Ao contrário de outras operações Git, como merge ou rebase, que trabalham com ramos inteiros, cherry-pick permite que você pegue commits específicos de um ramo e os aplique em outro. Isso oferece precisão, especialmente em cenários em que você só precisa integrar mudanças específicas em vez de todas as modificações em um ramo.

O comando git cherry-pick funciona copiando o conteúdo dos commits selecionados e criando novos no ramo de destino, mantendo a integridade do histórico de commits.

Quando usar o git cherry-pick

Casos de uso para git cherry-pick incluem:

  • Aplicando correções de bugs: Você resolveu um bug em seu branch de desenvolvimento e precisa da mesma correção em um branch estável ou de release. O cherry-pick permite que você mova a correção do bug sem trazer mudanças não relacionadas.
  • Aplicando hotfixes: Quando a produção requer uma correção crítica enquanto os branches de desenvolvimento continuam evoluindo, o cherry-pick permite que você extraia e aplique a correção no branch de produção.
  • Isolamento de recurso para testes: Apenas commits específicos relacionados a um recurso podem precisar ser testados durante os testes. Em vez de mesclar todo o branch do recurso, o cherry-pick dos commits necessários mantém o branch de teste limpo e eficiente.
  • Corrigindo commits mal posicionados: Se um commit foi erroneamente enviado para o branch errado, você pode escolher o commit e adicioná-lo ao branch apropriado sem interromper o histórico do projeto.
  • Reutilizando alterações em vários branches: Em casos em que você precisa da mesma atualização em vários branches, o cherry-pick permite replicar as alterações em diferentes branches sem ter que refazer o trabalho ou introduzir complexidade nos branches.

Sintaxe do Git Cherry-Pick

Entender a sintaxe do git cherry-pick é fundamental para usar esse comando de forma eficaz. Não se trata apenas de selecionar commits, mas de aplicá-los com precisão para obter o resultado desejado.

A sintaxe básica para escolher um único commit é:

git cherry-pick <commit-hash>
  • git cherry-pick: O comando que inicia a operação.
  • <commit-hash>: O identificador único (hash SHA-1) do commit que você deseja escolher. Esse hash pode ser encontrado executando git log para listar o histórico de commits.

Ao executar o comando acima, o Git aplica as alterações do commit especificado no branch atual, criando um novo commit com as mesmas alterações, mas com um hash diferente.

É importante observar que o comando apenas transfere o commit em si, não o contexto ou o histórico pai do branch original.

Novo no Git e GitHub? Comece com controle de versão neste tutorial amigável para iniciantes GitHub e Git.

Como usar o Git Cherry-Pick: Exemplos passo a passo

Agora que você entende a sintaxe básica do git cherry-pick, é hora de ver o comando em ação.

Esta seção fornece exemplos práticos que o guiarão por cenários básicos comuns e mais complexos onde a seleção de commits é útil. Cada exemplo ilustra como aplicar as alterações de um ou mais commits para outro ramo.

Exemplo 1: Selecionando um único commit

Vamos dizer que você fez um ajuste em um ramo de funcionalidade que deseja aplicar ao ramo principal sem mesclar todo o ramco de funcionalidades.

  • Primeiro, encontre o hash do commit que deseja aplicar usando cherry-pick executando:
git log
  • Localize o hash do commit.
  • Mude para o ramo principal:
git checkout main
  • Execute o comando cherry-pick (assuma que o hash é abc1234):
git cherry-pick abc1234

Ao executar este comando, o Git aplicará as alterações do commit identificado por abc1234 para o seu branch atual (que é o main neste caso). O Git cria um novo commit no branch principal que contém as mesmas alterações do commit original, mas com um novo hash de commit.

Exemplo 2: Selecionando múltiplos commits

Em algumas situações, você pode precisar aplicar vários commits distintos de um branch para outro. Suponha que você tenha três commits separados em seu branch de feature que você precisa trazer para o branch principal.

  • Encontre os hashes de commit para cada commit que deseja selecionar usando git log:
git log
  • Mude para o branch principal:
git checkout main
  • Execute o comando cherry-pick, listando os commits:
git cherry-pick abc1234 def5678 ghi7890

Exemplo 3: Fazendo cherry-pick de um intervalo de commits

Digamos que você tenha feito uma série de commits no ramo de funcionalidade e queira aplicá-los ao ramo principal de uma só vez sem especificar cada commit individualmente. Como você faria isso?

  • Use git log para identificar os commits inicial e final que deseja cherry-pick (por exemplo, abc1234 até ghi7890).
  • Mude para o ramo principal:
git checkout main
  • Execute o comando cherry-pick com um intervalo de commits:
git cherry-pick abc1234...ghi7890

Exemplo 4: Fazendo cherry-pick de um commit de um ramo remoto

Às vezes, uma correção crítica existe em um ramo remoto, e você deseja aplicá-la ao seu ramo local sem mesclar o ramo inteiro. Veja como fazer:

  • Buscar as últimas alterações do repositório remoto
git fetch origin
  • Listar os commits no ramo remoto para encontrar o hash necessário:
git log origin/feature_branch --oneline
  • Suponha que o hash do commit necessário seja abc1234.
  • Mudar para o seu ramo principal local:
git checkout main
  • Cherry-pick do commit do ramo remoto:
git cherry-pick abc1234

Isso permite que você aplique um commit de um ramo remoto sem mesclar todo o ramo.

Precisa fazer check-out de um ramo remoto? Siga este guia passo a passo sobre Git checkout para ramos remotos.

Exemplo 5: Escolhendo um commit e modificando-o

Se você escolher um commit, mas precisar fazer pequenas modificações antes de confirmar, você pode usar o modo interativo do Git. Veja como:

  • Mude para o ramo de destino:
git checkout main
  • Escolha o commit, mas pare antes de confirmar:
git cherry-pick -n abc1234

O sinalizador -n (ou --no-commit) aplica as mudanças, mas não cria um commit.

  • Modifique os arquivos conforme necessário.
  • Adicione e faça o commit das mudanças manualmente:
git add . git commit -m "Modified cherry-picked commit from feature_branch"

Isso é útil quando é necessário ajustar um commit cherry-picked antes de finalizá-lo.

Manuseando Conflitos Durante o Git Cherry-Pick

Conflitos são inevitáveis ao cherry-pick de commits entre branches, especialmente quando a base de código divergiu significativamente.

Embora o cherry-pick seja projetado para aplicar alterações limpas, nem sempre ele pode reconciliar diferenças automaticamente. Nestes casos, os conflitos devem ser resolvidos manualmente. Compreender como os conflitos surgem e como lidar com eles é crucial para completar uma operação de cherry-pick.

Como os conflitos acontecem

Conflitos normalmente ocorrem quando as alterações do commit cherry-pick se sobrepõem ou contradizem alterações já presentes no branch de destino. Por exemplo:

  • Mesma linha modificada em ambos os branches: Se a mesma linha de código for modificada tanto nos branches de origem quanto de destino, o Git não saberá qual versão aplicar.
  • Arquivo deletado em um branch mas modificado em outro: Se um arquivo é deletado em um branch mas modificado no commit cherry-picked, o Git não saberá se deve mantê-lo ou aplicar as mudanças.
  • Mudanças não relacionadas mas mesmo arquivo: Mesmo quando as mudanças parecem não estar relacionadas, se elas ocorrem no mesmo arquivo, o Git pode identificá-lo como um conflito potencial.

Quando ocorre um conflito, o Git irá interromper a operação de cherry-pick, deixando seu diretório de trabalho em um estado de conflito que deve ser resolvido antes de prosseguir.

Resolvendo conflitos

Uma vez que surge um conflito, o Git fornecerá indicadores dos arquivos em conflito, e você precisará resolver manualmente as discrepâncias. Veja como resolver conflitos:

1. Verifique os arquivos em conflito: Execute o seguinte comando para ver quais arquivos estão em conflito:

git status

O comando exibirá a lista de arquivos com conflitos.

2. Resolva os conflitos: Você pode editar manualmente os arquivos em conflito para resolver os problemas. Remova os marcadores de conflito (<<<<<<<, =======, >>>>>>>) e determine quais alterações manter ou como combiná-las.

3. Use Git Mergetool (opcional): Se resolver conflitos manualmente for trabalhoso, você pode usar uma ferramenta de mesclagem para ajudar na visualização e resolução de conflitos:

git mergetool

Dependendo da sua configuração, a ferramenta acima abrirá uma ferramenta de mesclagem visual, que facilita a revisão e resolução de conflitos.

4. Marque os conflitos como resolvidos: Após resolver os conflitos, marque os arquivos como resolvidos usando:

git add <conflicted-file>

5. Complete o cherry-pick: Uma vez que todos os conflitos forem resolvidos e os arquivos estiverem preparados, finalize o cherry-pick executando:

git cherry-pick --continue

Muitas IDEs e ferramentas modernas, como Visual Studio Code e GitHub, oferecem recursos integrados de resolução de conflitos de mesclagem. A interface web do GitHub permite que você resolva conflitos diretamente em solicitações de pull, facilitando a colaboração em repositórios compartilhados sem precisar mudar para um ambiente local.

Pulando um commit após um conflito

Às vezes, resolver um conflito pode ser muito complexo, ou você pode perceber que o commit não é necessário afinal. Nestes casos, você pode pular o commit completamente.

1. Abortar o processo de cherry-pick atual: Se o conflito for muito complicado e você não deseja aplicar o commit, você pode ignorá-lo executando:

git cherry-pick --skip

Isso irá abandonar o commit em conflito e avançar para o próximo (se estiver cherry-pickando vários commits).

2. Abortar todo o cherry-pick: Se deseja abortar completamente a operação de cherry-pick, você pode executar:

git cherry-pick --abort

Este comando irá restaurar seu diretório de trabalho para o estado em que estava antes de começar o cherry-pick. 

Quer limpar seu histórico de commits? Aprenda como combinar vários commits em um com este tutorial de squash do Git.

Melhores Práticas para Usar o Git Cherry-Pick

O uso inadequado do cherry-pick pode levar a históricos complicados e confusão no controle de versão do seu projeto. Para evitar essas armadilhas, seguir as melhores práticas garante que você está usando o cherry-pick de forma eficaz sem introduzir complexidade desnecessária em sua base de código.

Mantenha pequeno e específico

O cherry-pick é mais eficaz quando usado para commits pequenos e específicos que abordam tarefas bem definidas, como correção de bugs ou pequenas melhorias de recursos.

Ao evitar escolher commits grandes e complexos que agrupam várias mudanças, você pode evitar conflitos e tornar mais fácil gerenciar a base de código. Quanto mais direcionado o commit, mais fácil é aplicá-lo sem efeitos colaterais indesejados.

Documente seus cherry-picks

Para manter um histórico claro, sempre forneça o contexto adequado ao fazer cherry-picking. Isso pode ser feito por meio de mensagens de commit detalhadas ou anotações na documentação.

O principal é que você deve explicar por que um cherry-pick foi necessário. Isso é especialmente importante ao fazer cherry-picking em branches de longa duração ou em ambientes colaborativos, pois ajuda os futuros colaboradores a entender por que as mudanças foram aplicadas seletivamente.

Revise o histórico de commits

Antes de fazer cherry-pick, revise o histórico de commits tanto das branches de origem quanto de destino. Esse passo ajuda a identificar se o commit que você está prestes a fazer cherry-pick depende de outras alterações. A falta de dependências pode resultar em funcionalidades incompletas ou bugs, então garanta que o cherry-pick não introduza funcionalidades ou atualizações malfeitas.

Avoid overuse of cherry-picking

Embora o cherry-pick seja conveniente para aplicar alterações específicas, o uso excessivo pode levar a um histórico fragmentado com commits duplicados em várias branches. Isso pode dificultar rastrear a origem de determinadas alterações ou entender o contexto mais amplo do desenvolvimento.

Avalie sempre se mesclar ou rebase é uma estratégia mais apropriada antes de fazer cherry-pick. Use o cherry-pick com parcimônia e intencionalidade para evitar poluir o histórico de commits.

Com problemas com arquivos desnecessários no Git? Aprenda a usar .gitignore de forma eficaz com este tutorial de ignorar Git.

Solucionando Problemas Comuns com Git Cherry-Pick

Resolver problemas que surgem ao usar cherry-pick requer um entendimento claro dos mecanismos subjacentes do Git. Nesta seção, vou abordar alguns problemas comuns que você pode encontrar ao fazer cherry-picking e como resolvê-los.

Fazendo cherry-pick de um commit que não existe

Às vezes, você pode tentar fazer cherry-pick de um commit que não está acessível a partir do branch atual ou que já foi mesclado. Isso geralmente resulta em uma mensagem de erro informando que o commit não pôde ser encontrado ou aplicado.

1. Commit não encontrado: Isso acontece quando o hash do commit que você está tentando pegar não existe no seu repositório atual ou contexto do branch. Certifique-se de que está referenciando o commit correto verificando o histórico de commits com git log no branch onde o commit existe. Solução:

  • Verifique novamente o hash do commit para garantir que está correto.
  • Verifique se o commit existe em um branch ao qual você tem acesso.
  • Se o commit estiver em um branch remoto, certifique-se de que o branch foi baixado com git fetch.

2. Confirmar já aplicado: Se o commit já foi mesclado ou cherry-picked para o branch de destino, o Git impedirá que você o duplique. Essa proteção mantém o histórico limpo e evita alterações redundantes. Solução:

  • Use git log para verificar se o commit já está no branch de destino.
  • Se necessário, pule a operação de cherry-pick pois as alterações já foram aplicadas.

Cherry-pick após um rebase ou uma mesclagem

Cherry-pick após um rebase ou mesclagem pode introduzir complexidades devido ao histórico alterado de seus branches. O rebase reescreve os históricos de commit enquanto a mesclagem combina branches, ambos os quais podem impactar a aplicabilidade de um cherry-pick.

1. Conflitos devido a commits reposicionados: Após um rebase, o histórico de commits é reescrito, o que pode causar problemas se você tentar escolher commits que foram alterados durante o processo de rebase. Você pode encontrar conflitos, já que o cherry-pick tenta aplicar alterações que não estão alinhadas com o histórico reescrito. Solução:

  • Revise cuidadosamente o histórico de commits após um rebase usando git log para garantir que o commit que você está escolhendo não tenha sido modificado.
  • Resolva os conflitos como faria em um processo padrão de cherry-pick, usando git status e edições manuais.

2. Commits duplicados após um merge: Mesclar branches pode levar a uma situação em que um commit que você deseja cherry-pick já foi incluído no histórico mesclado. Fazer cherry-pick novamente pode resultar em commits duplicados, o que pode bagunçar seu histórico e dificultar o rastreamento de alterações. Solução:

  • Antes de fazer cherry-pick, inspecione o histórico de commits em ambas as branches para confirmar se o commit já foi mesclado.
  • Evite fazer cherry-pick do mesmo commit se ele já estiver na branch de destino.

Precisa desfazer alterações no Git? Aprenda quando usar git reset vs. git revert neste tutorial sobre reset e revert do Git.

Conclusão

git cherry-pick é uma maneira poderosa de aplicar commits específicos de um branch para outro sem mesclar o branch inteiro. Seja para mover uma correção de bug, uma atualização de recurso, ou apenas aplicar mudanças de forma seletiva, isso ajuda a manter o histórico do seu Git limpo e focado.

Neste guia, eu abordei como fazer cherry-pick de commits únicos e múltiplos, resolver conflitos e seguir as melhores práticas para evitar armadilhas comuns. Ao usar o cherry-pick de forma sábia, você pode melhorar seu fluxo de trabalho mantendo seu repositório organizado.

Se você está procurando aprofundar suas habilidades no Git, confira Foundations of Git como um ponto de partida sólido. Você também pode explorar Introduction to GitHub Concepts ou seguir uma abordagem estruturada com o GitHub Foundations skill track.

Agora que você sabe como fazer cherry-pick como um profissional, vá em frente e experimente no seu próximo projeto!

Source:
https://www.datacamp.com/tutorial/git-cherry-pick