2012-09-27 12 views
50

Quindi ho già fatto innumerevoli scelte piccanti e sembra che adesso non riesca a fallire in questo momento, sto provando a selezionare da un ramo all'altro che dovrebbe essere facile, come mai ho avuto un errore sul fatto che si trattava di unire ma non -m è stato dato?Sintassi git cherry-pick e fusione dei rami

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 
error: Commit a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 is a merge but no -m option was given. 
fatal: cherry-pick failed 

Che sembra sbagliato ....... dovrebbe essere:

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 

Da quando devo fornire una funzione -m?

risposta

64

È necessario fornire -m se il commit è un commit , ad esempio un commit con più di un genitore.

Normalmente, ciò git cherry-pick REV non può essere descritto come:

  1. Prendere i cambiamenti tra rev e il suo genitore.

  2. Applicare queste modifiche al TESTO corrente e confermare il risultato con il messaggio di commit rev.

Un commit di unione unisce due linee di sviluppo. Ad esempio, una riga implementa il widget e l'altra linea rimuove il disordine. L'unione ti dà il codice con il widget, senza l'ingombro.

Considerare ora il passaggio 1 del processo di selezione rapida: git non può indovinare se si desidera rimuovere la confusione o implementare il widget. Né si può fare entrambe le cose, perché le informazioni su come fare entrambe le cose, non è contenuta all'interno di un singolo merge commit, solo il contenuto della risultante fuse albero è.

L'opzione -m consente di dire git come procedere. Ad esempio, se la rimozione del clutter si è verificata su master e il commit di unione è stato creato utilizzando git merge WIDGET, quindi git cherry-pick -m 1 merged-commit selezionerà il nuovo widget perché la differenza tra l'albero unito e il padre 1 (l'ultimo dei commit di rimozione del disordine) sarà stata esattamente la aggiunta di widget.D'altra parte, git cherry-pick -m 2 merge-commit eliminerà la confusione, perché la differenza tra padre 2 (l'ultimo del widget-aggiunta commette) e merge-commit è esattamente la rimozione di ingombro mancante dal ramo del widget.

+2

Per verificare 'git cherry-pick' ha fatto ciò che intendevi fare, esegui' git mostra' prima di spingere; questo ti mostrerà il diff di ciò che sta per essere spinto. – Jimothy

+1

Per quello che vale, il ripristino di un merge commette ha esattamente le stesse considerazioni e l'argomento della riga di comando richiesto per avere successo. – ErikE

+2

E se volessi inserire sia widget-aggiunta che cancellazione-clutter? questo è il punto in cui si sceglie il commit di merge giusto? altrimenti, selezionerei l'ultimo commit dell'aggiunta del widget o l'ultimo commit della cancellazione del clutter invece – Zennichimaro

2

La sintassi dalle pagine man è la seguente:

git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>... 

Il genitore-numero si riferisce a:

-m genitore-numero, --mainline genitore-numero, di solito non è possibile cherry-pick una fusione, perché non si sa da che parte della fusione dovrebbe essere considerata la linea principale. Questa opzione specifica il numero genitore (a partire dal 1) della linea principale e permette ciliegio pick per riprodurre il cambiamento relativo all'elemento principale specificato.

Quindi vorrei ricontrollare per assicurarmi di avere l'hash di commit corretto. Potrebbe essere che si desidera uno che non è da una fusione, ma piuttosto il commit prima di esso. In caso contrario, è necessario utilizzare questo flag e puntare al lato corretto della fusione per disambiguare la vostra richiesta.

3

Personalmente quello che faccio normalmente è che dal momento che un'unione combina 2 commit, ad esempio se ho un merge commit C che è composto da 2 genitori ad esempio commit A in master e commit B dall'altro ramo che viene unito, se ho bisogno per scegliere l'unione non mi preoccuperei del comando confuso di cherry pick the merge commit in se stesso, ma invece vorrei solo citare ciascuno dei genitori A e B individualmente, questo è anche utile in una situazione in cui si desidera solo selezionare la ciliegia commit B solo nel caso in cui il commit A da master è già stato selezionato nel ramo a cui si sta eseguendo il cherry picking prima che avvenisse l'unione.

0

tenta di unire risultato:

git cherry-pick .... 
git mergetool 
git cherry-pick --continue 
14

GIT richiede di specificare il numero genitore (-m), perché la stampa commettere ha due genitori e git non sanno da che parte della fusione dovrebbe essere considerato la linea principale. Quindi, utilizzando questa opzione, è possibile specificare il numero genitore (a partire da 1) della linea principale e il selettore di selezione per riprodurre la modifica relativa al genitore specificato.

Per scoprire il vostro commettere genitori, provare uno:

git show --pretty=raw <merge_commit> 

o:

git cat-file -p <merge_commit> 

o anche per una migliore visibilità GUI, tenta:

gitk <merge_commit> 

Come risultato, si dovrebbe ottenere qualcosa come:

commit fc70b1e9f940a6b511cbf86fe20293b181fb7821 
tree 8d2ed6b21f074725db4f90e6aca1ebda6bc5d050 
parent 54d59bedb9228fbbb9d645b977173009647a08a9 = <parent1_commit> 
parent 80f1016b327cd8482a3855ade89a41ffab64a792 = <parent2_commit> 

Poi controlla i tuoi ogni dettaglio genitore da:

git show <parent1_or_2_commit> 

Aggiungi --stat per vedere la lista dei file modificati.

o utilizzare il seguente comando per confrontare i cambiamenti (sulla base del genitore di cui sopra):

git diff <parent1_or_2_commit>..<commit> 

Aggiungi --stat per vedere la lista dei file modificati.

o utilizzare il diff combinato per confrontare i due genitori da:

git diff --cc <parent1_commit> 
git diff --cc <parent2_commit> 

quindi specificare il numero genitore a partire dal 1 per il cherry-pick, per esempio

git cherry-pick -m 1 <merge_commit> 

Poi gestita git status per vedere cosa sta succedendo. Se non vuoi ancora confermare le modifiche, aggiungi l'opzione -n per vedere cosa succede. Quindi, quando non sei felice, reimposta su HEAD (git reset HEAD --hard).Se ottieni conflitti di git, probabilmente dovrai risolverli manualmente o specificare la strategia di unione (-X), vedi: How to resolve merge conflicts in Git?