Perché git revert si lamenta di un'opzione -m mancante?


185

Quindi sto lavorando a un progetto con altre persone e ci sono più forcelle github su cui si sta lavorando. Qualcuno ha appena risolto un problema e mi sono unito alla sua forcella, ma poi ho capito che avrei potuto trovare una soluzione migliore. Voglio ripristinare il commit che ho appena fatto. Ho provato a farlo con git revert HEADma mi ha dato questo errore:

fatale: Commit <SHA1> è un'unione ma non è stata data alcuna opzione -m.

Cosa significa? Quando mi sono unito e impegnato, ho usato l'opzione -m per dire "Unita con <nomeutente>".

Cosa sto facendo di sbagliato qui?

Risposte:


217

Per impostazione predefinita, git revertrifiuta di ripristinare un commit di unione in quanto ciò che in realtà significa è ambiguo. Presumo che il tuo HEADsia in effetti un commit di merge.

Se si desidera ripristinare il commit di unione, è necessario specificare quale padre dell'unione si desidera considerare il trunk principale, ovvero a cosa si desidera ripristinare.

Spesso questo sarà il genitore numero uno, ad esempio se tu fossi attivo mastere lo facessi git merge unwantede poi decidessi di ripristinare l'unione di unwanted. Il primo genitore sarebbe il masterramo di pre-fusione e il secondo genitore sarebbe la punta di unwanted.

In questo caso potresti fare:

git revert -m 1 HEAD

4
Ok grazie. Ho trovato più semplice solo cambiare i due file interessati dall'unione e quindi eseguire il commit anche di alcune delle mie altre modifiche.
icnhzabot,

43
Dove posso trovare informazioni se devo usare -m1 o -m2, ...?
Patrick Cornelissen, il

34
git cat-file -p [MERGE_COMMIT_ID]mostrerà i rami principali in ordine. Il primo elencato sarebbe -m 1, il secondo -m 2.
nostromo,

2
git revert [HASH] -m 2mi sta dicendo sul ramo 1.x-1.x nulla da impegnare, directory di lavoro pulita ma il mio commit non viene ripristinato.
Jenlampton,

3
Quindi, se devo ripristinare le ultime 10 fusioni (il che è abbastanza probabile dal momento che git esegue automaticamente un'unione ogni volta che inserisco le modifiche da un altro sviluppatore), devo farlo per ogni singola unione? È per questo che i fan di Git sono così entusiasti del rebasing, perché il ripristino è sostanzialmente inutile?
Neutrino,

46

Dì che l'altro ragazzo ha creato la barra in cima a foo, ma nel frattempo hai creato baz e poi ti sei unito, dando una storia di

$ git lola
* 2582152 (HEAD, master) Unisci ramo 'altro guy'
| \  
| * barra c7256de (altro guy)
* | b7e7176 baz
| /  
* 9968f79 foo

Nota: git lola è un alias non standard ma utile.

Nessun dado con git revert:

$ git ripristina HEAD
fatale: Commit 2582152 ... è un'unione ma non è stata data l'opzione -m.

Charles Bailey ha dato una risposta eccellente come al solito. Usando git revertcome in

$ git revert --no-edit -m 1 HEAD
[master e900aad] Ripristina "Unisci ramo 'altro guy'"
 0 file modificati, 0 inserzioni (+), 0 eliminazioni (-)
 modalità di eliminazione 100644 bar

cancella efficacemente bare produce una storia di

$ git lola
* e900aad (HEAD, master) Ripristina "Unisci ramo 'altro guy'"
* 2582152 Unisci ramo 'altro guy'
| \  
| * barra c7256de (altro guy)
* | b7e7176 baz
| /  
* 9968f79 foo

Ma sospetto che tu voglia buttare via il commit della fusione:

$ git reset --hard HEAD ^
HEAD è ora su b7e7176 baz

$ git lola
* b7e7176 (HEAD, master) baz
| * barra c7256de (altro guy)
| /  
* 9968f79 foo

Come documentato nel git rev-parsemanuale

<rev>^, ad esempio HEAD ^,v1.5.1^0
un suffisso ^per un parametro di revisione indica il primo genitore dell'oggetto commit. ^<n>indica l' n -esimo genitore ( cioè <rev>^ equivale a <rev>^1). Come regola speciale, <rev>^0indica il commit stesso e viene utilizzato quando <rev>è il nome oggetto di un oggetto tag che fa riferimento a un oggetto commit.

così prima di invocare git reset, HEAD^(o HEAD^1) era b7e7176 ed HEAD^2era c7256de, cioè rispettivamente il primo e il secondo genitore del commit di merge.

Fai attenzione git reset --hardperché può distruggere il lavoro.


3
È un mondo confuso, confuso, scosso. Tranne Lola. Grazie mille per questo fantastico alias.
Barney,

Modo semplice per aggiungere lolaai comandi git:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D. Gibbs,

8

Ho avuto questo problema, la soluzione era guardare il grafico di commit (usando gitk) e vedere che avevo il seguente:

*   commit I want to cherry-pick (x)
|\  
| * branch I want to cherry-pick to (y)
* | 
|/  
* common parent (x)

Adesso capisco che voglio fare

git cherry-pick -m 2 mycommitsha

Questo perché -m 1si fonderebbero in base al genitore comune dove come si -m 2fonde in base al ramo y, quello è quello che voglio scegliere.


1
Forse perché non è correlato git-revert, ed è di questo che tratta questa domanda.
pnomolos,

1
Penso che questa domanda riguardi l' -mopzione, non esclusivamente git merge. Vale a dire, il ragionamento alla base dell'uso -mdell'opzione sembrerebbe simile per i ripristini e le scelte positive. Se questo non è vero, faccelo sapere. Dal momento che non ho trovato altre domande che si rivolgono in modo specifico al suo utilizzo, grazie per questa risposta, che probabilmente ha portato Google a aiutarmi a trovare questa domanda e una discussione utile e pertinente!
nealmcb,
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.