0b10

Github został uruchomiony w 2008 roku. Jeśli twoja kariera programistyczna, jak moja, nie jest starsza niż Github, to Git może być jedynym oprogramowaniem do kontroli wersji, którego kiedykolwiek używałeś. Podczas gdy ludzie czasami marudzą o jego stromej krzywej uczenia się lub interfejsie intuicyjnym, Git stał się dla wszystkich wyborem do kontroli wersji. W badaniu InStack Overflow na 2015 r. 69,3% respondentów korzystało z Git, prawie tyle samo, co z drugiego pod względem popularności systemu kontroli wersji,Subversion.1 po 2015 roku Stack Overflow przestał wypytywać programistów o systemy kontroli wersji, których używają, być może dlatego, że Git stał się tak popularny, że pytanie było nieciekawe.

Sam Git nie jest dużo starszy od Githuba. Linus Torvalds wydał pierwszą wersję Git w 2005 roku. Chociaż dziś młodsi programiści mogą mieć trudny czasporozumienie świata, w którym termin „oprogramowanie do kontroli wersji” nie oznaczał bardziej lub mniej tylko Git, taki świat istniał nie tak dawno temu. Było w czym wybierać. Deweloperzy Open source preferowali Subversion, przedsiębiorstwa i firmy produkujące gry wideo korzystały z Perforce (niektórzy nadal tak robią), podczas gdy projekt jądra linuxu słynnie opierał się na systemie kontroli wersji zwanym bitkeeper.

niektóre z tych systemów, szczególnie BitKeeper, mogą wydawać się znajome młodemu użytkownikowi. Większość nie. Pomijając bitkeepera, wersjasystemy kontroli, które pojawiły się przed Gitem, działały zgodnie z fundamentalnym, odmiennym paradygmatem. W taksonomii zaproponowanej przez Erica Sinka, autora VersionControl by Example, Git jest systemem kontroli wersji trzeciej generacji, podczas gdy większość poprzedników Git, systemy popularne w 1990 i na początku 2000, są systemami kontroli wersji drugiej generacji.2 gdzie systemy kontroli wersji trzeciej generacji są rozproszone, systemy kontroli wersji drugiej generacji są scentralizowane. Prawie na pewno słyszałeś już o Git opisywanym jako” rozproszony ” system kontroli wersji. Nigdy nie rozumiałem rozróżnienia rozproszonego/scentralizowanego, przynajmniej dopóki nie zainstalowałem i nie rozwinąłem scentralizowanego systemu kontroli wersji drugiej generacji.

System, który zainstalowałem to CVS. CVS, skrót od Concurrent Versions System, był pierwszym systemem kontroli wersji drugiej generacji. Był to również najbardziej popularny system kontroli wersji przez około dekadę, dopóki nie został zastąpiony w 2000 roku przez Subversion. Nawet wtedy Subversion miał być „CVS, ale lepszy”, co tylko podkreśla, jak dominujące CVS stały się w latach 90.

CVS został po raz pierwszy opracowany w 1986 roku przez holenderskiego Informatyka Dicka Grune ’ a,który szukał sposobu na współpracę ze swoimi uczniami nad projektem kompilatora.3 CVS był początkowo tylko zbiorem skryptów powłoki RCS( Revision Control System), systemu kontroli wersji pierwszej generacji, który Grune chciał ulepszyć. RCS działa według modelu pesymistycznego, co oznacza, że żaden programista nie może pracować na jednym pliku w jednym momencie. Aby edytować plik, musisz najpierw poprosić RCS o wyłączną blokadęna pliku, który przechowujesz do momentu zakończenia edycji. Jeśli ktoś już edytuje plik, który musisz edytować, musisz poczekać. CVS ulepszone na RCSI zapoczątkował drugą generację systemów kontroli wersji, zamieniając model blokowania pesymistycznego na optymistyczny. Programiści mogą teraz edytować ten sam plik w tym samym czasie, łącząc swoje edycje i rozwiązując wszelkie konflikty. (Brian Berliner, inżynier, który później przejął projekt CVS, napisał bardzo czytelny artykuł o innowacjach CVS w 1990 roku.)

