Jak poprawnie zamknąć gałąź funkcji w Mercurial?

240

Skończyłem pracę nad gałęzią funkcji feature-x. Chcę scalić wyniki z powrotem do defaultgałęzi i zamknąć feature-x, aby się go pozbyć na wyjściu hg branches.

Wymyśliłem następujący scenariusz, ale ma on pewne problemy:

$ hg up default
$ hg merge feature-x
$ hg ci -m merge
$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch

Więc feature-xgałąź (zmienia 40- 41) jest zamknięta, ale jest jedna nowa głowa , zestaw zmian gałęzi zamykającej 44, który będzie wymieniony za hg headskażdym razem:

$ hg log ...
o  44 Closed branch feature-x
|
| @  43 merge
|/|
| o  42 Changeset C
| |
o |  41 Changeset 2
| |
o |  40 Changeset 1
|/
o  39 Changeset B
|
o  38 Changeset A
|

Aktualizacja : Wygląda na to, że od wersji 1.5 Mercurial nie wyświetla już główek zamkniętych gałęzi na wyjściu hg heads.

Czy można zamknąć połączony oddział bez pozostawiania jednej głowy? Czy istnieje bardziej poprawny sposób zamknięcia gałęzi funkcji?

Powiązane pytania:

Andrey Vlasovskikh
źródło
@Andrey: ale wskazany artykuł NIE mówi tylko o „--close-branch”. Pokazuje cztery sposoby przycinania gałęzi. Jeśli naprawdę tego nie chcesz, możesz sklonować, jak wyjaśniono w artykule. Jedyny „problem” polega na tym, że z jakiegokolwiek powodu chcesz go zamknąć, a jednak zachować go przy sobie.
SyntaxT3rr0r
1
@WizardOfOdds Tak, przeczytałem cały artykuł na temat przycinania martwych gałęzi. Chcę, aby oddział pozostał w historii zmian, a nie wyrzucał. Wcześniej po prostu połączyłem gałęzie funkcji defaultbez ich „zamykania”. Spowodowało to 0 nowych głów, ale takie gałęzie były widoczne na hg brancheszawsze (jako nieaktywne gałęzie).
Andrey Vlasovskikh
Aby opracować funkcje, mam tendencję do klonowania całego repozytorium, a następnie scalania go z powrotem po zakończeniu funkcji. Nie lubię pozostałości (zamkniętych) gałęzi w historii.
DanMan

Odpowiedzi:

218

Jednym ze sposobów jest pozostawienie połączonych gałęzi funkcji otwartych (i nieaktywnych):

$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
feature-x  41:...
    (2 branches)

$ hg branches -a
default    43:...
    (1 branch)

Innym sposobem jest zamknięcie gałęzi funkcji przed scaleniem przy użyciu dodatkowego zatwierdzenia:

$ hg up feature-x
$ hg ci -m 'Closed branch feature-x' --close-branch
$ hg up default
$ hg merge feature-x
$ hg ci -m merge

$ hg heads
    (1 head)

$ hg branches
default    43:...
    (1 branch)

Pierwszy jest prostszy, ale pozostawia otwartą gałąź. Drugi nie pozostawia otwartych głów / gałęzi, ale wymaga jeszcze jednego zatwierdzenia pomocniczego. Można połączyć ostatnie rzeczywiste zatwierdzenie z gałęzią funkcji z tym dodatkowym zatwierdzeniem za pomocą --close-branch, ale należy wcześniej wiedzieć, które zatwierdzenie będzie ostatnim.

Aktualizacja : Ponieważ Mercurial 1.5 można zamknąć oddział w każdej chwili, więc nie pojawi się w obu hg branchesi hg headswięcej. Jedyną rzeczą, która mogłaby cię drażnić, jest to, że technicznie wykres wersji będzie zawierał jeszcze jedną wersję bez potomka.

Aktualizacja 2 : Od kiedy zakładki Mercurial 1.8 stały się podstawową funkcją Mercurial. Zakładki są wygodniejsze do rozgałęziania niż nazwane gałęzie. Zobacz także to pytanie:

Andrey Vlasovskikh
źródło
2
Niekoniecznie jest to prawdą Bookmarks are more convenient for branching than named branches. Zakładki Hg to nie to samo, co gałęzie Git. Są pełne wielu skrzynek, co czyni je nieodpowiednimi jako gałęzie cech. Na przykład: po sklonowaniu repozytorium skończysz z najnowszym zatwierdzeniem w defaultgałęzi. Jeśli korzystasz z zakładek, ten zestaw zmian odpowiada losowej (niestabilnej) zakładce. Jeśli użyjesz nazwanych gałęzi, otrzymasz najnowsze zatwierdzenie w gałęzi stabilnej / domyślnej, co zwykle jest tym, czego chcesz. Zakładki dotrą tam pewnego dnia, ale jeszcze ich tam nie ma.
Gili
Używam zakładek jako znaczników prywatnych, które są widoczne tylko w moim lokalnym repozytorium. Działają jako przypomnienia o zestawach zmian, które muszę ponownie odwiedzić.
Gili
Starałem się śledzić to podejście, ale nadal pojawia się błąd, gdy próbujesz przekazać: abort: push creates new remote branches:. Co mogłem zrobić źle?
kasperd
79

imho istnieją dwa przypadki dla oddziałów, które zostały zapomniane do zamknięcia

Przypadek 1: oddział nie został scalony w domyślny

w tym przypadku aktualizuję gałąź i wykonuję kolejne zatwierdzenie z opcją --close-branch, niestety to wybiera gałąź, aby stała się nową wskazówką, a zatem przed przekazaniem jej do innych klonów upewniam się, że prawdziwa wskazówka otrzyma więcej zmian i inne nie daj się zwieść tej dziwnej wskazówce.

hg up myBranch
hg commit --close-branch

Przypadek 2: gałąź została połączona w domyślną

Ten przypadek nie różni się zbytnio od przypadku 1 i można go rozwiązać, odtwarzając kroki dla przypadku 1 i dwóch dodatkowych.

w tym przypadku aktualizuję do zestawu zmian gałęzi, wykonuję kolejne zatwierdzenie z opcją --close-branch i łączę nowy zestaw zmian, który stał się wskazówką domyślną. ostatnia operacja tworzy nową wskazówkę, która znajduje się w domyślnej gałęzi - HOORAY!

hg up myBranch
hg commit --close-branch
hg up default
hg merge myBranch

Mam nadzieję, że pomoże to przyszłym czytelnikom.

Nachbars Lumpi
źródło
3
Dobra jasna odpowiedź dla początkującego Mercurial, takiego jak ja. I dziękuję, że nie użyłeś „ci”, który nie jest wymieniony jako jedno z poleceń pomocy hg, więc nie wiem, co to znaczy :)
MB.
8
@ MB .: w takich przypadkach hg help ciwyjaśnię ci to.
Chris Morgan
Wierzę, że jak powie ci polecenie 'hg merge', na końcu jest jeszcze jedno zatwierdzenie
Chip Grandits
11

EDYCJA ouch, za późno ... Wiem, że przeczytałem twój komentarz stwierdzający, że chcesz zachować zestaw zmian Feature-X, więc metoda klonowania tutaj nie działa.

Nadal dam odpowiedź tutaj, ponieważ może ona pomóc innym.

Jeśli chcesz całkowicie pozbyć się „funkcji X”, ponieważ na przykład nie działała, możesz sklonować. Jest to jedna z metod wyjaśnionych w artykule i działa, a konkretnie mówi o głowach.

O ile rozumiem, masz to i chcesz raz na zawsze pozbyć się głowy „Feature-X”:

@    changeset:   7:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| | o  changeset:   5:013a3e954cfd
| |/   summary:     Closed branch feature-x
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Więc robisz to:

hg clone . ../cleanedrepo --rev 7

I będziesz mieć następujące, i zobaczysz, że funkcja-x rzeczywiście zniknęła:

@    changeset:   5:00a7f69c8335
|\   tag:         tip
| |  parent:      4:31b6f976956b
| |  parent:      2:0a834fa43688
| |  summary:     merge
| |
| o  changeset:   4:31b6f976956b
| |  summary:     Changeset2
| |
| o  changeset:   3:5cb34be9e777
| |  parent:      1:1cc843e7f4b5
| |  summary:     Changeset 1
| |
o |  changeset:   2:0a834fa43688
|/   summary:     Changeset C
|
o  changeset:   1:1cc843e7f4b5
|  summary:     Changeset B
|
o  changeset:   0:a9afb25eaede
   summary:     Changeset A

Być może źle zrozumiałem, co chciałeś, ale proszę nie zmniejszać, odtworzyłem twój przypadek użycia:)

Składnia T3rr0r
źródło
7

Dziwne, że nikt jeszcze nie zaproponował najbardziej niezawodnego sposobu zamykania gałęzi funkcji ... Możesz po prostu połączyć zatwierdzenie scalania z flagą --close-branch (tzn. Zatwierdzić zmodyfikowane pliki i zamknąć gałąź jednocześnie):

hg up feature-x
hg merge default
hg ci -m "Merge feature-x and close branch" --close-branch
hg branch default -f

To wszystko. Nikt nie zastanawia się nad ponownym zapisaniem. Bez dodatkowego zatwierdzania.

tav
źródło
Wspomniałem o tym w mojej odpowiedzi: „” „Można połączyć ostatnie rzeczywiste zatwierdzenie do gałęzi funkcji z tym dodatkowym zatwierdzeniem, używając opcji --close-branch, ale należy wcześniej wiedzieć, który zatwierdzenie będzie ostatnim.” ” "
Andrey Vlasovskikh
Dobra, widzę. Po prostu nie do końca rozumiem ostatnią część zdania („ale trzeba wiedzieć ...”), więc pomyślałem, że to coś innego. Chciałbym również zauważyć, że ta metoda nie jest obsługiwana przez większość narzędzi GUI (TortoiseHG, SourceTree itp.).
tav
@AndreyVlasovskikh Celem tej odpowiedzi jest zamknięcie gałęzi podczas scalania, a nie ostatniego zatwierdzenia gałęzi operacji.
kasperd
@tav Przed wydaniem mergepolecenia dobrym pomysłem może być hg branchsprawdzenie, czy nazwa gałęzi scalania jest tą, którą chcesz zachować.
kasperd,
2
Przy bliższym przyjrzeniu wydaje się, że scalenie zawsze będzie na zamkniętej gałęzi. Pożądanym rezultatem byłoby, aby znalazł się on w gałęzi jednego z jego rodziców i zamyka gałąź drugiego z rodziców. To wydaje się niemożliwe. W końcu nie wygląda to na realne rozwiązanie. Szkoda, naprawdę chciałem użyć scalenia jako punktu zamknięcia gałęzi.
kasperd