Na ringu zostały: mercurial i git
Distributed VCS-y są fajne, od paru lat w pracy używałem darcs-a. Problem z darcsem jest taki, że (a) ma w cholerę bugów i (b) praktycznie rzecz biorąc jest martwy. Czas na alternatywy.
Ostatnio bawię się bazaarem m.in. dlatego, że PLD przeszło na launchpad.net z którym bazaar jest domyślnie zintegrowany, więc gdyby kiedyś mi się nudziło i przerzuciłbym PLD-owego CVS-a do bazaara, to od razu mielibyśmy integrację z bugtrackerem. Poza tym bazaar jest dosyć intuicyjny, Shuttleworth przekonująco pisze, a całość jest w Pythonie.
Problem: nie odpowiada on mojemu trybowi pracy.
Darcs ma dwie wielkie zalety:
1. Polecenie do robienia commitów jest domyślnie interaktywne, tzn. pyta się czy zapisać każdą jedną zmianę w każdym pliku. Brzmi wkurzająco, ale, po pierwsze, wystarczy nacisnąć 'a' (all) i z głowy, a po drugie oznacza to, że mogę, mając kompletnie rozgrzebany plik z kodem, zauważyć, że właśnie stworzyłem self-contained zmianę i sobie ją commitnąć niezależnie od całej reszty śmiecia w pliku. Jest to bardzo naturalny sposób pracy, bo, zwłaszcza przy większych zmianach, dopiero w trakcie ich tworzenia zauważam wyodrębniające się niezależne, eee, ciągi funkcjonalne (?). Afaik inne VCS-y zaadoptowały to w postaci trybu "interactive" (bazaar przez plugin, hg chyba domyślnie w kodzie, nie wiem jak git).
2. Darcs nie ma rewizji, dla niego rezpozytorium to tak naprawdę zbiór patchy. Oznacza to, że (a) komenda rebase (w bazaarze jak zwykle w postaci pluginu, w hg nie mam pojęcia, czy w ogóle jest, a git ma domyślnie) jest kompletnie bez sensu, bo mogę sobie pullnąć patche z czegokolwiek na cokolwiek, ważne, żeby się nakładały i (b) mogę utrzymywać kilka wersji dokładnie tego samego drzewa, różniących się tylko i wyłącznie jednym patchem.
Punkt pierwszy to nie problem, punkt drugi i owszem. Wynikają z niego dwa różne workflowy:
1. Surwiwal fitnessu (survival of the fittest). System ma robić X. Nie mam pojęcia jaki jest najlepszy sposób na zrobienie X, więc robię kilka możliwych implementacji, po czym odpalam je na różnych maszynach. I dalej wprowadzam równoległe zmiany sprawdzając, jak różne wersje na nie zareagują. W darcsie jest to proste, wystarczy, żebym w pewnym momencie do jednego drzewka wprowadził patch XX, a do drugiego XY i pullując nowe zmiany z drzewka A do B lub vice versa, pamiętał o niepullowaniu tych konkretnych patchy. I mogę sobie tak rozwijać równoległe wersje tego samego programu praktycznie w nieskończoność, zachowując owe różniące je patche. O ile wiem w bazaarze w ogóle tak się nie da, nie wiem jak w hg i gicie.
2. Odgałęzianie się od ruchomego pnia (dla twardzieli: odbranchowywanie się od movowalnego trunka). Sprowadza się do tego, że mam gotowy kawałek softu, który jest rozwijany niezależnie ode mnie przez upstream i ja mam na ów soft nałożyć własne poprawki, sporadycznie mergując się z upstreamem. W darcsie nie problem, mogę pullować dowolne patche skądkolwiek dokądkolwiek, w pozostałych natomiast potrzebny jest rebase. Jak pisałem: bzr i git to mają, nie wiem jak hg.
Pierwszy tryb rozwoju softu jest dosyć specyficzny dla mojej pracy, drugi natomiast, co uświadomiłem sobie dosyć niedawno, wcale nie (acz też obecny). radioemiter.pl i pld-users.org to dokuwiki, www.pld-linux.org to MoinMoin, forum.pld-linux.org to bodajże phpbb (acz nie stawiane przeze mnie). I gdybym wtedy wiedział to, co wiem teraz, to wszystkie one od razu lądowałyby w jakimś VCS-ie. Bardzo ładnie ten problem wyszedł z pld-users, gdzie jeden z adminów zupgrejdował do nowszej wersji dokuwiki i wszystkie moje site-specific zmiany poszły do /dev/null. I żeby je teraz odzyskać będę się musiał z jakimiś patchami i diffami bawić (zakładając, że gdzieś się zachowała stara wersja). A tak, to jeden rebase i po paru minutach miałbym z głowy.
I właśnie dlatego nowy 7thguard, stawiany na drupalu, będzie od początku czymś wersjonowany.
Przy czym nie samym rebasem człowiek żyje. Można powiedzieć, że na co mi rebase -- ściągam najnowszą wersję upstreama, diffuję względem wersji od której się odbranchowałem, po czym próbuję nałożyć takiego patcha na swój kod z commitlogiem "upgrade to upstream X.Y.Z". Prawda, rzecz w tym, że w wypadku tego typu workflowu bardzo liczy się przejrzystość commitlogów, gdyż po paru latach pogubię się w tym, co tam właściwie jest zrobione względem oryginału, a już tym bardziej będzie z tym miał problem ktoś inny chcący też coś pomóc.
I tutaj wychodzi drugi problem z bazaarem -- nie wspiera on przepisywania historii. Rebase rebasem, ale po jakimś czasie commitlogi wyglądałyby tak: 3. implemented X; 4. fixed bug in X; 7 upgraded to upstream 5.0; 11 X obsolete, same functionality implemented elsewhere", etc, etc. Tego typu historia jest ważna w przypadku publicznego projektu, do którego jest np. bugtracker i w którym spójność całości jest święta (to dlatego Linus nie rebase'uje swojego drzewa, ani nie grzebie w jego historii post-factum). Jest ona natomiast ewidentną przeszkadzajką (bo zamazuje obraz zmian) w przypadku projektów bardziej prywatnych, typu opisanych powyżej/tych, co mam w pracy. Po prostu utrudnia życie.
Jestem praktycznie pewien, że z gitem tutaj nie byłoby problemów, nie wiem natomiast jak hg.
W ogóle dosyć oczywiste jest, że bazaar odpada i że najprawdopodobniej wyląduje na gicie. Łudzę się jeszcze, że hg spełni moje wymagania, acz nie mam jakiś specjalnych nadziei. Ot, po prostu, autorzy gita najprawdopodobniej przewidzieli powyższe przypadki użycia oraz setki innych, o których jeszcze nie pomyślałem i które pewnie nigdy nie będą mi potrzebne. Do tego git ma pewnie zaimplementowane optymalne sposoby integracji z wszystkimi innymi rozwiązaniami na rynku (perforce anyone?), więc gdybym kiedykolwiek trafił do jakiejś firmy, gdzie standardem jest coś niespecjalnie wygodnego, najprawdopodobniej byłbym w stanie uprzyjemnić sobie życie przy pomocy odpowiednio użytego gita.
Główny problem z gitem jest taki, że jest on trudny i nieintuicyjny dla ludzi wychowanych na czymkolwiek innym. Tego problemu nie ma z bazaarem, nie wiem jak z hg, ale git to jest oczywisty kosmos. Jest to trochę sytuacja jak z vimem -- używam, bo jest dla mnie wydajniejszy, niż alternatywy. Ale gdybym musiał kogoś innego zmuszać do jego używania, to już byłby problem. Ale nie muszę, bo edytować tekst można w czymkolwiek. Z VCS-ami już nie ma tak łatwo. Jeśli wrzucę 7thguarda do gita, to znacznie podniosę poprzeczkę dla kogokolwiek, kto chciałby w tym później coś pogrzebać (ditto dla pld-users i reszty). Tak nie jest w przypadku np. bazaara, bo czyś z CVS-a, SVN-a, czy czegoś takiego, będziesz się czuł jak w domu.
(To jest powód dla którego przy jakichkolwiek zmianach PLD prawie na pewno nie wyląduje na gicie. Zaawansowane funkcje gita i tak nie zostałyby wykorzystane, a ludzie by się pewnie w końcu zbuntowali, że nowy soft działa kompletnie na odwrót, niż stary dobry CVS. Tego problemu praktycznie nie byłoby właśnie z bazaarem.)
W ogóle nowy 7thguard to będzie ciekawy przypadek. W teorii w ogóle nie powinienem musieć grzebać bezpośrednio w kodzie drupala, wszystko powinno być do załatwienia themami, konfigami i pluginami. W teorii. Jak to wyjdzie w praniu, to się jeszcze zobaczy.
Hmmm, tak się zastanawiam. Może te systemy to jest nowy sposób na rozwój różnych webowych CMS-ów i takich tam? Może to właśnie powinno być specjalnie robione tak, żeby klienci mogli upgrejdować swoje rozwiązania przy pomocy jakiegoś bzr-a z rebasem? Nowe tarballe powinny od razu zawierać katalog .bzr, a nowe wersje powinny być także dostępne do łatwego pullowania/mergowania takimi narzędziami? Graficzne konfigo-klikadła powinny automatycznie commitować wprowadzone zmiany? Interesting... Ciekawym, czy dałoby się taki sposób tworzenia stron dla klientów wprowadzić w mojej opolskiej firmie. Acz to już temat na osobny wpis.
24 VIII 2008 o 21:37
Obawiam się, że chyba masz rację i Hg nie spełni oczekiwań. Jest jeszcze prostrzy od bzr-a i jeszcze bardziej stroni od zmieniania historii — teraz powstaja jakieś rozszerzenia i pluginy do zabawy z tym, ale generalnie cały format repozytorium nie jest do tego przystosowany, więc to trochę na siłe.
24 VIII 2008 o 21:38
Hmm, git nie jest taki straszny, 90% userów nie będzie używać czarów. Ba, aż musiałem sobie właśnie git help rebase odpalić, bo mi dotychczas nie było do niczego sensownego potrzebne ;)
24 VIII 2008 o 22:46
Rebase w Hg byl jednym z tegorocznych projektów w ramach Summer of Code:
http://www.selenic.com/mercurial/wiki/index.cgi/RebaseProject
24 VIII 2008 o 23:26
@deejay1
Git jest straszny. Przez to, że (a) implementacja najbardziej podstawowych operacji różni się od tego, co robią inne scm-y (opisane w linku) i (b) ilość jego poleceń jest tak gigantyczna, że jeśli nie wiesz czego szukasz, to pewnie tego nie znajdziesz (w czym nie pomaga (a)).
@PawelPacana
Ta strona powstała półtora roku temu, a nie chciało mi się specjalnie grzebać, czy to rzeczywiście tegoroczny soc (a jeśli, to hgw czy im się to uda i kiedy to wydadzą w ramach jakiegoś releasu), czy ubiegłoroczny i wszyscy o tym zapomnieli. W każdym razie rebase jest w tym momencie niezbyt do przetestowania w hg :( Zostaje kurde git.
24 VIII 2008 o 23:56
Z całej puli poleceń gita użytkownikowi potrzebne jest clone i diff. To chyba na tyle :)
24 VIII 2008 o 23:57
Commit może np? Który dziwnie działa…
25 VIII 2008 o 00:57
mmazur:
Userowi commit do czego? Deweloper będzie commitować, to się nauczy używać status i add, a po skończonej pracy push.
Commit bardzo ładnie działa, bo można go cofnąć, więc można sobie commitować każdy kawałek, a na końcu posortować historię i pchnąć.
25 VIII 2008 o 01:14
E, zaraz, ale jaki niby user ma korzystać z gita? Po co? O czym ty w ogóle?
25 VIII 2008 o 01:27
User korzysta z gita po to, żeby przygotować i wysłać łatkę. Deweloper raczej nie będzie miał problemu z gitem.
25 VIII 2008 o 01:35
Ponieważ programiści/deweloperzy wcale nie są leniwi i jak jeden mąż kochają systemy robiące prawie to samo, ale w inny i nieintuicyjny sposób? Taaak.
Przestań palić to świństwo. GIT jest powalony i to nie dla „userów” (user nie ma wcześniejszych doświadczeń z takimi rzeczami, więc po prostu zmałpuje to, co mu tutorial powie), tylko właśnie dla deweloperów. Bo jest nieintuicyjny i skomplikowany.
25 VIII 2008 o 02:05
mmazur:
Używaj go przez jeden dzień do prawdziwej pracy (jak nie masz gdzie, to sobie sklonuj jakiś SVN pod kontrolą gita). Potem powiedz, że jest powalony.
25 VIII 2008 o 02:52
Za dużo pepsi na noc, więc czytam docsy do mercuriala. Wygląda na to, że powinien być w stanie zrobić wszystko to, co jest mi potrzebne, a nawet więcej i to nawet bez polecenia rebase (funkcjonalność rebase’a jest tu do osiągnięcia chyba na dwa sposoby, więc sama komenda będzie tylko pewnym ułatwieniem; chyba).
25 VIII 2008 o 02:55
@Patrys:
Ja tam nie wiem, ale mnie git do siebie przekonał. Uczyłem się go z dokumentacji około jeden dzień (przy tym miał robić za offline’owy VCS dla Subversion), więc nie może być trudny.
Poza tym nie miałem żadnych większych problemów ze znalezieniem właściwego polecenia, chyba że nie istniało. Ale te dwa, których mi brakowało, bez problemu napisałem sobie sam.
Dodajmy do tego, że git faktycznie jest szybki. Bardzo szybki. Pracował błyskawicznie na repozytorium z binarnymi pakietami (coś ponad 600MB kilkumegowych tarballi objętych kontrolą wersji; stosowny wpis na Joggerze). Jestem ciekaw jak by się zachował Mercurial czy bazaar.
@mmazur (kolejność cytatów dowolna):
To tylko dwa gotchas, oba wynikające wprost z odróżnienia lokalnej kopii roboczej plików, zawartości indeksu i gałęzi HEAD.
A to nie do tego służy czasem rozgałęzianie i merge’owanie zmian z gałęzi do gałęzi?
Jest? Ciekawe. Rebase w gicie służy do podmiany historii tak, aby wszystkie patche mieć nałożone na aktualną wersję gałęzi macierzystej. Nie trzeba go używać, wystarczy samo git-merge (uruchamiane przez git-pull).
25 VIII 2008 o 03:46
Jak ostatnim razem patrzyłem na gita, to pluł on na mnie dziwnymi rzeczami przy próbie commitu (te gotchasy), listowanie komend pokazywało ich chyba ze sto, a w dokumentacji nie wiedziałem za co się złapać. I to już było za czasów, gdy się trąbiło o tym, że git się zrobił przystępny dla zwykłych śmiertelników. Więc mam do niego uraz.
Zasadniczo tak, przy czym w darcsie wystarczyło pullować pamiętając o niepullowaniu tych kilku patchy specyficznych dla danego brancha i skutek był taki, że oba branche miały tę samą historię, minus niepullowane patche. Bazaar i owszem pozwala mi mergnąć tylko konkretne rewizje z innego brancha, ale przy okazji tracę historię. Tzn. jeśli merguję cały branch, to jest do tego dołączona cała historia z poprzedniego brancha, jeśli merguję tylko wybrany zakres rewizji, to są one kolapsowane do jednego commita bez załączonej historii. Czyli bazaar się nie nadaje, szukamy dalej (właśnie przejrzałem obecne release note’y do jeszcze nie wydanej wersji 1.6; nie wygląda na to, żeby to poprawili).
Inna sprawa, że na koniec takiej zabawy, nawet przy założeniu, że historia jest poprawnie zapamiętana, miałbym ją w postaci sieczki pozornie bezsensownych mergów i bym pewnie próbował to naprawiać przepisując te merge tak, żeby nie wyglądały jak merge, tylko jak ciągła historia. Strata czasu. O ile rozumiem docsy, w hg do tego jest polecenie transplant zachowujące się po prostu jak darcsowy pull.
W dalszej części tekstu jest wytłumaczone dlaczego w tym wypadku zwykły merge nie jest pożądanym rozwiązaniem.
25 VIII 2008 o 04:38
A ile jest komend do bzr czy hg?
Poza tym ta liczba to konsekwencja wystawienia prawie całej mechaniki na wierzch i wprasowania w system kontroli wersji kilku rzeczy, którymi właściwie nie powinien się zajmować. Skutkiem pierwszego jest fakt, że możesz dobrać się bezpośrednio do indeksu (*-index) czy operować na całym poddrzewie plików (*-tree). Drugie to na przykład tworzenie tarballi z repozytorium oraz wyciąganie i nakładanie patchy bezpośrednio z e-maila.
Ja zaczynałem od man git.
I nadal nie widzę do czego ten rebase jest potrzebny w przypadku gita. Gdy zostały wprowadzone jakieś zmiany do upstreama, to je po prostu ściągasz i merge’ujesz do swojej gałęzi (git-pull albo git-fetch + git-merge). Gdy już masz toto ściągnięte, możesz sobie zrobić git-rebase, żeby swoje lokalne zmiany mieć nakładane do tego, co jest najnowsze w upstreamie zamiast mieszanki commit-commit_upstreamowy-merge.
25 VIII 2008 o 10:50
Mniej. A te „niestandardowe”, czyli poza typowymi, CVS-owatymi są zazwyczaj dodatkowo pochowane jakoś i trzeba je albo ściągnąć (bzr) albo ściągnąć/uaktywnić (hg ma domyślny zestaw nieaktywnych pluginów razem ze sobą).
Jest kompletnie nieistotne czego jest to konsekwencja. Faktem jest, że są ze sobą wymieszane komendy zupełnie różnych poziomów, co utrudnia nowemu użytkownikowi znalezienie czegokolwiek. Inne systemy ewidentnie zwracają na to uwagę, a git jak widzę chyba też w jakimś stopniu, bo w najnowszej wersji wszystkie git-cosie wyleciały z $PATH. Przy czym, czy to jest tylko pierwszy krok na drodze do większej intuicyjności, czy też ostatni, tego nie wiem. I nie mam zamiaru sprawdzać dopóki nie upewnię się, że alternatywy rzeczywiście nie spełniają moich wymogów (bo alternatywy są mniej zastraszające i bardziej intuicyjne).
Czyli nie widzisz po co jest potrzebny, po czym tłumaczysz jak go użyć? To ja z kolei nie widzę logiki w powyższym akapicie. Bo jest mi on właśnie po to, co opisujesz w ostatnim zdaniu tegoż akapitu.
25 VIII 2008 o 11:06
O widzisz, ale dopiero teraz to napisałeś. Założyłem że nie rozumiesz po co jest rebase, stąd wyjaśnienia do czego służy.
A git jest moim zdaniem wystarczająco intuicyjny. Jak mówiłem, nauczyłem się go w jeden dzień, a miał przecież robić nieco więcej niż to, czego się od systemu kontroli wersji na ogół oczekuje.
25 VIII 2008 o 11:49
mmazur:
Prosta ścieżka zdrowia dla pracujących z repo SVN, żebyś mógł się pobawić, zanim uciekniesz z krzykiem i powiesz, że gita nawet kijem zza rogu:
http://live.gnome.org/GitForGnomeDevelopers
26 VIII 2008 o 10:05
Dla zatwardziałych fanów CVS zawsze jest też git-cvsserver, pozwalający na wykonywanie sporej części standardowych operacji CVS (za wyjątkiem tag i branch) na repozytorium git.