Przywróć zakres zatwierdzeń w git

127

Jak mogę cofnąć zakres zatwierdzeń w git? Patrząc na dokumentację gitrevisions , nie widzę, jak określić zakres, którego potrzebuję. Na przykład:

A -> B -> C -> D -> E -> HEAD

Chcę zrobić odpowiednik:

git revert B-D

gdzie wynik byłby:

A -> B -> C -> D -> E -> F -> HEAD

gdzie F zawiera odwrotność BD włącznie.

Alex Spurling
źródło
Pod koniec strony gitrevisions (7) znajduje się sekcja zatytułowana „OKREŚLANIE ZAKRESÓW”. W jaki sposób to, czego chcesz, różni się od tego, co tam opisano?
Gareth McCaughan,
2
Strona gitrevisions sugeruje, że 'git revert A..D' zrobi to, co chcę. Jednak gdy próbuję, pojawia się błąd „fatalny: nie można znaleźć„ A..D ””
Alex Spurling,

Odpowiedzi:

172

Jakiej wersji Git używasz?

Przywracanie wielu zatwierdzeń jest obsługiwane tylko w Git1.7.2 +: zobacz „Przywracanie starego zatwierdzenia przy użyciu wielokrotnego przywracania ”, aby uzyskać więcej informacji.
Bieżąca git revertstrona podręcznika dotyczy tylko aktualnej wersji Gita (1.7.4+).


Jako OP Alex Spurling relacjonuje w komentarzach:

Aktualizacja do wersji 1.7.4 działa dobrze.
Odpowiadając na moje własne pytanie, szukałem składni:

git revert B^..D 

B^oznacza „pierwszy nadrzędny zatwierdzenie B”: to pozwala na włączenie Bdo przywrócenia.
Zobacz git rev-parsesekcjęOKREŚLANIE WERSJI ”, która zawiera <rev>^np.HEAD^ Składnię: zobacz więcej w „ Co oznacza ^znak daszka ( )? ”)

Zauważ, że każde przywrócone zatwierdzenie jest zatwierdzane osobno.

Henrik N wyjaśnia w komentarzach :

git revert OLDER_COMMIT^..NEWER_COMMIT

Jak pokazano poniżej, możesz cofnąć przywracanie bez dokonywania od razu:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"
VonC
źródło
1
Dzięki, to była odpowiedź. Aktualizacja do wersji 1.7.4 działa dobrze. Odpowiadając na moje własne pytanie, szukałem składni: git revert B ^ .. D
Alex Spurling
geniusz. dzięki. Nie przyszło mi do głowy, że muszę cofnąć zatwierdzenia w odwrotnej kolejności, aby poprawki zostały nałożone. To polecenie wskazuje drogę.
Tim Abell
5
Często wracam do tej odpowiedzi i zawsze zajmuje mi trochę czasu, zanim wymyślę kolejność. Tak więc, aby pomóc mojemu przyszłemu ja:git revert OLDER_COMMIT^..NEWER_COMMIT
Henrik N
2
co oznacza ^?
Dustin Getz
1
@DustinGetz pierwszy rodzic: patrz git-scm.com/docs/gitrevisions : "Sufiks ^do parametru wersji oznacza pierwszego rodzica tego obiektu zatwierdzenia".
VonC
15

Jeśli chcesz przywrócić zakres zatwierdzenia B do D (przynajmniej w wersji 2 git) w pojedynczym zatwierdzeniu, możesz zrobić

 git revert -n B^..D

Powoduje to cofnięcie zmian dokonanych przez zatwierdzenia z zatwierdzenia rodzica B (wykluczone) do zatwierdzenia D (uwzględnione), ale nie tworzy żadnego zatwierdzenia z cofniętymi zmianami. Przywrócenie modyfikuje tylko drzewo robocze i indeks.

Nie zapomnij o zatwierdzeniu zmian później

 git commit -m "revert commit range B to D"

Możesz również cofnąć wiele niepowiązanych zatwierdzeń w jednym zatwierdzeniu, używając tej samej metody. na przykład, aby przywrócić B i D, ale nie C

 git revert -n B D
 git commit -m "Revert commits B and D"

Odniesienie: https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

Dzięki Honza Haering za korektę

Ramast
źródło
3
git revert -n B..Dnie powracają popełnienia B, C i D. tylko git revert -n B^..Dpowraca B a.
Honza Haering
zgodnie z dokumentacją git. odniesienie w poście
Ramast
1
Jeśli odwołujesz się do tego przykładu (który myślę, że jest nieco zagmatwany) w odnośniku git revert -n master~5..master~2:, jest tam napisane, że zawiera piąte najnowsze zatwierdzenie. Ale master~5tak naprawdę jest szóstym ostatnim zatwierdzeniem. Zobacz wybór wersji w dokumentacji git, aby uzyskać szczegółowe informacje o ..notacji :-)
Honza Haering
6

To git revert OLDER_COMMIT^..NEWER_COMMITnie działa dla mnie.

Użyłem git revert -n OLDER_COMMIT^..NEWER_COMMITi wszystko jest w porządku. Używam wersji git 1.7.9.6.

Orlando
źródło
Miałem ten sam problem i napraw go za pomocą -n, ale powinieneś zostawić ^ z OLDER_COMMIT (git revert -n OLDER_COMMIT ^ .. NEWER_COMMIT).
FeelGood
@FeelGood dlaczego powinieneś opuścić ^?
Orlando
Miałem historię A -> B -> C i celem było przywrócenie B i C. Kiedy uruchomiłem 'git revert -n B..C', tylko C zostało przywrócone. Kiedy użyłem 'git revert -n B ^ .. C', git przywrócił oba zatwierdzenia. Może zrobiłem coś złego.
FeelGood
fajnie, muszę to przetestować, ale myślę, że w moim przypadku działało dobrze (chyba, że ​​przywracałem 1 zakres zatwierdzenia lol) zmodyfikuję odpowiedź, aby uwzględnić ^. dzięki
Orlando
2
Opcja -nlub --no-commitprzywróci wszystkie zmiany w zakresie w pojedynczym zatwierdzeniu, zamiast tworzyć odwrócone zatwierdzenie dla każdego zatwierdzenia w zakresie. Wynik końcowy jest taki sam, jak w programie, te same zmiany zostaną cofnięte. Zależy tylko, jak chcesz, aby wyglądała Twoja historia git.
Dennis
0

Służy git rebase -ido zgniatania odpowiednich zatwierdzeń w jedno. Wtedy masz tylko jedno zobowiązanie do przywrócenia.

Graham Borland
źródło
7
Jeśli używasz git rebase, możesz po prostu usunąć zatwierdzenia. Myślę, że jest powód, aby nie zmieniać bazy, na przykład chcąc zachować SHA1 zatwierdzenia F.
Paŭlo Ebermann
5
Alternatywnie, zmiażdż powracające zatwierdzenia w jedno.
aeosynth