Oto, czego nie lubię w git:
Po pierwsze, myślę, że rozproszona idea leci w obliczu rzeczywistości. Każdy, kto faktycznie używa git, robi to w sposób scentralizowany, nawet Linus Torvalds. Gdyby jądro było zarządzane w sposób rozproszony, oznaczałoby to, że nie mógłbym faktycznie pobrać "oficjalnych" źródeł jądra - nie byłoby takiego - musiałbym zdecydować, czy chcę wersję Linusa, czy wersję Joe, lub wersja Billa. To byłoby oczywiście śmieszne i dlatego istnieje oficjalna definicja, którą Linus kontroluje za pomocą scentralizowanego przepływu pracy.
Jeśli zaakceptujesz, że chcesz scentralizowanej definicji swoich rzeczy, stanie się jasne, że role serwera i klienta są zupełnie inne, więc dogmat, że oprogramowanie klienta i serwera powinno być takie samo, staje się czysto ograniczający. Dogmat, że klient i serwer danych powinna być taka sama staje się jawnie niedorzeczne, szczególnie w kodzie, który dostał piętnaście lat historii, że nikt nie dba o ale każdy musiałby klonu.
To, co naprawdę chcemy zrobić ze wszystkimi starymi rzeczami, to wrzucić je do szafki i zapomnieć, że tam są, tak jak robi to każdy normalny VCS. Fakt, że git codziennie przenosi to wszystko tam iz powrotem przez sieć, jest bardzo niebezpieczny, ponieważ nęka cię przycinanie. To przycinanie wiąże się z wieloma żmudnymi decyzjami i może się nie udać. Więc ludzie prawdopodobnie będą przechowywać całą serię repozytoriów migawek z różnych punktów w historii, ale czy nie po to była przede wszystkim kontrola źródła? Ten problem nie istniał, dopóki ktoś nie wymyślił modelu rozproszonego.
Git aktywnie zachęca ludzi do przepisywania historii, a powyższe jest prawdopodobnie jednym z powodów. Każdy normalny system VCS sprawia, że przepisywanie historii jest niemożliwe dla wszystkich oprócz administratorów i zapewnia, że administratorzy nie mają powodu, aby to rozważać. Popraw mnie, jeśli się mylę, ale o ile wiem, git nie zapewnia możliwości przyznania zwykłym użytkownikom prawa do zapisu, ale zakazuje im przepisywania historii. Oznacza to, że każdy programista mający urazę (lub wciąż borykający się z krzywą uczenia się) może zniszczyć całą bazę kodu. Jak to dokręcamy? Cóż, albo robisz regularne kopie zapasowe całej historii, tj. Utrzymujesz historię do kwadratu, albo blokujesz dostęp do zapisu wszystkim z wyjątkiem jakiegoś biednego drania, który otrzymywałby wszystkie różnice pocztą e-mail i łączył je ręcznie.
Weźmy przykład dobrze finansowanego, dużego projektu i zobaczmy, jak działa dla nich git: Android. Kiedyś postanowiłem pobawić się samym systemem Android. Dowiedziałem się, że powinienem użyć kilku skryptów zwanych repo, aby dostać się do ich gita. Część repozytoriów działa na kliencie, a część na serwerze, ale oba, przez samo ich istnienie, ilustrują fakt, że git jest niekompletny w obu przypadkach. Stało się tak, że nie byłem w stanie wyciągnąć źródeł przez około tydzień, a potem całkowicie się poddałem. Musiałbym pobrać naprawdę ogromną ilość danych z kilku różnych repozytoriów, ale serwer był całkowicie przeładowany ludźmi takimi jak ja. Upłynął limit czasu repozytorium i nie można go było wznowić od momentu, w którym upłynął limit czasu. Jeśli git jest tak rozpowszechnialny, można by pomyśleć, że Zrobiłem coś w rodzaju peer-to-peer, aby odciążyć ten jeden serwer. Git można rozpowszechniać, ale nie jest to serwer. Repozytorium Git + to serwer, ale repozytorium nie można rozpowszechniać, ponieważ jest to po prostu zbiór hacków ad hoc.
Podobną ilustracją nieadekwatności git jest gitolite (i jego przodek, który najwyraźniej nie działał tak dobrze). Gitolite opisuje swoją pracę jako ułatwianie wdrażania serwera git. Ponownie, samo istnienie tego czegoś dowodzi, że git nie jest serwerem, tak samo jak klientem. Co więcej, nigdy nie będzie, ponieważ gdyby wyrósł na jedno z nich, zdradziłoby jego podstawowe zasady.
Nawet gdybyś wierzył w to, co jest rozpowszechniane, git nadal byłby bałaganem. Czym jest na przykład oddział? Mówią, że niejawnie tworzysz gałąź za każdym razem, gdy klonujesz repozytorium, ale to nie może być to samo, co gałąź w pojedynczym repozytorium. Więc to co najmniej dwie różne rzeczy nazywane są gałęziami. Ale możesz też przewinąć do tyłu w repozytorium i po prostu rozpocząć edycję. Czy to jak drugi rodzaj gałęzi, czy znowu coś innego? Może to zależy od tego, jaki masz typ repozytorium - o tak - najwyraźniej repozytorium też nie jest zbyt jasną koncepcją. Są normalne i nagie. Nie możesz przejść do normalnego, ponieważ nieosłonięta część może stracić synchronizację ze swoim drzewem źródłowym. Ale nie możesz importować do gołego, bo oni o tym nie pomyśleli. Więc musisz cvsimportować do normalnego, sklonuj to do nagiego pliku, który trafił programiści, i przenieś to do kopii roboczej cvs, która nadal musi zostać sprawdzona w cvs. Kto może się niepokoić? Skąd się wzięły te wszystkie komplikacje? Z samego rozproszonego pomysłu. W końcu porzuciłem gitolite, ponieważ narzucał mi jeszcze więcej tych ograniczeń.
Git mówi, że rozgałęzianie powinno być lekkie, ale wiele firm ma już poważny problem z nieuczciwymi gałęziami, więc pomyślałbym, że rozgałęzianie powinno być doniosłą decyzją ze ścisłą kontrolą policji. To właśnie tam perforce naprawdę błyszczy ...
Z konieczności rzadko potrzebujesz gałęzi, ponieważ możesz żonglować zestawami zmian w bardzo zwinny sposób. Na przykład, typowy przepływ pracy polega na synchronizacji z ostatnią znaną dobrą wersją w sieci głównej, a następnie napisaniu funkcji. Za każdym razem, gdy spróbujesz zmodyfikować plik, różnica tego pliku zostanie dodana do twojego „domyślnego zestawu zmian”. Kiedy próbujesz sprawdzić zestaw zmian, automatycznie próbuje scalić wiadomości z linii głównej z zestawem zmian (skutecznie zmieniając bazę), a następnie zatwierdza. Ten przepływ pracy jest wymuszany bez konieczności jego zrozumienia. W ten sposób Mainline gromadzi historię zmian, przez które możesz łatwo przejść później. Na przykład załóżmy, że chcesz przywrócić stary, powiedzmy, ten przed ostatnim. Synchronizujesz się z momentem przed szkodliwą zmianą, zaznaczasz pliki, których to dotyczy, jako część zestawu zmian, zsynchronizuj się z chwilą później i połącz z „zawsze moje”. (Było tam coś bardzo interesującego: synchronizacja nie oznacza tego samego - jeśli plik jest edytowalny (tj. W aktywnym zbiorze zmian), nie zostanie on zbity przez synchronizację, ale oznaczony jako przeznaczony do rozwiązania.) Teraz masz lista zmian, która unieważnia jedną z nich. Połącz kolejne wiadomości, a otrzymasz listę zmian, którą możesz umieścić na głównej linii, aby uzyskać pożądany efekt. W żadnym momencie nie przepisaliśmy żadnej historii na nowo. Połącz kolejne wiadomości, a otrzymasz listę zmian, którą możesz umieścić na głównej linii, aby uzyskać pożądany efekt. W żadnym momencie nie przepisaliśmy żadnej historii na nowo. Połącz kolejne wiadomości, a otrzymasz listę zmian, którą możesz umieścić na głównej linii, aby uzyskać pożądany efekt. W żadnym momencie nie przepisaliśmy żadnej historii na nowo.
Teraz, przypuśćmy, że w połowie tego procesu ktoś podbiega do ciebie i każe ci rzucić wszystko i naprawić jakiś błąd. Po prostu nadajesz swojej domyślnej liście zmian nazwę (a właściwie numer), a następnie "zawieszasz" ją, naprawiasz błąd w pustej domyślnej liście zmian, zatwierdzasz ją i wznawiasz nazwaną listę zmian. Typowe jest zawieszenie kilku list zmian naraz, podczas których próbujesz różnych rzeczy. To łatwe i prywatne. Dostajesz to, czego naprawdę chcesz, od reżimu oddziału bez pokusy zwlekania lub powstrzymywania się przed włączeniem się do głównej linii.
Przypuszczam, że teoretycznie byłoby możliwe zrobienie czegoś podobnego w git, ale git praktycznie wszystko umożliwia, zamiast zapewniać przepływ pracy, który akceptujemy. Model scentralizowany to zbiór ważnych uproszczeń w stosunku do modelu rozproszonego, który jest nieprawidłowym uogólnieniem. Jest tak uogólniony, że zasadniczo oczekuje, że zaimplementujesz kontrolę źródła, tak jak robi to repozytorium.
Druga sprawa to replikacja. W git wszystko jest możliwe, więc musisz sam to rozgryźć. W efekcie otrzymujesz efektywnie bezstanową pamięć podręczną. Jedyną konfiguracją, którą musi znać, jest lokalizacja mastera, a klienci mogą wskazać serwer główny lub pamięć podręczną według własnego uznania. To pięć minut pracy i nie może pójść źle.
Masz również wyzwalacze i konfigurowalne formularze do potwierdzania recenzji kodu, odniesień do bugzilli itp. I oczywiście masz gałęzie, które są używane wtedy, gdy ich potrzebujesz. To nie jest jasne, ale jest blisko i jest bardzo łatwe w konfiguracji i utrzymaniu.
Podsumowując, myślę, że jeśli wiesz, że będziesz pracować w sposób scentralizowany, co robi każdy, równie dobrze możesz użyć narzędzia, które zostało zaprojektowane z myślą o tym. Git jest przereklamowany z powodu przerażającego dowcipu Linusa i skłonności ludzi do podążania za sobą jak owce, ale jego główna racja bytu nie stoi w sprzeczności ze zdrowym rozsądkiem, a idąc za nim, wiąże swoje ręce z dwa ogromne dogmaty, że (a) oprogramowanie i (b) dane muszą być takie same zarówno na kliencie, jak i na serwerze, a to zawsze komplikuje i komplikuje scentralizowaną pracę.