Git, Squid, nagłówki…
Jakiś czas temu do zarządzania własnymi projektami przesiadłem się z darcsa na Gita. Nie jest aż tak intuicyjny, ale nie jest też aż tak zabugowany (w darcsie pewne rzeczy wydają się być broken by design) i ma o wiele większe możliwości. Nie narzuca użytkownikowi żadnego konkretnego modelu pracy, za to daje możliwość użycia w praktycznie dowolny sposób. Jednakowoż, TANSTAAFL. Jest o wiele trudniejszy w obsłudze i do sprawnego użycia wymaga jednak pewnej znajomości działania wnętrzności.
Ale tyle o słoniu. W końcu jakbym chciał na tym blogasku opisywać wszystko, co robię, to pisałbym chyba trochę częściej; porównań systemów kontroli wersji w sieci jest od groma i trochę, i nie ma potrzeby pisania jeszcze jednego. Ku pamięci swojej i innych chciałbym za to opisać, jak git zachowuje się w połączeniu z protokołem HTTP i serwerem pośredniczącym Squid po drodze, co zjadło mi spory kawał czasu dzisiaj, i nie jest tak trywialne. Otóż, w domu siedzę za wspomnianym Squidem – dostawca Internetu nie daje mi pod tym względem wyboru – a jedna z bibliotek, których używam i tworzę (konkretnie CL-Trane) jest dostępna jako repozytorium Gita po HTTP. Psuję ją sobie, psuję, na stanowisku roboczym pchnąłem poprawkę jakiegoś błędu, i próbuję ją pociągnąć na drugim komputerze… Already up-to-date.
Łaty nie ma. Na serwerze – jest; po jakimś czasie nawet na repo.or.cz była widoczna; git clone na serwerze daleko-w-świecie widzi; na komputerze obok stacji roboczej, ani git pull, ani świeży git clone nie widzą. Ki czort?
Oczywiście, mógłbym przepchnąć tę konkretną łatę bezpośrednio z repo roboczego. Ale to niehonorowo, poza tym testowałem akurat instalację od zera (uwaga na boku: Capistrano rządzi rulezem), więc ręczne przeciąganie łatek popsułoby całą zabawę. Po poszukaniu trochę na temat transportu HTTP dla gita (który jest tzw. „głupim” transportem) dotarłem do magicznego pliku .git/info/refs; okazało się, że plik ten obejrzany przeglądarką tekstową na serwerze jest inny niż ten sam plik obejrzany z domu. Przeładowanie go z poziomu przeglądarki WWW doprowadziło zawartość do normy. Uff…
Okazuje się zatem, że Git jako klient HTTP grzecznie współpracuje z serwerami cache'ującymi i pośredniczącymi (co się chwali), ale gdy odpytuje, czy zawartość repozytorium dostępnego przez HTTP nie zmieniła się, jest aż za miły i wierzy serwerowi pośredniczącemu zamiast wymusić na nim sprawdzenie tego bezpośrednio u źródła. Trzeba to na serwerze wymusić samemu, korzystając z przeglądarki, wget --no-cache, czy nawet (opcja dla geeków-superbohaterów) bezpośrednio telnetem lub netcatem. Dobrej zabawy! ;)