w tym sensie CVS nie różnił się aż tak bardzo od Git, który również działa zgodnie z optymistycznym modelem. Ale na tym kończą się podobieństwa. W rzeczywistości, kiedy Linus Torvalds rozwijał Gita, jedną z jego zasad przewodnich byłowwcvsnd, czyli ” czego CVS by nie zrobił.”Ilekroć miał wątpliwości co do decyzji, dążył do wyboru opcji, która nie została wybrana w projektowaniu pojazdów.4 więc mimo że CVS wyprzedził Gita o ponad dekadę, wpłynęło to na Gita jako rodzaj negatywnego szablonu.

bardzo mi się podobało bawić z CVS. Myślę, że nie ma lepszego sposobu, aby zrozumieć, dlaczego rozproszona natura Gita jest taką poprawą tego, co było wcześniej. Więc zapraszam do pójścia ze mną w ekscytującą podróż i spędzić następne dziesięć minut swojego życia uczenia się o kawałek softwarenobody użył w ostatniej dekadzie. (Patrz poprawka.)

pierwsze kroki z CVS

instrukcje instalacji CVS można znaleźć na stronie głównej projektu. Na MacOS, można zainstalować CVS usingHomebrew.

ponieważ CVS jest scentralizowany, rozróżnia wszechświat po stronie klienta i wszechświat po stronie serwera w sposób, w jaki coś takiego jak Git tego nie robi. Thedistinction nie jest tak wyraźny, że istnieją różne pliki wykonywalne. Ale aby rozpocząć korzystanie z CVS, nawet na własnej maszynie, będziesz musiał skonfigurować backend theCVS.

backend CVS, centralny magazyn całego kodu, nazywa się repozytorium.Podczas gdy w Git zazwyczaj masz repozytorium dla każdego projektu, w Cvsrepozytorium przechowuje wszystkie twoje projekty. Istnieje jedno centralne repozytorium na zawsze, choć istnieją sposoby na pracę tylko z projektem naraz.

aby utworzyć lokalne repozytorium, uruchom polecenieinit. Zrobiłbyś to gdziekolwiek globalny jak Twój katalog domowy.

$ cvs -d ~/sandbox init

CVS pozwala przekazać opcje do poleceniacvs lub do poleceniainit. Opcje pojawiające się po poleceniu cvs mają charakter globalny, natomiast opcje pojawiające się po poleceniu podrzędnym są specyficzne dla polecenia sub. W tym przypadku flaga -d jest globalna. Tutaj zdarza się powiedzieć CVSwhere chcemy utworzyć nasze repozytorium, ale ogólnie znacznik-d wskazuje lokalizację repozytorium, które chcemy wykorzystać dla danej akcji. Można betedious dostarczyć-d flagę cały czas, więcCVSROOT environmentvariable można ustawić zamiast.

ponieważ pracujemy lokalnie, właśnie przekazaliśmy ścieżkę dla naszego argumentu -d, ale mogliśmy również podać nazwę hosta.

polecenie tworzy katalog o nazwie sandbox w Twoim katalogu domowym. Jeśli podasz zawartość sandbox, zobaczysz, że zawiera ona inny katalog CVSROOT. Ten katalog, nie mylić z environmentvariable, przechowuje pliki administracyjne dla repozytorium.

Gratulacje! Właśnie utworzyłeś swoje pierwsze repozytorium CVS.

sprawdzanie kodu

powiedzmy, że zdecydowałeś się zachować listę swoich ulubionych kolorów. Jesteś artystycznie skłonny, ale niezwykle zapominalski. Wpisujesz listę kolorów i zapisujesz ją jako plik o nazwie favorites.txt:

