Mercurial - przywróć starą wersję i kontynuuj od tego momentu

249

Korzystam z Mercurial lokalnie do projektu (jest to jedyne repozytorium, w którym nie ma pchania / ciągnięcia do / z jakiegokolwiek innego miejsca).

Do tej pory ma liniową historię. Jednak obecna rzecz, nad którą teraz pracuję, uświadomiłem sobie, że jest to okropne podejście i chcę wrócić do wersji przed jej uruchomieniem i zaimplementować ją w inny sposób.

Jestem trochę mylony z poleceniami branch/ revert/ update -Cw Mercurial. Zasadniczo chcę wrócić do wersji 38 (obecnie 45) i moje następne commity mają 38 jako rodzic i kontynuują od tego momentu. Nie dbam o to, czy wersje 39-45 zostaną utracone na zawsze, czy też skończą się w ślepej uliczce.

Jakiego polecenia / zestawu poleceń potrzebuję?

Paolo
źródło
6
Dla wszystkich zainteresowanych pojawiło się to na powiązanym pasku bocznym, który jest doskonałym wytłumaczeniem cofnięcia vs aktualizacji: stackoverflow.com/questions/2506803/…
Paolo

Odpowiedzi:

150
hg update [-r REV]

Jeśli później zatwierdzisz, skutecznie utworzysz nowy oddział. Następnie możesz kontynuować pracę tylko nad tym oddziałem lub ewentualnie połączyć istniejący z nim.

awangarda
źródło
6
następne zatwierdzenie utworzy nowy oddział. Jeśli nie masz pewności, po prostu wykonaj kopię zapasową swojego repozytorium (z kopią roboczą), wypróbuj go - nie podoba ci się wynik -> zacznij od zera bez żadnych kosztów
van
Jest to wątpliwa odpowiedź, ponieważ łączy bieżące zmiany ze starą wersją, która prawdopodobnie nie jest tym, czego nie chcesz robić. Prawidłowa odpowiedź powinna zostać cofnięta.
Trevor de Koekkoek
Odpowiedź jest w porządku, z wyjątkiem fragmentu dotyczącego scalania (nie sądzę, aby pytający chciał scalić).
ctrl-alt-delor
3
@NeonWarge REV to po prostu symbol zastępczy dla wersji. Może to być jego numer, skrót, zakładka i tak dalej. Trevor: nie jest to wątpliwe, ponieważ niczego nie łączy. Bez konieczności.
DanMan
401

Oto ściągawka na polecenia:

  • hg updatezmienia wersję nadrzędną kopii roboczej, a także zmienia zawartość pliku, aby pasowała do tej nowej wersji nadrzędnej. Oznacza to, że nowe zatwierdzenia będą kontynuowane od zaktualizowanej wersji.

  • hg revertzmienia tylko zawartość pliku i pozostawia samą wersję nadrzędną kopii roboczej. Zazwyczaj używasz tego, hg revertgdy decydujesz, że nie chcesz zachować niezatwierdzonych zmian, które wprowadziłeś w pliku w kopii roboczej.

  • hg branchuruchamia nowy nazwany oddział. Pomyśl o nazwie gałęzi jako etykiecie, którą przypisujesz do zestawów zmian. Jeśli tak hg branch red, to następujące zestawy zmian zostaną oznaczone jako należące do „czerwonej” gałęzi. Może to być dobry sposób na organizowanie zestawów zmian, szczególnie gdy różne osoby pracują w różnych gałęziach, a później chcesz sprawdzić, skąd pochodzi zestaw zmian. Ale nie chcesz go używać w swojej sytuacji.

Jeśli użyjesz hg update --rev 38, to zestawy zmian 39–45 zostaną pozostawione jako ślepy zaułek - zwisająca głowa, jak to nazywamy. Otrzymasz ostrzeżenie, gdy będziesz pchać, ponieważ będziesz tworzyć „wiele głów” w repozytorium, do którego pchasz. Jest to ostrzeżenie, ponieważ jest to trochę niegrzeczne, aby pozostawić takie głowy, ponieważ sugerują, że ktoś musi wykonać scalenie. Ale w twoim przypadku możesz po prostu iść naprzód, a hg push --forceponieważ naprawdę chcesz pozostawić go wisi.

Jeśli jeszcze nie wysłałeś wersji 39-45 w inne miejsce, możesz zachować ich prywatność. To bardzo proste: hg clone --rev 38 foo foo-38otrzymasz nowy lokalny klon, który zawiera tylko wersję 38. Możesz kontynuować pracę foo-38i wypychać nowe (dobre) zestawy zmian, które tworzysz. Nadal będziesz mieć stare (złe) wersje w swoim fooklonie. (Możesz zmienić nazwę klonów w dowolny sposób, np. fooNa foo-badi foo-38na foo.)

Na koniec możesz także użyć, hg revert --all --rev 38a następnie zatwierdzić. Spowoduje to utworzenie wersji 46, która wygląda identycznie jak wersja 38. Następnie będziesz kontynuować pracę od wersji 46. To nie stworzy rozwidlenia w historii w taki sam wyraźny sposób, jak to hg updatezrobiono, ale z drugiej strony nie będziesz narzekać na to, że masz wiele głów. Przydałby mi się, hg revertgdybym współpracował z innymi, którzy już stworzyli własną pracę na podstawie wersji 45. W przeciwnym razie hg updatejest bardziej wyraźna.

Martin Geisler
źródło
2
NIESAMOWITA odpowiedź. Użyłem hg revert --all --rev ## i uratowałem sobie tyłek: D
Van Thoai Nguyen
1
Czy nie byłoby lepiej zamknąć gałąź zwisającej głowy? Pozwoliłoby to uniknąć przyszłych ostrzeżeń w repozytorium. Zobacz stackoverflow.com/a/3688320/900130
Zoltán
Uwaga: hg revert --all --rev xxx zmodyfikuje lokalne pliki potrzebne do przywrócenia z lokalnego repozytorium. Musisz więc zaktualizować wcześniej miejsce, z którego chcesz wrócić.
Vincent
Aby rozgałęzić wcześniejszą wersję, najpierw musiałem cofnąć, a następnie zaktualizować. To powiedziawszy, mniej niejasne wyjaśnienie niż większość.
CodeLurker
30

Właśnie spotkałem się z przypadkiem konieczności przywrócenia tylko jednego pliku do poprzedniej wersji, zaraz po tym, jak wykonałem zatwierdzenie i wypchnięcie. Skrócona składnia do określania tych wersji nie jest objęta innymi odpowiedziami, więc oto polecenie, aby to zrobić

hg revert path/to/file -r-2

Że -2powróci do wersji przedostatni popełnienia, używając -1po prostu przywrócić bieżące zmiany niezatwierdzone.

hyde
źródło
1
Uważam to za niezwykle przydatne. Oczywiście dla opcji -r możesz po prostu podać numer wersji
Alex
Możesz także wybrać konkretną wersję. np.hg revert path/to/file -r478
Matt
7

IMHO, hg strip -r 39lepiej pasuje do tej skrzynki.

Wymaga włączenia rozszerzenia mq i ma te same ograniczenia co „metoda klonowania repozytorium” zalecana przez Martina Geislera: Jeśli zestaw zmian został w jakiś sposób opublikowany, (prawdopodobnie) w pewnym momencie powróci do repozytorium, ponieważ zmieniłeś tylko Twoje lokalne repozytorium.

Magras
źródło
Nie wiedziałem o tym. Łatwiejsze i czystsze niż usuwanie i ponowne klonowanie repozytorium. Dzięki.
Przywróć Monikę - nie
6

Po użyciu hg update -r REVnie było jasne w odpowiedzi na temat tego, jak zatwierdzić tę zmianę, aby można było dalej naciskać.

Jeśli po prostu spróbujesz zatwierdzić po aktualizacji, Mercurial nie podejrzewa żadnych zmian.

Musiałem najpierw wprowadzić zmiany do dowolnego pliku (powiedzmy w pliku README), aby Mercurial uznał, że dokonałem nowej zmiany, a następnie mógłbym ją zatwierdzić.

To stworzyło dwie głowy, jak wspomniano.

Aby pozbyć się drugiej głowy przed pchnięciem, podążyłem za krokiem No-Op Merges, aby naprawić tę sytuację.

Byłem wtedy w stanie naciskać.

Brian Gershon
źródło
możesz zrobić commit --close-branchna starej gałęzi. Możesz także push -fpopchnąć nowe głowy, ale może to powodować zamieszanie co do tego, który jest obecny.
ctrl-alt-delor
5

Powyższe odpowiedzi były najbardziej przydatne i wiele się nauczyłem. Jednak na moje potrzeby zwięzła odpowiedź brzmi:

hg revert --all --rev ${1}

hg commit -m "Restoring branch ${1} as default"

gdzie ${1}jest numer zmiany lub nazwa oddziału. Te dwie linie są w rzeczywistości częścią skryptu bash, ale same działają dobrze, jeśli chcesz to zrobić ręcznie.

Jest to przydatne, jeśli chcesz dodać poprawkę do gałęzi wydania, ale musisz budować domyślnie (dopóki nie uzyskamy poprawności naszych narzędzi CI i będziemy mogli budować z gałęzi, a później zrezygnować również z gałęzi wydania).

Brian Carr
źródło
1

Zainstalowałbym Tortoise Hg (darmowy GUI dla Mercurial) i użyłem go. Następnie możesz po prostu kliknąć prawym przyciskiem myszy wersję, do której możesz wrócić - ze wszystkimi komunikatami zatwierdzenia przed oczami - i „Przywrócić wszystkie pliki”. Sprawia, że ​​intuicyjne i łatwe jest przewijanie do tyłu i do przodu między wersjami zestawu plików, co może być bardzo przydatne, jeśli chcesz ustalić, kiedy problem pojawił się po raz pierwszy.

Geoff Kendall
źródło