Twierdzenie, że „rozgałęzienie jest darmowe w git” jest uproszczeniem faktów, ponieważ samo w sobie nie jest „bezpłatne”. Patrząc pod maską, bardziej poprawnym twierdzeniem byłoby stwierdzenie, że rozgałęzienie jest zamiast tego wyjątkowo tanie , ponieważ gałęzie są w zasadzie odniesieniami do zatwierdzeń . Określam tutaj „taniość” jako im mniejszy koszt, tym tańsze.
Zobaczmy, dlaczego Git jest tak „tani”, sprawdzając, jakie to koszty ogólne:
Jak implementowane są gałęzie w git?
Repozytorium git .git
składa się głównie z katalogów z plikami zawierającymi metadane, których używa git. Ilekroć tworzysz gałąź w git, z np. Dzieje git branch {name_of_branch}
się kilka rzeczy:
- Odwołanie jest tworzone do lokalnego oddziału pod adresem:
.git/refs/heads/{name_of_branch}
- Dziennik historii jest tworzony dla oddziału lokalnego w:
.git/logs/refs/heads/{name_of_branch}
To w zasadzie tyle, że utworzono kilka plików tekstowych. Jeśli otworzysz referencję jako plik tekstowy, zawartość będzie identyfikatorem zatwierdzenia, na który wskazuje gałąź. Zauważ, że rozgałęzienie nie wymaga dokonywania żadnych zatwierdzeń, ponieważ są one innego rodzaju obiektami. Zarówno oddziały, jak i zobowiązania są „pierwszorzędnymi obywatelami” git, a jednym ze sposobów jest myślenie o relacji między oddziałami, a raczej ich agregacją, a nie kompozycją. Jeśli usuniesz gałąź, zatwierdzenia nadal będą istnieć jako „wiszące”. Jeśli przypadkowo usunąłeś gałąź, zawsze możesz spróbować znaleźć zatwierdzenie za pomocą git-lost-found
lub git-fsck --lost-found
utworzyć gałąź na sha-id, który pozostaje wiszący (i dopóki git nie wykonał jeszcze żadnego śmiecia).
Jak więc git śledzi, nad którą gałęzią pracujesz? Odpowiedź brzmi: .git/HEAD
plik, który wygląda mniej więcej tak, jeśli jesteś w master
oddziale.
ref: refs/heads/master
Przełączanie gałęzi po prostu zmienia odwołanie w .git/HEAD
pliku, a następnie przechodzi do zmiany zawartości twojego obszaru roboczego za pomocą tych zdefiniowanych w zatwierdzeniu.
Jak to się ma do innych systemów kontroli wersji?
W Subversion gałęzie są katalogami wirtualnymi w repozytorium . Tak więc najłatwiejszym sposobem na rozgałęzienie jest zrobienie tego zdalnie za pomocą jednej linii svn copy {trunk-url} {branch-url} -m "Branched it!"
. SVN zrobi to:
- Skopiuj katalog źródłowy, np.
trunk
Do katalogu docelowego,
- Zatwierdź zmiany, aby sfinalizować operację kopiowania.
Będziesz chciał wykonać tę akcję zdalnie na serwerze, ponieważ tworzenie tej kopii lokalnie jest operacją w czasie liniowym, a pliki są kopiowane i dowiązane symbolicznie. Jest to bardzo wolna operacja, podczas gdy robienie tego na serwerze jest operacją o stałym czasie. Zauważ, że nawet podczas wykonywania rozgałęzienia na serwerze, subversion wymaga zatwierdzenia podczas rozgałęzienia, podczas gdy git nie, co jest kluczową różnicą. Jest to jeden rodzaj kosztów ogólnych, który sprawia, że SVN jest niewiele tańszy niż Git.
Polecenie przełączania gałęzi w SVN , tj. svn switch
, Jest naprawdę svn update
w przebraniu. Dzięki koncepcji katalogu wirtualnego polecenie jest nieco bardziej elastyczne w svn niż w git. Podkatalogi w twoim obszarze roboczym można zamienić, aby dublować inny adres URL repozytorium. Najbliższą rzeczą byłoby użycie, git-submodule
ale użycie tego semantycznie różni się znacznie od rozgałęzienia. Niestety jest to również decyzja projektowa, która powoduje, że przełączanie jest nieco wolniejsze w SVN niż w Git, ponieważ musi sprawdzać każdy katalog obszaru roboczego, którego zdalny adres URL dubluje. Z mojego doświadczenia wynika, że Git szybciej przełącza gałęzie niż SVN.
Rozgałęzienie SVN wiąże się z pewnym kosztem, ponieważ kopiuje pliki i zawsze musi być publicznie dostępne. W git, jak wyjaśniono powyżej, gałęzie są „tylko referencjami” i można je przechowywać w lokalnym repozytorium i publikować według własnego uznania. Z mojego doświadczenia wynika jednak, że SVN jest nadal znacznie tańszy i bardziej wydajny niż np. ClearCase.
To tylko szaleństwo, że SVN nie jest zdecentralizowany. Możesz mieć wiele repozytoriów odzwierciedlonych w niektórych repozytoriach źródłowych, ale synchronizowanie różnych zmian wiele repozytoriów SVN nie jest możliwe, ponieważ SVN nie ma jednoznacznych identyfikatorów dla zatwierdzeń (git hashuje identyfikatory, które są oparte na zawartości zatwierdzenia). Powodem, dla którego osobiście zacząłem używać git przez SVN, jest to, że inicjowanie repozytorium jest znacznie łatwiejsze i tańsze w git . Pod względem koncepcyjnym w zakresie zarządzania konfiguracją oprogramowania każda rozbieżna kopia projektu (klon, rozwidlenie, obszar roboczy itp.) Jest „gałęzią”, a biorąc pod uwagę tę terminologię, tworzenie nowej kopii w SVN nie jest tak tanie jak Git, gdzie ten ostatni ma oddziały „wbudowane”.
Jako kolejny przykład w Mercurial rozgałęzianie zaczęło się nieco inaczej niż DVCS, a tworzenie / niszczenie nazwanych gałęzi wymagało osobnych zatwierdzeń. Mercurial deweloperzy realizowane w późniejszym okresie rozwoju zakładek naśladować git za samego modelu rozgałęzienia chociaż heads
nazywane są tips
i branches
są bookmarks
zamiast w mercurial terminologii.
This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.
- Utworzenie gałęzi jest proste w SVN, chyba że wykonujesz kopię każdego pliku.Rzeczywistym kosztem oddziału jest jego połączenie. Git czyni to łatwiejszym niż niektóre inne systemy kontroli źródeł. Zobacz pytanie Przepełnienie stosu Jak i / lub dlaczego scalanie w Git jest lepsze niż w SVN? .
źródło
W Git gałąź jest tylko odniesieniem do zatwierdzenia lokalnego repozytorium. Stworzenie go jest bardzo tanie, w ogóle nie ma sieci. Nie całkiem za darmo (musisz wpisać polecenie), ale cholernie blisko.
Rozgałęzienie nie jest szczególnie drogie w SVN - to tylko kopia, która jest bardzo tanim zatwierdzeniem. SVN ma model centralnego repozytorium, więc jest to dostęp do sieci, ale nie straszny.
Z kolei w czcigodnym CVS rozgałęzienie jest BARDZO drogie. Zasadniczo gałęzie CVS wymagają dodania znacznika, ale w CVS oznacza to, że KAŻDY ODDZIAŁYWANY PLIK ODNOŚNIE musi zostać zmodyfikowany. Każdy plik jest przepisywany w celu włączenia nowego znacznika. To jest strasznie drogie. A jeśli twoje repozytorium jest duże, jest również strasznie wolne. W rzeczywistości, jeśli masz duży projekt, jest na tyle powolny, że niektórzy ludzie unikają tworzenia gałęzi, jeśli mogą.
źródło
Rozgałęzienie SVN jest tak samo bezpłatne jak Git. To tylko trochę danych porządkowych, które mówią, gdzie zaczyna się oddział, bez żadnych zmian w przechowywanych plikach. „Kopia” w SVN przypomina dodawanie dowiązania symbolicznego do katalogu Unix. Zauważ, że gałąź SVN nie będzie wymagać wyłączenia sieciowego, dopóki nie zatwierdzisz zmian kopii roboczej (ale SCM nie ma większego sensu, jeśli w pewnym momencie nie wykonasz zlecenia lokalnego).
Zauważ, że gałąź Git będzie również wymagała pewnych czynności porządkowych - takich jak dodanie tego znacznika wewnętrznie - które będą musiały być gdzieś zapisane podczas zatwierdzania. To wcale nie jest wielka sprawa, dlatego nazywa się ją „darmową”.
źródło
Jest „darmowy” (w tym kontekście „bezpłatny” naprawdę oznacza szybki i łatwy i nie zajmujący miejsca), ponieważ w niektórych starszych systemach kontroli wersji gałąź była w tym momencie pełną kopią kodu, więc gałęzie zajmowały dużo miejsca i łatwo było skończyć z wieloma różnymi całkowicie pełnymi wersjami oprogramowania, które następnie objęło zarządzanie. W innych nie była to kompletna kopia kodu, ale każdy plik wciąż wymagał modyfikacji dla tagu, więc był powolny i bolesny („kosztowny”).
gałęzie git są zasadniczo etykietami wskazującymi na zatwierdzenie, dzięki czemu unikają powyższych problemów.
źródło
Kolejny aspekt „darmowy / tani / drogi” dotyczy tego, ile kosztują zasoby programistów, aby poradzić sobie z konsekwencjami dalszego podziału; tj. proces łączenia zmian z oddziałów.
A tutaj łączenie oddziałów w systemach DVCS, takich jak Git i Mercurial, jest łatwiejsze niż w starszych systemach ... ponieważ systemy DVCS znacznie lepiej śledzą historię wersji na wykresie; tzn. tam, gdzie miało miejsce poprzednie połączenie. To sprawia, że fuzje są dokładniejsze, redukuje niepotrzebne konflikty i ... czyni subiektywnie „łatwiejszym” lub „mniej przerażającym” dla zaangażowanych programistów.
źródło