blueorangegreendefinitely not yellow

Załóżmy również, że zapisałeś swój plik w nowym katalogu o nazwiecolors. Teraz chcesz umieścić swoją ulubioną listę kolorów pod kontrolą wersji, ponieważ za pięćdziesiąt lat będzie ciekawie spojrzeć wstecz i zobaczyć, jak twoje gusta zmieniały się w czasie.

aby to zrobić, musisz zaimportować swój katalog jako nowy CVSproject. Możesz to zrobić za pomocą poleceniaimport :

$ cvs -d ~/sandbox import -m "" colors colors initialN colors/favorites.txtNo conflicts created by this import

tutaj określamy lokalizację naszego repozytorium za pomocą znacznika-d. Pozostałe argumenty są przekazywane do poleceniaimport. Musimy dostarczyć wiadomość, ale tutaj tak naprawdę jej nie potrzebujemy, więc zostawiliśmy ją w spokoju. Następny argument, colors, określa nazwę naszego nowego katalogu w repozytorium; tutaj właśnie użyliśmy tej samej nazwy, co katalog, w którym się znajdujemy.Dwa ostatnie argumenty określają odpowiednio tag dostawcy i tag wydania.Za chwilę porozmawiamy o tagach.

właśnie wciągnąłeś swój projekt „colors” do repozytorium CVS. Istnieją różne sposoby wprowadzania kodu do CVS, ale jest to metoda zalecana przez Pragmatic Version Control UsingCVS, pragmaticprogrammer book o CVS. To, co sprawia, że ta metoda jest trochę niezręczna, to fakt, że musisz sprawdzić swoją pracę, mimo że masz już istniejący katalog colors. Zamiast używać tego katalogu, musisz go usunąć, a następnie sprawdzić wersję, o której CVs już wie:

$ cvs -d ~/sandbox co colorscvs checkout: Updating colorsU colors/favorites.txt

spowoduje to utworzenie nowego katalogu o nazwiecolors. W tym katalogu znajdziesz oryginalny plik favorites.txt wraz z katalogiem o nazwieCVS. KatalogCVSjest w zasadzie odpowiednikiem katalogu.git w każdym repozytorium Git.

wprowadzanie zmian

przygotuj się na wycieczkę.

podobnie jak Git, CVS mastatus subcommand:

To jest miejsce, gdzie wszystko zaczyna wyglądać obco. CVS nie posiada obiektów commit. Powyżej jest coś, co nazywa się” identyfikatorem zatwierdzeń”, ale może to być tylko stosunkowo niedawne wydanie—brak wzmianki o” identyfikatorze zatwierdzeń ” pojawia się wpragmatycznej kontroli wersji za pomocą CVS, która została opublikowana w 2003 roku. (Ostatnia aktualizacja dla CVS została wydana w 2008.5)

podczas gdy z Gitem można by mówić o wersji pliku powiązanego z commit45de392, w CVs pliki są wersjonowane osobno. Pierwsza wersja yourfile to wersja 1.1, następna wersja to 1.2 i tak dalej. Gdy gałęzie są rozwiązywane, dodawane są dodatkowe liczby, więc możesz skończyć z czymś takim jak1.1.1.1 powyżej, co wydaje się być domyślne w naszym przypadku, mimo że nie stworzyliśmy żadnych gałęzi.

Jeśli chcesz uruchomić cvs log(odpowiednik git log) w projekcie z plikami lotsof i zatwierdzeniami, zobaczysz indywidualną historię dla każdego pliku. Możesz zapisać plik w wersji 1.2 i plik w wersji 1.14 w tym samym projekcie.

przejdźmy do wersji 1.1 naszego plikufavorites.txt :

 blue orange green+cyan definitely not yellow

po dokonaniu zmiany możemy uruchomićcvs diff, aby zobaczyć, co CVs myśli, że dodaliśmy jeden:

CVS rozpoznaje, że dodaliśmy nową linię zawierającą kolor „cyan” do pliku. (Właściwie, mówi, że wprowadziliśmy zmiany w pliku „RCS”; widać, że CVs nigdy nie uniknął w pełni swojego pierwotnego skojarzenia z RCS.) Pokazany przez nas diff to różnica pomiędzy kopią favorites.txt w naszym workingdirectory A wersją 1.1.1.1 przechowywaną w repozytorium.

aby zaktualizować wersję przechowywaną w repozytorium, musimy zatwierdzić zmianę. W Gita byłby to wieloetapowy proces. Musielibyśmy ułożyć zmiany tak, aby pojawiły się w naszym indeksie. Wtedy dokonamy zmiany. Na koniec, aby zmiana była widoczna dla kogokolwiek innego, musielibyśmy przesunąć commit do repozytorium origin.

w CVS wszystkie te rzeczy zdarzają się po uruchomieniucvs commit. CVS po prostu usuwa wszystkie zmiany, które może znaleźć i umieszcza je w repozytorium:

jestem tak przyzwyczajony do Gita, że wydaje mi się to przerażające. Bez możliwości wprowadzania zmian, każda stara rzecz, którą dotknąłeś w swoim działającym katalogu, kończy się jako część publicznego repozytorium. Czy pasywnie agresywnie napisałeś źle zaimplementowaną funkcję współpracownika z oczyszczającej konieczności, nigdy nie zamierzając, aby on się dowiedział? Szkoda, teraz myśli, że jesteś kutasem. Nie możesz również edytować swoich commitów przed ich wypchnięciem, ponieważ commit jest push. Czy lubisz spędzać 40 minut wielokrotnie uruchamiającgit rebase -i, dopóki twoja historia localcommit nie popłynie jak wyprowadzenie dowodu matematycznego? Przykro mi, nie możesz tego zrobić tutaj, a wszyscy się dowiedzą, że nie piszesz najpierw testów.

ale teraz rozumiem, dlaczego tak wielu ludzi uważa Git za niepotrzebnie skomplikowany.Jeśli cvs commit jest tym, do czego przywykłeś, to jestem pewien, że inscenizowanie i popychanie byłoby dla Ciebie bezsensownym obowiązkiem.

Kiedy ludzie mówią o tym, że Git jest systemem „rozproszonym”, jest to przede wszystkim ich odmienność. W CVS nie można wprowadzać zmian lokalnie. Commit jest przekazaniem kodu do centralnego repozytorium, więc nie jest to coś, co można zrobić bez połączenia. Lokalnie masz tylko katalog roboczy. W Git, masz pełnoprawne repozytorium lokalne, więc możesz dokonywać commitów przez cały dzień nawet podczas rozłączenia. I możesz edytować te commity, revert, branch, andcherry pick tyle, ile chcesz, bez nikogo innego musi wiedzieć.

ponieważ commity były czymś większym, użytkownicy CVS często robili je rzadko.Commity zawierałyby tyle zmian, ile obecnie możemy spodziewać się w Aten-commit pull request. Było to szczególnie prawdziwe, jeśli commity wywołały CIbuild i automated test suite.

Jeśli teraz uruchomimy cvs status, widzimy, że mamy nową wersję naszego pliku:

Scalanie

jak wspomniano powyżej, w CVS możesz edytować plik, który już ktoś inny edytuje. To była duża poprawa CVS na RCS. Co się stanie, gdy będziesz musiał połączyć swoje zmiany z powrotem?

Załóżmy, że zaprosiłeś znajomych, aby dodali swoje ulubione kolory do naszej listy. Podczas gdy są one dodawanie ich kolory, zdecydować, że nie dłużnejlubić kolor zielony i usunąć go z listy.

kiedy przechodzisz do zatwierdzania zmian, możesz odkryć, że CVS zauważa problem:

wygląda na to, że Twoi znajomi wpierw popełnili swoje zmiany. Tak więc Twoja wersja favorites.txt nie jest aktualna z wersją w repozytorium. Jeśli użyjesz cvs status, zobaczysz, że Twoja lokalna kopia favorites.txt to wersja 1.2 z pewnymi lokalnymi zmianami, ale wersja repozytorium to 1.3:

możesz uruchomić cvs diff, aby zobaczyć dokładnie, jakie są różnice między 1.2 A 1.3:

wygląda na to, że nasi przyjaciele naprawdę lubią pink. W każdym razie edytowali inną część pliku niż my, więc zmiany są łatwe do scalenia. CVScan zrobi to za nas, gdy uruchomimy cvs update, który jest podobny do git pull:

$ cvs updatecvs update: Updating .RCS file: /Users/sinclairtarget/sandbox/colors/favorites.txt,vretrieving revision 1.2retrieving revision 1.3Merging differences between 1.2 and 1.3 into favorites.txtM favorites.txt

Jeśli teraz spojrzysz nafavorites.txt, przekonasz się, że został zmodyfikowany, aby uwzględnić zmiany, które Twoi znajomi wprowadzili do pliku. Twoje zmiany też tam są. Teraz możesz zatwierdzić plik:

rezultatem końcowym jest to, co uzyskasz w gitu, uruchamiając git pull --rebase. Twoje zmiany zostały dodane oprócz zmian twoich znajomych. Nie ma „mergecommit.”

czasami zmiany w tym samym pliku mogą być niekompatybilne. Gdyby Twoi znajomi zmienili na przykład „zielony” na „oliwkowy”, spowodowałoby to konflikt z Twoją zmianą całkowicie usuwając „zielony”. We wczesnych dniach CVS był to dokładnie taki przypadek, który powodował, że ludzie martwili się, że CVS nie jest bezpieczne; Ryglowanie pesymistyczne RCS zapewniło, że taki przypadek nigdy nie może powstać. Ale CVs gwarantuje bezpieczeństwo, upewniając się, że żadne zmiany nie zostaną automatycznie nadpisane. Musisz powiedzieć CVs, które zmiany chcesz zachować, więc po uruchomieniu cvs update, CVS zaznacza plik obiema zmianami w taki sam sposób, jak robi to Git, gdy Git wykryje konflikt scalania. Następnie musisz ręcznie edytować plik i wybrać zmianę, którą chcesz zachować.

ciekawostką jest to, że konflikty scalania muszą zostać naprawione przed zatwierdzeniem. Jest to kolejna konsekwencja scentralizowanego CVS nature.In Git, nie musisz się martwić o rozwiązywanie mergów, dopóki nie wypchniesz poleceń, które masz lokalnie.

tagi i gałęzie

ponieważ CVS nie ma łatwo adresowalnych obiektów commit, jedynym sposobem na grupowanie zmian jest zaznaczenie określonego stanu katalogu roboczego za pomocą atag.

Tworzenie tagu jest łatwe:

$ cvs tag VERSION_1_0cvs tag: Tagging .T favorites.txt

będziesz później mógł przywrócić pliki do tego stanu, uruchamiając cvs update I umieszczając tag do -r flaga:

$ cvs update -r VERSION_1_0cvs update: Updating .U favorites.txt

ponieważ potrzebujesz znacznika do przewinięcia do wcześniejszego stanu katalogu roboczego, Cvsencouca wiele prewencyjnych tagów. Na przykład przed głównymi refaktorami możesz utworzyć znacznikBEFORE_REFACTOR_01, którego możesz później użyć, jeśli therefactor pójdzie źle. Ludzie używali również tagów, jeśli chcieli generować dyfferencje o szerokim zakresie projektów. Zasadniczo, wszystkie rzeczy, które rutynowo robimy dzisiaj z commithashes muszą być przewidywane i planowane w CVs, ponieważ musiałeś mieć już dostępne tagi.

