Dlaczego git revert narzeka na brakującą opcję -m?

185

Pracuję więc nad projektem z innymi ludźmi i pracuję nad wieloma widelcami github. Ktoś właśnie naprawił problem i połączyłem się z jego widelcem, ale potem zdałem sobie sprawę, że mogę znaleźć lepsze rozwiązanie. Chcę cofnąć właśnie zatwierdzone zatwierdzenie. Próbowałem to zrobić, git revert HEADale otrzymałem ten błąd:

fatal: Commit <SHA1> to scalenie, ale nie podano opcji -m.

Co to znaczy? Kiedy się połączyłem i zatwierdziłem, użyłem opcji -m, aby powiedzieć „Połączono z <nazwa_użytkownika>”.

Co robię tutaj źle?

icnhzabot
źródło

Odpowiedzi:

217

Domyślnie git revertodmawia cofnięcia zatwierdzenia scalania, ponieważ to, co tak naprawdę oznacza, jest niejednoznaczne. Zakładam, że HEADw rzeczywistości jest to zatwierdzenie przez scalenie.

Jeśli chcesz cofnąć zatwierdzenie scalania, musisz określić, który rodzic scalenia, który chcesz uznać za główny pień, tj. Do czego chcesz przywrócić.

Często będzie to rodzic numer jeden, na przykład jeśli byłeś włączony masteri zrobiłeś, git merge unwanteda następnie postanowiłeś cofnąć scalenie unwanted. Pierwszy rodzic byłby twoją mastergałęzią przed scalaniem, a drugi rodzic byłby wierzchołkiem unwanted.

W takim przypadku możesz wykonać:

git revert -m 1 HEAD
CB Bailey
źródło
4
Ok dzięki. Łatwiej mi było po prostu zmienić dwa pliki, na które miało wpływ scalanie, a następnie zatwierdzić niektóre inne moje zmiany.
icnhzabot
43
Gdzie mogę znaleźć informacje, czy muszę użyć opcji -m1 czy -m2, ...?
Patrick Cornelissen,
34
git cat-file -p [MERGE_COMMIT_ID]pokaże gałęzie nadrzędne w kolejności. Pierwszy z wymienionych będzie -m 1, drugi -m 2.
nostromo
2
git revert [HASH] -m 2mówi mi W gałęzi 1.x-1.x nic do zatwierdzenia, katalog roboczy jest czysty, ale moje zatwierdzenie nie zostało przywrócone.
jenlampton
3
Więc jeśli muszę przywrócić poprzednie 10 scaleń (co jest całkiem prawdopodobne, ponieważ git wykonuje scalanie automatycznie za każdym razem, gdy ściągam zmiany od innego programisty), muszę to robić dla każdego scalenia? Czy dlatego fani git są tak chętni do bazowania, ponieważ powrót jest w zasadzie bezużyteczny?
Neutrino,
46

Powiedzmy, że ten drugi facet stworzył pasek na foo, ale w międzyczasie stworzyłeś baz, a następnie połączyłeś się, dając historię

$ git lola
* 2582152 (HEAD, master) Scal gałąź „otherguy”
| \  
| * Pasek c7256de (otherguy)
* | b7e7176 baz
| /  
* 9968f79 foo

Uwaga: git lola to niestandardowy, ale użyteczny alias.

Brak kości z git revert:

$ git przywróć HEAD
fatal: Commit 2582152 ... to scalenie, ale nie podano opcji -m.

Charles Bailey jak zwykle udzielił doskonałej odpowiedzi . Używanie git revertjak w

$ git revert --no-edit -m 1 HEAD
[master e900aad] Przywróć „Scal gałąź„ otherguy ””
 0 plików zmienionych, 0 wstawek (+), 0 usunięć (-)
 tryb kasowania 100644 bar

skutecznie usuwa bari tworzy historię

$ git lola
* e900aad (HEAD, master) Cofnij „Scal gałąź„ otherguy ””
* 2582152 Scal oddział „otherguy”
| \  
| * Pasek c7256de (otherguy)
* | b7e7176 baz
| /  
* 9968f79 foo

Ale podejrzewam, że chcesz wyrzucić zatwierdzenie scalania:

$ git reset --hard HEAD ^
HEAD jest teraz na bazie b7e7176

$ git lola
* b7e7176 (HEAD, master) baz
| * Pasek c7256de (otherguy)
| /  
* 9968f79 foo

Jak udokumentowano w git rev-parseinstrukcji

<rev>^, np. HEAD ^,v1.5.1^0
sufiks ^parametru rewizji oznacza pierwszego rodzica tego obiektu zatwierdzenia. ^<n>oznacza n- ty rodzic ( tj. <rev>^ jest równoważny <rev>^1). Jako specjalna zasada <rev>^0oznacza samo zatwierdzenie i jest używane, gdy <rev>jest nazwą obiektu znacznika, który odnosi się do obiektu zatwierdzenia.

więc przed wywołaniem git reset, HEAD^(a HEAD^1) był b7e7176 i HEAD^2był c7256de, to znaczy , odpowiednio, pierwsze i drugie rodzice seryjnej zatwierdzenia.

Bądź ostrożny, git reset --hardponieważ może zniszczyć pracę.

Greg Bacon
źródło
3
To świat pomieszany, zamazany, wstrząśnięty. Z wyjątkiem Loli. Dzięki milion za ten fantastyczny alias.
Barney
Łatwy sposób na loladodanie do poleceń git:git config --global alias.lola "log --graph --decorate --pretty=oneline --abbrev-commit --all"
D. Gibbs
8

Miałem ten problem, rozwiązaniem było przyjrzeć się grafowi zatwierdzeń (używając gitk) i zobaczyć, że mam następujące:

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

Teraz rozumiem, że chcę to zrobić

git cherry-pick -m 2 mycommitsha

Wynika to z faktu, -m 1że łączyłby się na podstawie wspólnego elementu nadrzędnego, gdzie podczas scalania na -m 2podstawie gałęzi y, to jest ten, który chcę wybrać.

shmish111
źródło
1
Być może dlatego, że nie jest to związane z tym git-revert, o co chodzi w tym pytaniu.
pnomolos
1
Myślę, że to pytanie dotyczy -mopcji, a nie wyłącznie git merge. Tj. Uzasadnienie zastosowania tej -mopcji wydaje się podobne w przypadku zwrotów i wyborów wiśniowych. Jeśli to nieprawda, daj nam znać. Ponieważ nie znalazłem żadnych innych pytań, które konkretnie dotyczyłyby tego wybitnego wyboru, dziękuję za tę odpowiedź, która prawdopodobnie doprowadziła google do pomocy w znalezieniu tego pytania i przydatnej, odpowiedniej dyskusji!
nealmcb