Che cosa significa scegliere una ciliegina con Git?


2340

Di recente mi è stato chiesto di cherry-pickimpegnarmi.

Cosa vuol dire scegliere una commessa in git con Cherry? Come si fa?


13
Invece di unire, con la raccolta delle ciliegie il reimpegnare da un ramo al ramo di destinazione (es: master) è più facile.
Levent Divilioglu,

Risposte:


2859

Raccogliere ciliegia in Git significa scegliere un commit da un ramo e applicarlo a un altro.

Ciò è in contrasto con altri modi come mergee rebaseche normalmente applicano molti commit su un altro ramo.

  1. Assicurati di essere nel ramo a cui desideri applicare il commit.

    git checkout master
    
  2. Eseguire quanto segue:

    git cherry-pick <commit-hash>
    

NB:

  1. Se scegli una ciliegia da una filiale pubblica, dovresti prendere in considerazione l'utilizzo

    git cherry-pick -x <commit-hash>
    

    Ciò genererà un messaggio di commit standardizzato. In questo modo, tu (e i tuoi colleghi) potete ancora tenere traccia dell'origine del commit ed evitare conflitti di unione in futuro.

  2. Se hai delle note allegate al commit, queste non seguono la scelta della ciliegia. Per portarli anche tu, devi usare:

    git notes copy <from> <to>
    

Link aggiuntivi:


247
Se scegli una ciliegia da una filiale pubblica, dovresti prendere in considerazione l'utilizzo git cherry-pick -x <commit-hash>. Ciò genererà un messaggio di commit standardizzato. In questo modo, tu (e i tuoi colleghi) potete ancora tenere traccia dell'origine del commit ed evitare conflitti di unione in futuro.
MBober,

2
La raccolta delle ciliegie è davvero necessaria? Un ripristino misto o un ripristino software non eseguono un processo simile?
Nav

10
Nota che se hai delle note allegate al commit non seguono il cherry-pick. Devi usare anche git notes copy <from> <to>per portarli oltre.
Zitrax,

5
git push è l'ultimo passo per apportare modifiche al master
sentirsi bene e programmare il

58
FYI: un commit semanticamente contiene tutti i file del albero di lavoro di quel momento (e commettere hash del commit precedente), in modo da non sta applicando un intero impegnarsi per un'altra impegnarsi, ma i cambiamenti un commit ha fatto sul precedente commit "cherry-pick commit applies the changes introduced by the named commit on the current branch"Most ppl tende a pensare al commit come a cambiamenti (come svn was iirc), ma non lo è, ogni commit fa riferimento all'albero di lavoro completo. Anche se questo non fa differenza in questo caso, può aiutare a capire perché git funziona così.
Emile Vrijdags,

314

Questa citazione è presa da; Controllo versione con Git (Davvero un ottimo libro, ti incoraggio a acquistarlo se sei interessato a Git )

Modifica: poiché questa risposta sta ancora ottenendo impressione, vorrei aggiungere un tutorial video molto bello in azione su di esso:

Youtube: Introduzione a Git cherry-pick

Uso di git cherry-pick Il comando git cherry-pick commit applica le modifiche introdotte dal commit denominato sul ramo corrente. Introdurrà un nuovo, distinto commit.A rigor di termini, l'uso di git cherry-pick non altera la storia esistente all'interno di un repository; invece, si aggiunge alla storia. Come per le altre operazioni Git che introducono modifiche attraverso il processo di applicazione di un diff, potrebbe essere necessario risolvere i conflitti per applicare completamente le modifiche da un determinato commit . Il comando git cherry-pick è in genere usato per introdurre particolari commit da un ramo all'interno di un repository su un ramo diverso. Un uso comune è il forwarding o back-port di commit da un ramo di manutenzione a un ramo di sviluppo.

$ git checkout rel_2.3
$ git cherry-pick dev~2 # commit F, above

prima: prima

dopo: dopo


12
quando i commit selezionati dalla ciliegia vengono presi su un ramo (b1) e successivamente consegnati al master. E se anche il ramo b1 (da cui erano stati inizialmente prelevati i commit) è stato tentato di essere consegnato al master. E i conflitti? È curato o come funziona?
Parassita,

3
@parasrish Sì, sono già occupati delle tue precedenti fusioni. Quindi hai apportato modifiche a, b, c, d dal ramo (b1). Hai scelto solo "c". Quindi, in futuro, una volta che si unisce da (b1) a master, poiché le modifiche "c" sono uguali, si uniranno solo le modifiche a, b, d e rimarranno le modifiche "c". Ma se esegui il rollback della tua unione, tornerai indietro alle modifiche con "c" al suo interno. Dovrai ripristinarli separatamente.
Teoman Shipahi,

