2014-10-24 36 views
9

użyć następującego polecenia, aby zastosować poprawkę w Mercurial, nie popełniając go:Jak zastosować kilka poprawek za pomocą wiersza polecenia hg, gdy są już niezatwierdzone zmiany?

hg import patch.diff --no-commit 

Działa świetnie, jednak gdy próbuję stosować kilka plastrów jednocześnie tak:

hg import patch1.diff --no-commit 
hg import patch2.diff --no-commit 
... 

I ten komunikat o błędzie po drugie popełnić:

abort: uncommitted changes 

Jeśli robię dokładnie to samo w SourceTree (zastosować patch1 następnie łata 2 i wybierz "Modyfikuj pliki kopii roboczej") działa: dwie poprawki są nakładane na kopię roboczą, zmiany z patch1 i patch2 połączone/złożone razem.

Jak zrobić to samo za pomocą wiersza polecenia hg?

Odpowiedz

10

To zachowanie zostało zaprojektowane przez autorów Mercurial: wyobraź sobie, że masz "ręcznie wykonane" niezatwierdzone zmiany w kopii roboczej, nie chcielibyśmy, aby hg import automatycznie nałożył łatę i zatwierdzili zarówno twoje zmiany, jak i łatkę zmiany z błędnym logiem i obie zmiany uwikłane razem.

Dlatego hg help import mówi:

Because import first applies changes to the working directory, import will 
abort if there are outstanding changes. 

Polecenie import jest bardziej do importowania Zestawienia zmian (z metedata gdy dane pochodzą z hg export) niż tylko wniesienia poprawek. Jeśli masz własne zmiany w kopii roboczej, możesz na przykład nadal używać hg import --bypass i nie wystąpi błąd, ponieważ zatwierdzenie jest bezpośrednio stosowane do repozytorium, a nie do kopii roboczej. (Uwaga: ale jeśli po prostu zatwierdzisz zmiany, dostaniesz dwie głowy, które musisz scalić .. :-).

Rozwiązaniem z wierszem poleceń dla systemów uniksowych jest użycie polecenia patch bezpośrednio zamiast hg import, ponieważ wtedy nie zostanie sprawdzone lokalne modyfikacje. Np

for i in 1 2 etc. 
do 
    patch -p1 < patch$i.diff 
done 
hg commit ... 

Dla nieuniksowych systemów można również czystą Mercurial rozwiązanie, instalując rozszerzenie shelve, umożliwiając jej w globalnym pliku konfiguracyjnym (mercurial.ini), a następnie użyć shelve obsłużyć scala jeden plaster po drugim:

hg import --no-commit patch1.diff 
hg shelve 
hg import --no-commit patch2.diff 
hg unshelve 
etc. 

Jeśli kiedykolwiek by wystąpić konflikt, shelve wykryje go i trzeba by rozwiązać to wtedy powiedzieć shelve że rozwiązano z opcją --continue.

Mam nadzieję, że to pomoże.

+0

o' polecenia patch': nie mam takiego narzędzia w moim folderze mercurial (Windows), mówisz 'Hg łatka'? Jeśli tak, to już wypróbowałem to przed zadawaniem tego pytania SO i po prostu zgłasza ten sam komunikat o błędzie, jak "hg import" – tigrou

+0

Wydaje się być narzędziem "Linux", może instalacja 'cygwin' sprawi, że będzie działał. – tigrou

+0

Nie zdawałem sobie sprawy, że nie korzystasz z Uniksa, tak 'patch' jest narzędziem Unix. Możesz albo: użyć wersji Cygwin, użyć kopii, jak wspomniałeś, albo myślę, że możesz mieć rozwiązanie "czysto-hg", dodam to do mojej odpowiedzi ..;) –

4

Oto co pracował dla mnie (roztwór Windows), pomysł chwycił od Christophe Muller odpowiedź:

copy /b "patch01.diff" + "patch02.diff" + ... + "patchXX.diff" "all.diff" 

hg import "all.diff" --no-commit 

To po prostu złączyć wszystkie łatki ze sobą (jak jeden duży plik), a następnie je stosować.

2

Jednym z możliwych rozwiązań jest użycie Mercurial Queues (uwaga - wydaje się, że to rozszerzenie jest "często brane pod uwagę w przypadku wycofywania", ale nie jest jeszcze przestarzałe i jest fabrycznie zainstalowane z Mercurial).

Jeśli wcześniej nie korzystałeś z MQ, to jest bardzo przydatny, jeśli jest trochę skomplikowany. Ale skutecznie pozwala tworzyć kolejki poprawek, które mogą być wciśnięty, zdejmowana ponownie nakazał itp

Można go używać, aby pomóc rozwiązać problem tak:

:: if you don't already have MQ initialised for the repo, do so 
hg init --mq 

:: import the patches you want as queue entries 
hg qimport -P patch1.diff 
hg qimport -P patch2.diff 
hg qimport -P patch3.diff 

Opcja -P przekazuje zmiany podczas ich importowania, co oznacza, że ​​skutecznie sprawdzasz, czy działają poprawnie. Gdy już wszystkie łaty importowane do MQ, pop je wszystkie (więc żaden są stosowane i jesteś z powrotem do miejsca startu) i złożyć je wszystkie do nowej, połączonej patch:

:: go back to no patches applied, and create a new patch at the front of the queue 
hg qpop --all 
hg qnew -m "Your planned commit message" combined_patches 
:: fold the named patches into the current one 
hg qfold patch1 patch2 patch3 

Następnie, jeśli „re zadowolony z uzyskanej łatki, po prostu przekształcić go w«prawdziwym»changeset:

:: convert combined_patches into a "real" changeset 
hg qfinish combined_patches 
+0

Kolejki Mercurial są dystrybuowane z Mercurial, ale nie są domyślnie włączone. Jeśli zastanawiasz się, dlaczego jest on często uznawany za wycofanie: http://gregoryszorc.com/blog/2014/06/23/please-stop-using-mq/ – Mathiasdm

+0

@Mathiasdm: Ah, musiałem włączyć to siebie wtedy :) - i tak, właśnie czytałem ten artykuł właśnie teraz. – icabod