Git cherry pick e integridade de datamodelo

Dado que dois ramos divergiram e um compromisso específico de um ramo (e não de tudo) precisa ser introduzido ao outro, a escolha exata da cereja alcança exatamente isso.

Depois de algum tempo, há a necessidade de mesclar completamente os dois ramos. Como vai saber que já tem o commit que foi escolhido no passado para que não o reintroduza?

Você pode querer ler

Git Cherry-pick vs Merge Workflow para uma boa comparação entre merge e cherry-pick, especialmente que cherry-pick não armazena o id pai, e assim não saberá que ele já tem o commit que foi escolhido no passado para que ele não vai reintroduzi-lo.

e

http://davitenio.wordpress.com/2008/09/27/git-merge-after-git-cherry-pick-avoiding-duplicate-commits/ sobre como evitar a duplicação de commits neste caso, usando rebase .

O artigo ” evitar confirmação duplicada ” mencionado na resposta da tonio diz:

Imagine que temos o branch master e um branch b:

  o---X < -- master \ b1---b2---b3---b4 <-- b 

Agora precisamos urgentemente dos commits b1 e b3 no master, mas não os commits restantes em b. Então, o que fazemos é fazer o checkout do branch master e fazer picks cherry-pick b1 e b3:

 $ git checkout master $ git cherry-pick “b1's SHA” $ git cherry-pick “b3's SHA” 

O resultado seria:

  o---X---b1'---b3' < -- master \ b1---b2---b3---b4 <-- b 

Digamos que façamos outro commit no master e recebamos:

  o---X---b1'---b3'---Y < -- master \ b1---b2---b3---b4 <-- b 

Se agora mesclássemos a ramificação b em master:

 $ git merge b 

Nós obteríamos o seguinte:

  o---X---b1'---b3'---Y--- M < -- master \ / b1----b2----b3----b4 <-- b 

Isso significa que as alterações introduzidas por b1 e b3 apareceriam duas vezes na história. Para evitar isso, podemos rebase em vez de mesclar:

 $ git rebase master b 

Que renderia:

  o---X---b1'---b3'---Y < -- master \ b2---b4 <-- b 

Finalmente:

 $ git checkout master $ git merge b 

nos dá:

  o---X---b1'---b3'---Y---b2---b4 < -- master, b 

(depois desta discussão )


O OP adiciona no comentário:

Mas ainda parece que eu não entendo muito bem como rebase funciona .. Quero dizer, mesmo depois de rebasing não deveria a cereja escolhida cometer ainda aparecem?

Não. A página man git commit man menciona explicitamente:

Se o branch upstream já contém uma mudança que você fez (por exemplo, porque você enviou um patch que foi aplicado a upstream), então esse commit será pulado .
Por exemplo, executando git rebase master no seguinte histórico (no qual A 'e A introduzem o mesmo conjunto de mudanças, mas possuem diferentes informações do committer):

  A---B---C topic / D---E---A'---F master 

vai resultar em:

  B'---C' topic / D---E---A'---F master 

Você pode detectar se um commit já está presente no master com o git cherry master (se você estiver no branch de topic ).