gałęzie mogą być tworzone w CVS, tak jakby. Gałęzie są po prostu specjalnym rodzajem tagu:

$ cvs rtag -b TRY_EXPERIMENTAL_THING colorscvs rtag: Tagging colors

, który tworzy tylko gałąź (przy okazji w pełnym widoku wszystkich), więc musisz przełączyć się na nią za pomocą cvs update:

$ cvs update -r TRY_EXPERIMENTAL_THING

powyższe polecenia przełączają się na nową gałąź w bieżącym katalogu workingdirectory, ale pragmatyczna Kontrola wersji za pomocą CVs faktycznie radzi, aby utworzyć nowy katalog, aby utrzymać nową gałąź. Prawdopodobnie jego autorzy stwierdzili, że Przełączanie katalogów jest łatwiejsze niż przełączanie gałęzi w CVS.

pragmatyczna Kontrola wersji przy użyciu CVS odradza również tworzenie gałęzi istniejącej gałęzi. Zalecają tylko tworzenie odgałęzień z gałęzi themainline, która w Gitcie jest znana jako master. Ogólnie rzecz biorąc, rozgałęzianie uważano za” zaawansowaną ” umiejętność CVS. W Gita, możesz uruchomić nową gałąź z niemal każdego błahego powodu, ale w CVS rozgałęzienia były zazwyczaj używane tylko wtedy, gdy jest to naprawdę konieczne, na przykład w przypadku wydań.

gałąź może być później połączona z powrotem do głównej linii za pomocącvs update I flagi-j :

$ cvs update -j TRY_EXPERIMENTAL_THING

dzięki za Historię commitów

w 2007 roku Linus Torvalds wygłosił atalk o Git w Google. Git był wtedy bardzo nowy, więc prelekcja była w zasadzie próbą przekonania wielu doświadczonych programistów, że powinni używać Git, mimo że Git był tak różny od wszystkiego, co wtedy było dostępne. Jeśli jeszcze nie widzieliście wykładu, gorąco zachęcam do obejrzenia. Linus jest zabawnym mówcą, nawet jeśli henever nie jest jego zuchwałym sobą. Doskonale wyjaśnia, dlaczego rozproszony model kontroli wersji jest lepszy niż scentralizowany. Wiele jego krytyki jest zarezerwowane dla CVS w szczególności.

Git jest złożonym narzędziem. Uczenie się go może być frustrującym doświadczeniem. Ale wciąż jestem zdumiony tym, co robi Gitcan. Dla porównania, CVS jest prosty i prosty, choć często niemożnyby wykonać wiele operacji, które teraz uważamy za oczywiste. Powrót i korzystanie z CVSfor a while to doskonały sposób, aby znaleźć się w nowym uznaniu dla siły i elastyczności forGit. To dobrze ilustruje, dlaczego zrozumienie historii tworzenia oprogramowania może być tak korzystne-zbieranie i ponowne analizowanie narzędzi Sol nauczy Cię tomów o tym, dlaczego za narzędziami, których używamy dzisiaj.

Jeśli podobał Ci się ten post, więcej takich wychodzi co cztery tygodnie! Śledź @TwoBitHistory na Twitterze lub subskrybuj kanał RSS, aby upewnić się, że wiesz, kiedy pojawi się nowy post.

korekta

powiedziano mi, że istnieje wiele organizacji, szczególnie organizacji ryzyka, które robią takie rzeczy, jak tworzenie oprogramowania urządzeń medycznych, które nadal używają vs. Programiści w tych organizacjach opracowali małe sztuczki do pracy wokół ograniczeń CVS, takich jak stworzenie nowej gałęzi dla prawie everychange, aby uniknąć bezpośredniego zatwierdzania HEAD. (Podziękowania dla Michaela Kohne ’ a za wyjaśnienie tego.)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *