Mercurial
Mercurial to system kontroli wersji, zajmujący wraz z gitem miejsce w czołówce otwartoźródlanych narzędzi tego typu.
Do 2011 roku byłem użytkownikiem Subversion, całkiem przyzwoitego i stabilnego narzędzia pracującego w modelu scentralizowanego. Po pewnym jednak czasie nie daje się nie zauważyć jego niedogodności. Gdy wypróbowałem Mercuriala, prędko się przekonałem o jego zaletach i wyższości nad SVN-em. Dlatego w zastosowaniach prywatnych przeszedłem stopniowo na Hg, konwertując do niego chyba wszystkie moje repozytoria.
Spis treści |
[edytuj] Do zainstalowania
- Mercurial
- Jeśli chcemy współpracować z Subversion:
- HgSubversion, rozszerzenie pozwalające w ograniczenym zakresie używać Mercuriala w roli klienta SVN
- SWIG albo subvertpy - moduły pozwalające na używanie subversion z pythona, niezbędne do działania hgsubversion
- TortoiseHg - GUI dla Mercuriala, coś na wzór TortoiseSVN, bezproblemowa (choć toporna) instalacja pod Windows, trochę więcej zabawy wymaga instalacja pod Linuksami (wiecej informacji).
Uwaga. Żeby działało polecenie hg view, trzeba po instalacji Mercuriala ręcznie dokopiować skrypt contrib/hgk.
[edytuj] Instalacja ze źródeł
Ostatnio instalowałem tak:
python setup.py build python setup.py install --prefix=/usr/local --root=/usr/local/stow/mercurial-1.9.x
Wydaje się, że alternatywnie można posłużyć się dostarczonymi Makefile'ami:
make install PREFIX=/user/local DESTDIR=/usr/local/stow/mercurial-1.9.x
Testy modułowe:
make check
[edytuj] Rozszerzenia
Rdzeń Mercuriala jest całkiem funkcjonalny, niemniej istnieje cały szereg rozszerzeń dostarczających dodatkowych, mniej lub bardziej pożytecznych funkcji. Część z nich jest "oficjalna" i dystrybuowana wraz z samym Mercurialem, ale domyślnie nie są aktywne. Żeby takie rozszerzenie włączyć, należy umieścić w pliku konfiguracyjnym wpis podobny do następującego:
[extensions] rebase =
To spowoduje aktywację rozszerzenia Rebase. W przypadku rozszerzeń nie dołączonych "fabrycznie" do Mercuriala, należy podać po znaku = ścieżkę do rozszerzenia, np.:
[extensions] hgsubversion = ~/hg-extensions/hgsubversion/hgsubversion
Pracując z Mercurialem znalazłem szereg rozszerzeń, które dziś uznaję za niemal niezbędne. Są to:
- bookmarks – zakładki przypominające nieco branche w stylu gita
- convert – konwersja pomiędzy różnymi typami repozytoriów
- graphlog – asciiartowy graf obok loga
- hglock – lockowanie plików w rozproszonym systemie kontroli oprogramowanie jest na pozór mało sensownym pomysłem, ale...
- hgsubversion – konwersja z Subversion bądź używanie Mercuriala w ograniczonym zakresie jako klienta SVN
- mq – Mercurial Queues czyli kolejki patchy, niezwykle przydatne narzędzie
- rebase –
- transplant – przenoszenie poszczególnych changesetów między branchami, odpowiednik git cherry-pick czy svn merge
Też fajne, choć można się bez nich obejść:
- color – koloryzuje na terminalu standardowe wyjście niektórych poleceń (np. log, diff)
- fetch – pull + update + merge + commit
- hgk – prymitywne gui wywoływane poleceniem hg view
- pager – przydatne gdy tekst nie mieści się na ekranie...
- progress, czyli pasek postępu przy niektórych poleceniach command line
- purge – czyści przestrzeń roboczą z niepotrzebnych plików
- record – pozwala interaktywnie wybrać zmiany do skomitowania
Inne ciekawie wyglądające rozszerzenia, pewnie się nimi pobawię niedługo:
[edytuj] Współpraca z Subversion
Do dyspozycji mamy jednorazową konwersję z repozytorium SVN przy pomocy standardowego rozszerzenia convert. Ale co jeśli nie jesteśmy gotowi na tak rewolucyjną zmianę? Jest kilka narzędzi umożliwiających traktowanie repozytorium SVN jako głównego, czy inaczej: używanie Mercuriala w roli klienta Subversion. Żadne z nich nie działa jednak wystarczająco dobrze jak na moje potrzeby.
Zobacz też: Working with Subversion
[edytuj] Konwersja
Przy pomocy standardowego rozszerzenia convert.
[edytuj] HgSubversion
Funkcjonalność pozwlająca na korzystanie (clone, push, pull) z repozytoriów subversion byłaby czymś nieocenionym przy próbach przejścia z svn na hg. Rozszerzenie HgSubversion byłoby strzełem w dziesiątkę, ale niestety, w praktyce działa tylko z niewielkimi repozytoriami, o niezbyt skomplikowanej historii. Warto jednak popróbować, a nuż się uda.
Ma dwa tryby pracy: klonowanie całego repozytorium SVN bądź tylko wybranego podkatalogu (np. trunk czy jakiś branch). Pierwsza metoda wymaga "standardowej" struktury (trunk, branches, tags). Testowałem to pobieżnie na dość dużym repozytorium o nie do końca takiej strukturze i nie udało się, po kilku tysiącach wywalił jakiś błąd. Z kolei konwersja jedynie tranka się powiodła, ale nie wiem, czy tak to ma faktycznie działać: próba dociągnięcia nowych zmian przez hg pull, bez modyfikowania czegokolwiek w klonie mercurialowym, powoduje utworzenie jakby nowej gałęzi o tej samej nazwie i potem mercurial chce mi je merge'ować dająć jakieś konflikty...
Pomocne materiały na wiki Mercuriala:
[edytuj] hgsvn
hgsvn to nierozwijany już od jakiegoś czasu zestaw skryptów pełniących podobną rolę jako rozszerzenie HgSubversion. Niedawno (w wakacje 2011) pojawił się jakiś bugfix, ale jak zaznacza autor - tylko naprawdę krytyczne błędy będą poprawiane.
[edytuj] Branche
Koncept branchy jako równoległych linii developmentu jest różnie realizowany w różnych systemach, a nawet w ramach jednego może być osiągnięty na różne sposoby. W przypadku Mercuriala mamy co najmniej 4 możliwości:
- sklonowanie repozytorium; branch w postaci klona oznacza separację na tak długo, jak nam się podoba, ale wadą, szczególnie przy dużych projektach, jest większe zużycie przestrzeni dyskowej
- w repozytorium pojawiają się spontaniczne rozgałęzienia spowodowane przez changesety posiadające te same parenty, niezależnie od tego, czy changesety te powstały w tym samym repozytorium, czy w różnych; rozgałęzienia te na ogół są merge'owane prędzej czy później
- nazwane branche, które w zasadzie są etykietami na stałe przypisywanymi do poszczególnych changesetów oraz ich childów, jednak ich zmiana w kopii roboczej wymusi powstanie rozgałęzienia; należy zwrócić uwagę, że to bardzo "ciężka" odmiana branchy, każdy changeset będzie na zawsze przypisany do jakiegoś nazwanego brancha (domyślnie default) i przypisanie to będzie się propagować na wszystkie klonowane repozytoria
- bookmarks, czyli nazwane wskaźniki przesuwające się wraz z comittami na danej linii developmentu; to mercurialowa odpowiedź na koncepcję branchy w gicie. Podstawowa wada: nowo dodane bookmarki nie propagują się pomiędzy repozytoriami podczas operacji pull i push; trzeba je jednorazowo przepchać jawnie (pull/push -B nazwa); potem będą już aktualizowane automatycznie.
[edytuj] Uwagi
- Napisany w pythonie, co ma swoje zalety i wady.
- Podobnie jak Subversion czy git, nie zwraca uwagi na prawa dostępu (mode) plików, z wyjątkiem flagi executable. Może to mieć znaczenie w zastosowaniach takich, jak wersjonowanie katalogu /etc.
- Wygląda na to, że git ma zdecydowanie aktywniejszy development i chyba też większą bazę użytkowników.
- Wersja 1.9 ma bug w poleceniu hg verify, powodujący wyświetlanie następującego komunikatu: "0: changeset refers to unknown manifest 000000000000" w repozytoriach stworzonych przez polecenie hg convert. Nie należy się tym przejmować. [3]. Poprawiono w 1.9.1.
- Mercurial nie interesuje się szczególnie katalogami w kontekście innym, niż wersjonowanie zawartych w nich plików. W konsekwencji nie da się zapamiętać w repozytorium pustych katalogów, co w niektórych zastosowaniach będzie upierdliwością.
[edytuj] Kto używa
- Mozilla (Firefox i inne produkty) [4]
- Python (ostateczna konwersja z subversion w marcu 2011) [5]
- Netbeans (prawie 200k changesetów) [6]
- Xen (przynajmniej częściowo) [7]
- OpenSolaris [8]
- OpenJDK [9]
- GMP, The Gnu Multiple Precision Arithmetic Library [10] [hgweb]
Zobacz też: lista projektów używających Mercuriala
[edytuj] Konfiguracja
Pluginowata architektura Mercuriala staje się po pewnym czasie ciut irytująca, w szczególności gdy chcemy z niego korzystać na różnych maszynach i z różnych kont. Na ten drugi przypadek pomóc może stworzenie globalnego, systemowego pliku konfiguracyjnego /etc/mercurial/hgrc, który u mnie wygląda następująco:
[extensions] color = convert = eol = extdiff = fetch = graphlog = #hgsubversion = hgk = rebase = mq = pager = progress = purge = record = transplant = [pager] pager = less -SFRX attend = diff glog help log qdiff incoming outgoing status [extdiff] kompare = kdiff3 = # for TortoiseHg: %include /usr/local/opt/thg-and-stuff/thg/contrib/mergetools.rc
[edytuj] Zobacz też
- HgInit - tutorial wprowadzający do Mercuriala napisany przez Joela Spolsky'ego
- Naucz się Mercuriala
- Wiki Mercuriala z mnóstwem przydatnych informacji
- Git czy Mercurial
- Git and Mercurial - Compare and Contrast
- A Guide to Branching in Mercurial
- Branching and merging in Mercurial (and Git) explained
- Git and Mercurial - Compare and Contrast autorstwa Jakuba Narębskiego