W przypadku Mercurial, jak mogę „skompresować” serię zestawów zmian w jeden przed naciśnięciem?

96

Powiedzmy, że mam lokalne i zdalne repozytorium Mercurial. Teraz zaczynam pracę nad funkcją. Pracuję nad tym, a kiedy wydaje mi się, że jest skończony, zatwierdzam zestaw zmian. Testując to nieco dokładniej, stwierdziłem, że mogę dalej ulepszyć tę funkcję, poprawiając coś w kodzie. Dokonuję zmiany i zobowiązuję się. 20 minut później stwierdzam, że jest błąd w tej nowej funkcji, więc naprawiam go i też popełniam.

Mam teraz 3 zestawy zmian, które naprawdę chciałbym wypchnąć do zdalnego repozytorium jako jeden zestaw zmian z komunikatem na przykład „Implementing feature X”.

Jak mogę to zrobić bez większych kłopotów? Myślę, że mógłbym to zrobić z łatkami, ale wydaje mi się, że to dużo pracy.

Lucas
źródło
40
Najwyraźniej nie jest moim miejscem, aby odwieść Cię od prób kompresji zestawów zmian, ale możesz rozważyć, że połowa wartości kontroli wersji odpowiada „dlaczego”, a nie tylko „co” po miesiącach i latach. Dokładne przedstawienie tego, jak powstała funkcja i na jakich etapach może mieć przyszłą wartość. Odrzucenie tego wydaje się takie ... niekontrolowane.
Ry4an Brase
To prowadzi do kolejnego pytania ... Jaka jest różnica między „histedit” a „collapse”
sylvanaar
1
collapse zapewnia podzbiór funkcji histedit, a histedit ma znacznie bardziej intuicyjny UX.
Stefan Rusek
1
Zapewnia również mechanizm edycji połączonego komunikatu zestawu zmian.
Stefan Rusek
1
@ Ry4an: Właściwie, zgniatanie / zwijanie w niektórych przypadkach zwiększa znaczenie kontroli wersji. Bez zgniatania miałbym codziennie dwa zatwierdzenia, które nie mają nic wspólnego z funkcjami lub poprawkami błędów, ale służą do przenoszenia kodu z laptopa na komputer i odwrotnie. Po prostu dodają szum do historii wersji.
John Reynolds

Odpowiedzi:

39

A co z rozszerzeniem Collapse ?

Steve Losh
źródło
20
Pozdrowienia z przyszłości! Właśnie wyszukałem w Google tę samą funkcjonalność i najwyraźniej obecnie hg obsługuje to po wyjęciu z pudełka hg rebase --collapse. Sprawdź wiki hg na temat polecenia rebase. Ponieważ to pytanie jest trzecim ogólnym wynikiem wyszukiwania i pierwszym na stackoverflow, pomyślałem, że informacje mogą być przydatne.
a.peganz
1
Pozdrowienia z dalszej przyszłości !! Wydaje się, że rozszerzenie rebase jest przeznaczone wyłącznie do przenoszenia zestawów zmian z jednej gałęzi do drugiej. Tak, istnieje opcja --collapse, ale nadal wydaje się, że ma ona zastosowanie tylko w przypadku przenoszenia zestawu zmian między gałęziami. Zobacz < mercurial-scm.org/wiki/… >
Brad Oestreicher,
3
Można korzystać hg rebasez --collapsezasięgu jednej gałęzi.
UuDdLrLrSs
52

Histedit rozszerzenie jest dokładnie to, czego szukasz.

hg histedit -o

lub

hg histedit --outgoing

wyświetli listę wychodzących zestawów zmian. Z listy możesz

  • Złóż 2 lub więcej zestawów zmian, tworząc jeden pojedynczy zestaw zmian
  • Upuść zestawy zmian, usuwając je z historii
  • Zmień kolejność zestawów zmian, jak chcesz.

histedit zapyta cię o nowy komunikat zatwierdzenia zwiniętych zestawów zmian, który domyślnie przyjmuje dwa komunikaty z rozdzieleniem "\ n *** \ n".

Możesz również uzyskać podobne wyniki używając rozszerzenia mq, ale jest to o wiele trudniejsze.

Możesz także użyć rozszerzenia zwijania, aby po prostu zawinąć, ale nie zapewnia ono tak przyjemnego interfejsu użytkownika i nie zapewnia sposobu na edycję wynikowego komunikatu o zatwierdzeniu. Edycja wynikowego komunikatu o zatwierdzeniu pozwala również na wyczyszczenie ostatecznego komunikatu, z czego zawsze korzystam.

Stefan Rusek
źródło
dzięki, właśnie tego potrzebowałem. Byłoby miło, gdybyś mógł to zrobić z poziomu TortoiseHg - ale wiersz poleceń jest dość prosty.
sylvanaar
21

Tak, możesz to zrobić za pomocą poprawek: załóżmy, że Twoja praca obejmuje zestawy zmian od 100 do 110 włącznie

  1. Utwórz łatkę:

    % hg export -o mypatch 100:110 --git

  2. Zaktualizuj do 99:

    % hg update 99

  3. Zastosuj łatkę za pomocą --no-commit (w przeciwnym razie odzyskasz wszystkie zestawy zmian):

    % hg import --no-commit mypatch

  4. Zatwierdź wszystkie zmiany naraz:

    % hg commit

  5. Masz teraz dwie głowice (110 i 111), które powinny być równoważne pod względem plików, które tworzą w twoim katalogu roboczym - może porównaj je dla rozsądku przed usunięciem starych:

    % hg strip 100

OK, teraz, kiedy to wszystko przeliterowałem, wydaje się, że jest to długie, ale zrobiłem to kilka razy sam, nie uważam tego za zbyt trudne ...

Arkady
źródło
1
Świetna odpowiedź, ale jest warunek wstępny: rozszerzenie MQ musi być włączone .
Chris Kelly
Aby uwzględnić zmiany również w plikach binarnych, upewnij się, że używasz opcji --git: na przykład: „hg export -o mypatch 100: 110 --git” Aby uzyskać więcej informacji, zobacz: stackoverflow.com/a/12537738/ 367663 Pozwoliłem sobie poprawić odpowiedź.
Kharlos Dominguez
1
Wydaje się zbyt skomplikowane, dlaczego nie, hg strip --keepa potem popełnia wszystko w jednym zatwierdzeniu?
G. Demecki
@ G.Demecki Ponieważ jest to potencjalnie bardzo stratna operacja ..? Chociaż MQ to przesada (a nawet często nie jest zalecana), z wyjątkiem sytuacji, gdy pożądany jest taki przepływ pracy.
user2864740
@ user2864740 Możesz mieć rację, bo nie jestem ekspertem Mercurial. Ale domyślnie hg stripumieszcza kopię zapasową w .hg/strip-backup/katalogu. Wydaje mi się, że nie jest to takie bezpieczne, git reflogale nadal zapewnia pewien rodzaj ratunku.
G. Demecki
19

Jeśli używasz TortoiseHg, użyj można po prostu wybrać dwie wersje (użyj CTRL, aby wybrać inne niż kolejne), kliknij prawym przyciskiem myszy i wybierz "Kompresuj historię" .

Następnie otrzymasz nową listę zmian w nowej nagłówku, zaczynając od pierwszej zmiany, którą wybrałeś wcześniej, będzie ona zawierać wszystkie listy zmian podrzędnych między tymi, które wybrałeś.

Możesz po prostu usunąć stare listy zmian, jeśli już ich nie potrzebujesz: użyj do tego rozszerzeń MQ . Ponownie w TortoiseHg: kliknij prawym przyciskiem myszy pierwszą listę zmian, która ma zostać usunięta ze wszystkimi jej potomkami, "Modyfikuj historię -> Usuń" .

George Marian
źródło
18

Moją preferowaną metodą używania mq do tego składania jest użycie TortoiseHg, jak opisano tutaj . Można to jednak łatwo zrobić z wiersza poleceń, na przykład:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(Może istnieć lepszy sposób wykonania kroku qfold, ale nie jestem tego świadomy, ponieważ zwykle używam TortoiseHg do tej operacji.)

Na początku wydaje się to trochę skomplikowane, ale kiedy zaczniesz używać mq, jest to całkiem proste i naturalne - a ponadto możesz robić wiele innych rzeczy za pomocą mq, które mogą być bardzo przydatne!

Chris Phillips
źródło
4

hg collapsei hg histeditsą najlepszymi sposobami. A raczej byłyby to najlepsze sposoby, gdyby działały niezawodnie ... W histeditciągu trzech minut zderzyłem się ze zrzutem stosu.Collapsenie jest dużo lepsze.

Pomyślałem, że mogę podzielić się dwoma innymi BKM:

  1. hg rebase --collapse

    To rozszerzenie jest dystrybuowane z Mercurialem. Nie miałem z tym jeszcze problemów. Być może będziesz musiał zagrać w niektóre gry, aby obejść hg rebaseograniczenia - w zasadzie nie lubi zmieniać bazy na przodka w tej samej gałęzi, nazwanej lub domyślnej, chociaż pozwala na to, jeśli zmienia się bazę między (nazwanymi) gałęziami.

  2. Przenieś repozytorium ( foo/.hg) do katalogu roboczego ( bar) i jego plików. Nie na odwrót.

Niektórzy mówili o tworzeniu dwóch drzew klonów i kopiowaniu plików między nimi. Albo łatanie między nimi. Zamiast tego łatwiej jest przenosić .hgkatalogi.

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg push

Działa to tak długo, jak prawdziwe repozytoria, .hgdrzewa, są niezależne od katalogu roboczego i jego plików.

Jeśli nie są niezależni ...

Krazy Glew
źródło
W 2015 roku histeditjest bardzo dobrą opcją do tego zadania. Nadal nie ufam temu, ponieważ robię rebase git -i, ale nie ulega awarii .. przynajmniej nowsze wersje zostawią cię w gałęzi tymczasowej, jeśli coś pójdzie nie tak, więc jedyny raz, kiedy zestawy zmian zostaną usunięte jest po zatwierdzeniu nowej gałęzi.
user2864740
2

Nigdy nie korzystałem z Mercuriala, ale brzmi to bardzo podobnie do tego, o czym Martin Fowler mówił na swoim blogu nie tak dawno:

http://martinfowler.com/bliki/MercurialSquashCommit.html

Józef
źródło
Wygląda to na nieco skomplikowane, ale dzięki za link. Szczerze mówiąc, mam nadzieję na jakieś magiczne rozszerzenie, które zrobi dokładnie to, co chcę, na przykład pobieranie i przeszczepianie z ciągnięciem i zbieraniem wiśni.
Lucas
0

Dlaczego nie po prostu hg strip --keeprozkazać?

Następnie możesz zatwierdzić wszystkie zmiany jako jedno zatwierdzenie.

G. Demecki
źródło
@Strawberry nie daje odpowiedzi ?? Uważa, że ​​doskonale odpowiada na pytanie autora. Czy możesz rozwinąć swój punkt widzenia?
G. Demecki
To starożytna historia, więc wycofam tę uwagę - ale zatwierdzona odpowiedź wydaje się bardziej wiarygodnym odniesieniem.
Truskawka
1
@Strawberry Rzeczywiście to starożytna nić. Ale zaakceptowana odpowiedź jest nieaktualna, ponieważ Mercurial nie potrzebuje już oddzielnego rozszerzenia innej firmy do tego zadania.
G. Demecki
0

HistEdit zrobi, co chcesz, ale prawdopodobnie jest to przesada. Jeśli jedyną rzeczą, której potrzebujesz, jest złożenie kilku zestawów zmian razem, Collapse Extension zrobi to.

Steve Losh
źródło
1
chociaż zapewnia znacznie łatwiejszy w użyciu i zrozumieniu interfejs użytkownika, co jest więcej niż wystarczającym powodem, aby go używać, ale zapewnia również mechanizm edycji scalonego komunikatu zestawu zmian, co jest kolejną rzeczą, którą zawsze chcę zrobić, scal zestawy zmian.
Stefan Rusek
A problem ze zrozumieniem tylko interfejsu użytkownika jest taki, którego naprawdę nie rozumiemy. W każdym razie, w przeszłości, podczas gdy było to trudne, pozwala to zmieniać „wiadomości”, a także zmieniać komunikaty podczas „składania”. Histedit jest doskonały; jeśli już, rozszerzenie upadku jest nieużyteczne.
user2864740
0

Załóżmy, że masz dwa niepublikowane THISi THATzatwierdzenia w Mercurial i polubisz je, aby dołączyć do jednego zatwierdzenia w THISpunkcie:

... --> THIS --> ... --> THAT --> ... --> LAST

Sprawdź, czy Twoje zatwierdzenia nie zostały opublikowane:

$ hg glog -r "draft() & ($THIS | $THAT)"

Aktualizacja do LASTzatwierdzenia:

$ hg up

i import zatwierdzeń do THISdo MQ ::

$ hg qimport $THIS::.

Usuń wszystkie łaty i zastosuj tylko najpierw THIS:

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

Dołącz do THAT:

$ hg qfold $THATNAME

UWAGA Aby znaleźć nazwę, THATNAMEużyj:

$ hg qseries

Zastosuj wszystkie łatki i przenieś je do historii repozytorium:

$ hg qpush -a
$ hg qfinish -a

Mój wpis na blogu na ten temat to Dołączenie do dwóch zatwierdzeń w Mercurial .

gavenkoa
źródło
0

Tak, strip --keepdziała na pytanie autora. Ale wyglądało to trochę inaczej niż inne, na przykład, jeśli masz wersję od 1 do 30, ale chcesz zwinąć tylko wersję 12-15. Inne rozwiązania działają, ale nie strip --keep.

Frank Tao
źródło