Jak odłożyć na bok kilka niezatwierdzonych zmian, pracując nad czymś innym

98

Jeśli mam kilka niezatwierdzonych zmian i chcę je odłożyć na bok, zamiast tego pracuję nad czymś innym, a później (po kilku dniach) wróć do tego i kontynuuj pracę. Jaki byłby najłatwiejszy przepływ pracy, aby to osiągnąć? (Jak dotąd mam tylko doświadczenie z podstawowymi funkcjami Mercurial). Moją zwykłą metodą było utworzenie nowej gałęzi za pomocą klonu, ale mogą być lepsze sposoby.

Erik
źródło

Odpowiedzi:

133

Masz kilka opcji:

  1. Półki na przedmioty. Spowoduje to zapisanie zmian i usunięcie ich z katalogu roboczego, aby gałąź mogła kontynuować. Nie tworzy zbioru zmian.

    hg shelve --all --name "UnfinishedChanges"
    
    hg unshelve --name "UnfinishedChanges"
    

    Aktualizacja / edycja : może być konieczne użycie nowszych wersji Mercurial

    hg shelve -n "UnfinishedChanges"
    hg unshelve "UnfinishedChanges"
    

    Nadal możesz używać --namejako alternatywy dla -n, ale Mercurial już nie lubi --name. Co więcej, --allnie jest już potrzebny, a mercurial faktycznie będzie z tego powodu wariować.

  2. Patch kolejkuje elementy za pomocą mq. Pod pewnymi względami nie różni się to zbytnio od półki, ale zachowuje się inaczej. Wynik końcowy jest taki sam, zmiany są usuwane i można je opcjonalnie zastosować ponownie później. Po wypchnięciu łatki są logicznymi zestawami zmian, po wyskakiwaniu są zapisywane w innym miejscu i nie są częścią historii zestawu zmian.

    hg qnew "UnfinishedWork"
    hg qrefresh
    hg qpop
    
    hg qpush "UnfinishedWork"
    
  3. Zatwierdź je lokalnie, zaktualizuj do poprzedniego zestawu zmian i kontynuuj pracę i korzystaj z anonimowych gałęzi (lub wielu głowic). Jeśli chcesz zmian, możesz scalić głowy. Jeśli nie chcesz zmian, możesz usunąć zbiór zmian.

    hg commit -m"Commiting unfinished work in-line."
    hg update -r<previous revision>
    
    hg strip -r<revision of temporary commit>
    
  4. Zatwierdź je w nazwanej gałęzi. Przepływ pracy staje się wtedy taki sam, jak opcja 3 - scalanie lub usuwanie, gdy jesteś gotowy.

    hg branch "NewBranch"
    hg commit -m"Commiting unfinished work to temporary named branch."
    hg update <previous branch name>
    

Osobiście używam opcji 3 lub 4, ponieważ nie mam nic przeciwko usuwaniu zestawów zmian lub sprawdzaniu częściowego kodu (o ile ostatecznie nie zostanie on wypchnięty). Można tego używać w połączeniu z nowymi funkcjami Phase , aby ukryć lokalne zestawy zmian przed innymi użytkownikami, jeśli zajdzie taka potrzeba.

Używam również rebase polecenia do przenoszenia zestawów zmian, aby uniknąć połączeń, w których scalenie nie dodałoby niczego do historii kodu. Połączenia, które zwykle oszczędzam na aktywność między ważnymi gałęziami (np. Uwalnianie gałęzi) lub aktywność z gałęzi cech o dłuższym okresie istnienia. Istnieje również histeditpolecenie, którego używam do kompresowania zbiorów zmian, w których ich „gadatliwość” zmniejsza wartość.

Kolejki poprawek są również powszechnym mechanizmem służącym do tego, ale mają semantykę stosu. Wpychasz i przebijasz łaty, ale łata znajdująca się „pod” inną łatą w stosie wymaga również wpychania tej na wierzchu.

Ostrzeżenie , podobnie jak w przypadku wszystkich tych opcji, jeśli pliki mają więcej zmian od czasu tymczasowych zmian, które umieściłeś w półce / kolejce / rozgałęzieniu, będzie wymagana rozdzielczość scalania podczas usuwania z półki / wypychania / scalania.

Adam Houldsworth
źródło
Dzięki za świetną odpowiedź i pomocne przykłady. Czy wiesz, czy używanie zakładek hg jest również opcją?
Erik
@Erik Możliwe, ale nie mam doświadczenia w jego używaniu.
Adam Houldsworth,
2
Zakładki mogą być pomocne przy opcji 3 - możesz użyć jednej do oznaczenia wersji utworzonej w celu przechowywania zmian. Nie mogą samodzielnie wykonać tego zadania.
Steve Kaye
opcja --allnie jest rozpoznawana. i tak jest domyślnym zachowaniem odkładanie wszystkich zmian na półkę.
naXa
@naXa Cześć kolego, jeśli jedno z moich poleceń jest trochę nie w porządku (może dlatego, że wersja się zmieniła), możesz edytować odpowiedź, a ja ją zatwierdzę, jeśli to konieczne :-)
Adam Houldsworth
23

Osobiście nie podoba mi się żadna z dotychczas opublikowanych odpowiedzi:

  1. Nie lubię rozgałęziania klonów, ponieważ lubię, aby każdy projekt miał tylko jeden katalog. Praca na różnych katalogach w tym samym czasie całkowicie psuje historię ostatnich plików moich redaktorów. Zawsze kończy się zmianą niewłaściwego pliku. Więc już tego nie robię.
  2. Używam shelvedo szybkich poprawek (tylko po to, aby przenieść moje niezaangażowane zmiany do innej gałęzi, jeśli zdaję sobie sprawę, że jestem w złym). Mówisz o dniach, nie ma mowy, bym odłożył coś na kilka dni.
  3. Myślę, że mqjest to zbyt skomplikowane na tak zwyczajną sytuację

Myślę, że najlepszym sposobem jest po prostu zatwierdzenie zmian, niż powrót do zestawu zmian, zanim rozpoczniesz te zmiany i zaczniesz od tego. Jest kilka drobnych problemów, zilustruję:

Powiedzmy, że masz zestaw zmian A. Następnie rozpocznij zmiany. W tym momencie chcesz go odłożyć na chwilę. Przede wszystkim oddaj swoją pracę:

hg ci -m "Working on new stuff"

Jeśli chcesz, możesz dodać zakładkę, aby ułatwić późniejszy powrót. Zawsze tworzę zakładki do moich anonimowych oddziałów.

hg bookmark new-stuff

Wróć do zestawu zmian sprzed tych modyfikacji

hg update A

Od tego momentu pracujesz i generujesz zestaw zmian C. Teraz masz 2 głowy (B i C), zostaniesz ostrzeżony, gdy spróbujesz pchnąć. Możesz wypchnąć tylko jedną gałąź, określając nagłówek tej gałęzi:

hg push -r C

Lub możesz zmienić fazę new-stuffgałęzi na tajną. Tajne zestawy zmian nie zostaną przesłane.

hg phase -r new-stuff --secret --force
Rafael Piccolo
źródło
Dzięki za szczegółową odpowiedź! Bardzo lubię czytać przepływy pracy ludzi pod kątem tych (zwykłych?) Problemów.
Erik,
Myślę, że mqjest nieco zbyt skomplikowane dla właśnie tej sytuacji, ale ma dość szeroki zakres zastosowań, włącznie z tym, że warto inwestować czas podczas stania biegły z nim.
Norman Gray
12

Aby zachować lokalne niezatwierdzone zmiany, najłatwiejszym sposobem jest zapisanie ich jako pliku poprawki.

hg diff > /tmp/`hg id -i`.patch

a kiedy trzeba wrócić do poprzedniego stanu:

hg up <REV_WHERE_SAVED>
hg patch --no-commit /tmp/<REV_WHERE_SAVED>.patch
mapcuk
źródło
Chciałbym rozebrać /tmpi hg id -ii będzie działać na Windoze też.
anatoly techtonik
I hg upnie jest tam potrzebny.
anatoly techtonik
1
@techtonik Co się stanie, jeśli zastosuję łatkę w innej wersji? Zwłaszcza jeśli zmodyfikowane są załatane pliki.
mapcuk
Mercurial spróbuje go scalić, ale i tak będziesz musiał poradzić sobie z konfliktem.
anatoly techtonik
6

Możesz po prostu klonować swoje repozytorium wiele razy. Mam zwykle klon root, a następnie wiele potomków. Przykład:

  • MyProject.Root
  • MyProject.BugFix1
  • MyProject.BugFix2
  • MyProject.FeatureChange1
  • MyProject.FeatureChange2

Wszystkie 4 elementy potomne są klonowane z katalogu głównego i wypychają / ściągają do / z katalogu głównego. Następnie root wypycha / ściąga z głównego repozytorium w sieci / Internecie gdzieś. Korzeń działa jak Twój osobisty obszar przejściowy.

W twoim przypadku po prostu sklonujesz nowe repozytorium i zaczniesz działać. Zostaw swoją „półkową” pracę w spokoju w drugim repozytorium. To takie proste.

Jedynym minusem jest użycie miejsca na dysku, ale gdyby to było problemem, i tak w ogóle nie używałbyś DVCS;) Aha, i to w pewnym sensie zanieczyszcza twoją listę "ostatnich projektów" Visual Studio, ale co tam.

[Edytuj następujące komentarze]: -

Podsumowując ... to, co robisz, jest w porządku i normalne. Twierdziłbym, że jest to najlepszy możliwy sposób pracy, gdy są spełnione następujące warunki: 1) jest krótkotrwały 2) nie musisz współpracować z innymi programistami 3) zmiany nie muszą opuszczać komputera do czasu zatwierdzenia / czas wypychania.

nbevans
źródło
Jest jakiś powód, aby nie używać oddziałów? Do tego służą i są znacznie szybsze niż klonowanie repo.
Adam Houldsworth,
W moim pytaniu stwierdziłem, co następuje: Moją zwykłą metodą było utworzenie nowej gałęzi za pomocą klonu, ale mogą być lepsze sposoby.
Erik
1
@AdamHouldsworth, technicznie rzecz biorąc, są to gałęzie ... tylko krótkotrwałe. Tworzenie nazwanej gałęzi dla krótkotrwałej pracy jest całkowicie głupie. Nadużywa celu nazwanego gałęziami, które są dla długowiecznych historii pracy.
nbevans
@NathanE Jeśli myślisz, że nazwane gałęzie do krótkotrwałej pracy są „całkowicie głupie”, to istnieje również anonimowe rozgałęzianie, regały lub kolejka poprawek jako inne lekkie opcje. Moim zdaniem ponowne klonowanie jest równie głupie w porównaniu z innymi opcjami - jego potencjalną korzyścią jest otwarcie dwóch zestawów kodu w dwóch instancjach VS, ale rzadko muszę to robić, więc używanie klonów jest oczywiste nie służy mi. Dla wyjaśnienia nie byłem zwolennikiem krytyki.
Adam Houldsworth,
@NathanE Nie są one również przeznaczone wyłącznie dla „długowiecznych historii o pracy”, to jest coś, w czym są dobrzy, jeśli podążasz za ciągłą integracją. Prosto z dokumentów : „Rozgałęzienia pojawiają się, gdy linie rozwoju się rozchodzą”, jeśli odkładasz element pracy na półkę, aby popracować nad czymś innym, wydaje mi się to dywergencją, niezależnie od tego, jak długo trwa.
Adam Houldsworth,