12
Va sottolineato: nell'esempio dato, solo la differenza (F - E) viene applicata a Z. Questo è un caso ristretto. Cherry-pick può essere usato per applicare le differenze di più commit, diciamo, tutte le differenze tra due commit non adiacenti. Ad esempio, seguendo da sopra, (F - E), (E - D), (D - C) e (C - B). Ciò equivale ad applicare la differenza (F - B).
Thomas Bitonti,

2
Inoltre, cosa succede se Commit selezionato (F nell'esempio) ha più di un predecessore immediato?
Thomas Bitonti,

2
@ j2emanue in altre parole, cherry-pick prenderà solo le modifiche dell'ultimo commit. Se commetti 3 volte diverse e se scegli l'ultima, non verranno apportate modifiche al primo e al secondo commit. Il comando Unisci prenderà tutte le modifiche e si applicherà al ramo di destinazione (principale).
Teoman Shipahi

157

La raccolta delle ciliegie in Git è progettata per applicare un commit da un ramo a un altro ramo. Si può fare se es. ha commesso un errore e ha commesso una modifica nel ramo sbagliato, ma non desidera unire l'intero ramo. Puoi semplicemente es. ripristina il commit e selezionalo su un altro ramo.

Per usarlo, hai solo bisogno git cherry-pick hash, dov'è hashun hash di commit da un altro ramo.

Per la procedura completa, consultare: http://technosophos.com/2009/12/04/git-cherry-picking-move-small-code-patches-across-branches.html


96

Breve esempio di situazione, quando hai bisogno di una ciliegia

Prendi in considerazione il seguente scenario. Hai due rami.

a) release1 - Questa filiale andrà al tuo cliente, ma ci sono ancora alcuni bug da correggere.

b) master - ramo master classico, dove ad esempio è possibile aggiungere funzionalità per release2.

SOCIETÀ : È aggiustare qualcosa in RELEASE1 . Naturalmente hai bisogno di questa correzione anche in master . E questo è un tipico caso d'uso per la raccolta delle ciliegie. Quindi in questo scenario la scelta della ciliegia significa che prendi un commit dal ramo release1 e lo includi nel ramo master .


3
Potresti aver bisogno solo dell'altro modo. Hai risolto un bug nel master e dovresti selezionarlo per rilasciare1. Inoltre potrebbero essere repository piuttosto che rami
canbax,

1
Perché non usare Merge per questo?
FreeLightman

Vorrei: creare il ramo off release, correggerlo nel ramo, unire il ramo nel rilascio, unire il rilascio nel master.
Jasper-M,

57

cherry-pick è una funzionalità Git. Se qualcuno desidera eseguire il commit di commit specifici in un ramo in un ramo di destinazione, viene utilizzato cherry-pick.
i passaggi git cherry-pick sono i seguenti.

  1. checkout (passa a) ramo target.
  2. git cherry-pick <commit id>
    

    Qui commit id è l'id di attività di un altro ramo.

    git cherry-pick 9772dd546a3609b06f84b680340fb84c5463264f
    
  3. spingere verso il ramo di destinazione

Visita https://git-scm.com/docs/git-cherry-pick


44

Ho preparato illustrazioni dettagliate su ciò che Cherry-Pick fa - e un'animazione di queste illustrazioni (verso la fine).

  1. Prima della raccolta delle ciliegie
    (faremo una raccolta delle ciliegie del commit Ldal ramo feature): inserisci qui la descrizione dell'immagine

  1. Avvio del comando git cherry-pick feature~2
    ( feature~2è il 2 ° commit precedente
    feature, ovvero il commit L): inserisci qui la descrizione dell'immagine

  1. Dopo aver eseguito il comando ( git cherry-pick feature~2): inserisci qui la descrizione dell'immagine

Lo stesso animato: inserisci qui la descrizione dell'immagine


Nota:

Il commit L'è dal punto di vista dell'utente (commit = snapshot) la copia esatta del commit L.

Tecnicamente (internamente), è un nuovo, diverso commit (perché ad esempio Lcontiene un puntatore a K(come suo genitore), mentre L'contiene un puntatore a E).


Vuol dire che L 'sarà N -> M -> L sul branch master? o porterà esclusivamente il commit L sul ramo principale
Priyank Thakkar il

1
@PriyankThakkar, sì, esclusivamente L , nient'altro (come puoi vedere dalle immagini / animazioni).
MarianD

22

Puoi pensare se una scelta di ciliegia è simile a una rebase, o meglio è gestita come una rebase. Con questo intendo che richiede un commit esistente e lo rigenera assumendo, come punto di partenza, il capo del ramo in cui ci si trova attualmente.

A rebaseaccetta un commit che aveva un genitore X e rigenera il commit come se avesse effettivamente un genitore Y, e questo è esattamente ciò che uncherry-pick fa .

Cherry Pick è più su come selezionare gli commit. Con pull(rebase), git rigenera implicitamente i tuoi commit locali oltre a ciò che è stato attirato nel tuo ramo, ma concherry-pick te scegli esplicitamente alcuni commit e rigenerali implicitamente (loro) sopra il tuo ramo corrente.

Quindi il modo in cui lo fai differisce, ma sotto il cofano sono operazioni molto simili: la rigenerazione degli impegni.


1
Trovo che sia una visione abbastanza utile delle cose. Implica il motivo per cui cherry-picksi comporta come quando il ramo di destinazione viene successivamente ricongiunto nel ramo di origine. Grazie Signore.
Aluan Haddad,

3
Vorrei usare Cherry Pick invece di Git Merge dopo aver completato una funzione. tutti fanno sempre git merge feature_branch quando completano una funzione. perché non usare il comando cherry-pick? hai qualche idea? perché preoccuparsi di schiacciare mi impegna se posso scegliere la ciliegia
j2emanue,

11

È un po 'come Copia (da qualche parte) e Incolla (da qualche parte), ma per commit specifici.

Se si desidera eseguire una correzione rapida, ad esempio, è possibile utilizzare cherry-pick funzione.

Fai il tuo cherry-pickin un ramo di sviluppo e mergeche si impegnano in un ramo di rilascio. Allo stesso modo, esegui un passaggio cherry-pickdal ramo di rilascio al master. Ecco


11

Quando lavori con un team di sviluppatori su un progetto, gestire le modifiche tra un numero di rami git può diventare un'attività complessa. A volte non vuoi unire un intero ramo in un altro e devi solo selezionare uno o due commit specifici. Questo processo è chiamato "cherry picking".

Ho trovato un ottimo articolo sulla raccolta delle ciliegie, guardalo per dettagli dettagliati: https://www.previousnext.com.au/blog/intro-cherry-picking-git


7

Se si desidera unire senza commit ID è possibile utilizzare questo comando

git cherry-pick master~2 master~0

Il comando precedente unirà gli ultimi tre commit del master da 1 a 3

Se si desidera eseguire questa operazione per un singolo commit, rimuovere l'ultima opzione

git cherry-pick master~2

In questo modo unirai il 3o commit dalla fine del master.


Questo è confusionario. Penso che qui sei su un ramo diverso dal maestro, giusto? E quando hai citato due commit ti riferisci ai <from> e <to> commit per definire l'intervallo che vuoi selezionare. Corretta? Sarebbe di grande aiuto se lo scenario fosse descritto. Buona aggiunta però. Grazie.
Saurabh Patil,

6

Applicherà un commit particolare alla tua filiale corrente.

Questo significa :

  • verranno aggiunti tutti i file aggiunti da questo commit
  • tutti i file eliminati da questo commit verranno eliminati
  • tutti i file modificati da questo commit verranno uniti. Ciò significa che l'intero file dal commit, non solo le modifiche da questo commit!

Es: considerare il commit A

added newFileA
modified main:
+ import './newFileA'

commettere B

added newFileB
modified main:
+ import './newFileB'

Se scegli il commit B su un altro ramo, finirai con:

/newFileB
/main :
   import './newFileA'
   import './newFileB'

poiché commit B contiene newFileB e main , ma non newFileA , con conseguente errore, quindi utilizzare con cautela.


0

Estratto dai documenti ufficiali:

Dati uno o più commit esistenti, applica la modifica che ognuno introduce, registrando un nuovo commit per ciascuno. Ciò richiede che l'albero di lavoro sia pulito (nessuna modifica dal commit HEAD).

Quando non è ovvio come applicare una modifica, si verifica quanto segue:

  1. Il ramo corrente e il puntatore HEAD rimangono all'ultimo commit eseguito correttamente.

  2. Il riferimento CHERRY_PICK_HEAD è impostato per indicare il commit che ha introdotto la modifica che è difficile da applicare.

  3. I percorsi in cui la modifica applicata in modo pulito vengono aggiornati sia nel file indice che nell'albero di lavoro.

  4. Per percorsi in conflitto, il file indice registra fino a tre versioni, come descritto nella sezione "VERO MERGE" di git-merge. I file dell'albero di lavoro includeranno una descrizione del conflitto racchiusa tra i soliti marker di conflitto <<<<<<< e >>>>>>>.

Non vengono apportate altre modifiche.

Leggi di più...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.