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.


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"

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ę


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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.