Mam ciekawą obserwację związaną ze sposobem używania różnych systemów kontroli wersji. Dokładniej mówiąc, chodzi o dość wyraźną różnicę w częstotliwości commitów między zwykłymi a rozproszonymi VCS-ami. Do tych pierwszych kod commituje się stosunkowo rzadko, ponieważ każda zmiana jest od razu widoczna w publicznym repozytorium. To ma zaś daleko idące konsekwencje, jak choćby natychmiastowa dostępność naszych modyfikacji dla innych osób pracujących nad projektem. Dlatego też trzeba starać się, aby nie wypuścić bubla. Minimalnym wymaganiem jest kompilowalność commitowanego kodu, a dobrze by było, żebyśmy też poddali go choćby wstępnemu testowaniu.
Gdy z kolei pracujemy z rozproszonymi systemami kontroli wersji, możemy teoretycznie robić dokładnie tak samo. Wówczas jednak nie tylko nie korzystamy z faktu posiadania lokalnego repozytorium, ale wręcz dodajemy sobie pracy. Osiągnięcie tego samego efektu (upublicznienia zmian) wymaga bowiem dwóch kroków – dodatkowym jest push, czyli synchronizacja z globalną bazą kodu. Będąc przyzwyczajonym do scentralizowanych VCS-ów można łatwo o nim zapomnieć.
Dlatego też wydaje mi się, że przy systemie rozproszonym warto nieco zmienić nawyki. Commitów można bowiem dokonywać częściej – znacznie częściej. Ponieważ żaden z nich nie wydostaje się automatycznie poza nasz komputer, nie muszą one dodawać kompletnych funkcjonalności albo w pełni poprawiać znalezione wcześniej błędy. Nie muszą działać. Ba, w zasadzie to nie muszą nawet się kompilować. Grunt, żeby zawierały modyfikacje, które wydają nam się warte zachowania i opatrzenia komentarzem. W praktyce w ciągu dnia można w ten sposób wykonać nawet do kilkudziesięciu commitów – w porównaniu do dwóch lub trzech w przypadku pracy z system scentralizowanym.
Czy taka częstotliwość dobrze wpływa na efektywność kodowania? Z początku nie byłem o tym przekonany, ale teraz widzę, że ma ona niewątpliwe zalety. Wykonując częste commity (a zwłaszcza opisując je), programujemy w sposób bardziej zdyscyplinowany. Trochę trudniej jest wtedy napisać wysublimowany, barokowo skomplikowany i ogólnie przekombinowany moduł albo takąż klasę. Mamy raczej większe szanse na to, że poczynimy jakieś realne postępy w pracy nad projektem. Dodatkowo częste “odhaczanie” wykonanych zadań i poczynionych postępów (nawet jeśli są bardzo drobne) jest bardziej motywujące niż oznaczanie zmian rzadkich a duże.
A co jeśli naszą przeszkodą w wykonywaniu częstych commitów jest brak weny twórczej odnośnie komentarzy do nich?… No cóż, wtedy zawsze można poszukać inspiracji tutaj ;-)
W przypadku centralizowanych VCS też można wykonywać commity co 15 minut. Wystarczy spełnić jeden z dwóch warunków:
– być jedyną osobą pracującą nad projektem/częścią projektu
– wydzielić sobie opracowywany kod do brancha ;-)
Choć fakt, w pierwszym przypadku nie ma różnicy między rozproszonym a centralizowanym systemem, w drugim wszystko jest ładnie do czasu łączenia zmian z pozostałym kodem – do czego nawiązując, życzę “obyś po miesiącu zrobił SVN Merge” wszystkim złym programistom :D
Z tym że przy DVCS można robić małe, śmieciowe commity się nie zgodzę jeżeli ktoś ma to potem czytać. Chyba że ktoś po skończonej “walce” zrobi patcha po czym cofnie się do mastera. Ale undo w IDE jest jednak do takich zadań zwykle lepsze. :)
Natomiast ważne jest (niezależnie czy VCS czy DVCS) żeby robić commity możliwie małe, dotyczące jednego konkretnego zagadnienia. Tutaj zaawansowane projekty open-source górują znacznie nad “biznesowymi” bo zwykle każdy commit w tych pierwszych zawiera dokładny opis zmian, wyjaśnienia dotyczące poprawianych usterek itp a nie “poprawki tu i ówdzie, jest 18 i idę do domu” ;)
@Dab: Nie wiem jak jest w Gicie, ale w Hg można “skompresować” kilka commitów w jeden przed wypchnięciem zmian na zewnątrz. W ten sposób parę “śmieciowych” commitów możemy połączyć w jeden i trzymać się zasady, że każdy revision w głównym repozytorium zawiera kompilowalny lub względnie działający kod.
Ja uważam częste komity i częstą integrację za podstawę zdrowej współpracy, i staram się tak działać niezależnie od rodzaju vcsa. Wolę zrobić commit z odpiętym, niedziałającym i nieprzetestowanym mechanizmem nad którym pracuję, niż chomikować go u siebie i potem modlić się o dobrą reakcję reszty teamu.
A opisanego mechanizmu nie lubię z bardzo prostego powodu – zachęca do tworzenia lokalnego brancha, i pracy u siebie bez pokazywania tego reszcie. Czyli jest dokładnie counterproductive – zamiast małych, regularnych zmian dostajemy jedną bombę na koniec tygodnia. “No ale po co miałem wysyłać, miałem lokalne kommity”. Yh.
IMO częstotliwość wynika też z faktu, że w DVCSie commity robi się dużo szybciej – nie trzeba czekać aż zmiany pójdą na serwer. Nie ma też problemu gdy repo padnie, a to się niestety zdarza ;-/
@Asmodeusz:
„obyś po miesiącu zrobił SVN Merge”
nawet przy dużej funkcjonalności jeżeli regularnie mergujesz trunka do siebie to nie masz takich problemów.
@Xion:
W gicie też można łączyć commity (git rebase -i). Osobiście nie jestem do tego jeszcze przekonany i obecnie nie “kompresuję”.
@Liosan:
Nie zgodzę się z tym co piszesz. Umawiacie się, że stawiacie git-daemon i każdy może przeglądać na bieżąco zmiany innych. Poza tym lokalne branche można pushnąć, tak aby inni je też widzieli.