streszczenie książki Git dla profesjonalistów Scott Chacon, Ben Straub (2022, wyd. II) efektywny system kontroli wersji jest w pracy zespołowej niezbędny git to powszechnie stosowane rozwiązanie w tym zakresie - umożliwia m. in. zarządzanie wersjami projektu, przeglądanie wszystkich zmian oraz przywracanie pliku do dowolnej wcześniejszej wersji git, choć parę wiosen już ma, wciąż dynamicznie się rozwija - dwa różne wydania tej książki dzieli zaledwie kilka lat, a przez ten czas zmieniło się tak wiele git ewoluował z prostego systemu kontroli wersji zmieniając się w rozwiązanie dominujące na rynku tworzenie oprogramowania z pomocą gita jest bardzo naturalne ZACZYNAMY na początek - omówienie VCS (version control system), uruchomienie gita w systemie oraz odpowiednie skonfigurowanie go i przygotowanie do dalszej, właściwej pracy czym właściwie są VCS? ano zajmują się zapamiętywaniem zmian wprowadzanych do plików (nie tylko kody źródłowe), co pozwala na późniejsze odwoływanie się do poszczególnych wersji można sprawdzić, kto wprowadził modyfikacje powodujące różne problemy i co ważne, raptem niewielkie zaangażowanie wystarczy, aby osiągnąć co w/w lokalne systemy kontroli wersji - wiele osób, na początku, wersjonowało pliki kopiując je do nowych katalogów opatrzonycyh datą - rozwiązanie proste i intuicyjne, choć ciężkie w stosowaniu, łatwo o pomyłki dlatego dawno temu powstały lokalne VCS, które budowały prostą bazę danych przechowującą wszystkie zmiany wprowadzane do plików objętych kontrolą następnie scentralizowane systemy kontroli wersji - kolejnym problemem jest konieczność współpracowania z innymi programistami, z czym poradzono sobie za pomocą scentralizowanych VCS w systemach tych istnieje specjalny serwer, przechowujący wszystkie pliki poddawane wersjonowaniu, a dowolna liczba klientów może pobierać te pliki z serwera przez wiele lat był to standard - do pewnego stopnia każdy wie, nad czym pracują pozostali członkowie zespołu, a admini mogą dokładnie określać uprawnienia poszczególnych użytkowników niestety, najbardziej oczywistą wadą jest pojedynczy punkt awarii - sam centralny serwer, np. przez godzinę nie będzie działał i praca jest wtedy sparaliżowana, a ponadto istnieje ryzyko utraty danych i wreszcie rozproszone systemy kontroli wersji (distributed) - w tym typie klienci nie pobierają jedynie ostatniej postaci każdego pliku, tylko wykonują pełną kopię całego repozytorium więc w razie awarii serwera - łatwo odzyskać dane, korzystając z danych jednego z klientów jednak przy każdym pobraniu danych z serwera, należy wykonać pełną kopię zapasową przechowywanych na nim informacji git nie powstał w obecnej formie od razu - tylko w kreatywnej destrukcji i w kontrowersjach - a do jego cech należą: szybkość, prostota, obsługa nieliniowego rozwoju (tysiące równoległych gałęzi), rozproszenie, skuteczne obsługiwanie wielkich projektów jak działa git? inne VCS przechowują informacje w postaci listy zmian wprowadzanych do plików - plik bazowy i zbiór zmian z czasem dodawanych git natomiast traktuje wszystkie dane jako zbiór migawek; przy wykonywaniu każdego zatwierdzania zmian wykonuje migawkę zawartości wszystkich plików projektu i zapisuje sobie referencję do niej (oczywiście niezmienione pliki, w ramach lepszej wydajności pracy, nie są ponownie zapisywane, tylko wykorzystywana jest referencja) mamy więc de facto strumień migawek niemal każda operacja wykonywana jest lokalnie - ponieważ cała historia projektu jest na dysku klienckim nie trzeba niczego pobierać z serwera, aby np. porównać zmiany ponadto, pracować można nawet w przypadku braku połączenia z siecią - samolot/pociąg zatwierdzasz zmiany wedle uznania, by w odpowiednim momencie przesłać je do głównego repozytorium po uzyskaniu połączenia z siecią w gicie wszystko przed zapisaniem w bazie danych otrzymuje swoją sumę kontrolną - z użyciem algorytmu SHA-1 - 40-znakowy łańcuch szesnastkowy i powstają pary: identyfikator (klucz) SHA-1 oraz zawartość pliku w gicie trudno np. utracić dane, dlatego warto eksperymentować podczas jego nauki - bez obaw git definiuje trzy stany, w których mogą znajdować się pliki: zatwierdzony (committed), zmodyfikowany (modified) i obszar przechowywania (staged) zatwierdzony - dane są bezpiecznie zapisane w lokalnej bazie zmodyfikowany - do śledzonego pliku wprowadzono zmiany i są jeszcze niezatwierdzone śledzony - oznacza, że aktualna wersja pliku oznaczona jest jako część następnej zatwierdzanej migawki katalog gita (.git) to miejsce w którym znajduje się baza danych i metadane (dane o danych) katalog roboczy to kopia jednej z wersji projektu, pliki z tego katalogu pobierane są ze skompresowanej bazy danych obszar przechowywania to plik z katalogu gita, w którym zapisane są informacje jakie elementy mają być częścią następnej operacji zatwierdzania w najprostszym przykładzie: zmieniasz zawartość plików w katalogu roboczym --> oznaczasz pliki jako śledzone --> wykonujesz zatwierdzenie, w wyniku którego zawartość plików z obszaru przechowywania zapisywana jest na stałe w katalogu gita zauważ: jeśli wiesz, jak posługiwać się gitem z wiersza poleceń, z pewnością łatwo odnajdziesz się w programie z gui (zależność ta nie działa w drugą stronę) po zainstalowaniu gita (uruchamianie na windowsie: poprzez aplikację git bash) należy przeprowadzić szybką konfigurację polecenie git config umożliwia odczytywanie i ustalanie zmiennych konfiguracyjnych wpływających na działanie gita istnieją trzy różne miejsca, w których zmienne te są zapisane: --system czyli wszyscy użytkownicy systemu oraz wszystkie repozytoria --global czyli konfiguracja właściwa danemu użytkownikowi plik config znajdujący się w katalogu poszczególnego repozytorium każdy następny poziom nadpisuje wartości z poziomów poprzednich na początek ustaw tożsamość (nazwa użytkownika + email) git config --global user.name "Adam Rębowicz" git config --global user.email arebowicz@gmail.com ponadto, można ustawić domyślny edytor tekstu używany za każdym razem, gdy git poprosi o wpisanie wiadomości git config --global core.editor xxx celem skontrolowania ustawień wystarczy wywołać polecenie git config --list niektóre klucze z tej listy mogą wystąpić wielokrotnie (bo są w różnych plikach), a wiążące są wartości z ostatniego odczytanego pliku można też sprawdzić wartość wybranego klucza, np git config user.name manual dla konkretego polecenia gita to git help czyli np. git help config PODSTAWY GITA w niniejszym rozdziale: konfiguracja i inicjowanie repozytorium, rozpoczynanie i zatrzymywanie śledznia plików, umieszczanie plików w przechowalni i zatwierdznie wprowadzonych zmian, ignorowanie wybranych plików/plików pasujących do wzorca oraz jak szybko i łatwo cofnąć niepoprawne operacje, także przeglądanie historii projektu oraz sprawdzanie zmian wprowadzonych w kolejnych commitach, a także pobieranie/wypychanie danych z/na zdalnych repozytoriów repozytorium można zainicjować w już istniejącym katalogu, bądź można sklonować je z innego serwera w katalogu głównym z projektem wystarczy wpisać polecenie git init utworzony zostanie nowy podkatalog o nazwie .git z podstawowym szkieletem repozytorium gita na tym etapie jeszcze żaden z plików projektu nie jest poddawany śledzeniu aby rozpocząć kontrolowanie wersji istniejących już plików, należy włączyć ich śledzenie i wykonać początkowe zatwierdzenie w bazie, czyli np: git add *.c git add LICENCJA git commit -m "pierwsza wersja projektu" i oto mamy repozytorium gita ze śledzonymi plikami oraz początkowym commitem z kolei aby uzyskać kopię istniejącego już repozytorioum, np. projektu w którego rozwoju uczestniczysz, użyj polecenia git clone istotna uwaga: jest to polecenie clone (sklonuj) a nie checkout (pobierz plik) - git tworzy pełną kopię niemal wszystkich danych git clone [url] ewentualnie git clone [url] nazwa-katalogu aby sklonować repo do katalogu o innej nazwie niż domyślna do transferu plików git stosuje kilka różnych protokołów (https, lub ssh itd) skoro mamy już przygotowane repozytorium gita, warto wprowadzić do niego kilka zmian i zatwierdzić migawki - takie zatwierdzenia na co dzień wykonywać należy za każdym razem, gdy w projekcie uzyskamy stan wart zapamiętania na początek: każdy plik w katalogu roboczym może mieć dwa stany - śledzony lub nieśledzony śledzone pliki to te, które znalazły się w ostatniej migawce (i mogą być niezmodyfikowane, zmodyfikowane lub przechowywane) natomiast nieśledzone pliki to cała reszta - nie były częścią ostatniej migawki ani nie zostały umieszczone w obszarze przechowywania domyślnie, po pierwszym sklonowaniu repozytorium, wszystkie pliki są jednocześnie śledzone i niezmodyfikowane po edycji pliku, git oznacza go jako zmodyfikowany - plik ten umieścić należy w strefie przechowywania, a potem całą tę strefę zatwierdzić trzeba w bazie repo - i cały cykl zaczyna się od nowa głównym poleceniem do kontrolowania stanów, w których znajdują się różne pliki, jest polecenie git status zaraz po sklonowaniu repo, git status zwraca: On branch main nothing to commit, working directory clean co oznacza, że masz do dyspozycji czysty katalog roboczy - ale nie tylko, bo git nie identyfikuje żadnych plików nieśledzonych, które, gdyby się pojawiły, zostałyby wylistowane załóżmy, że dodajemy nowy plik do projektu $ echo 'projekt' > CZYTAJ.MNIE $ git status nowy wydruk pokaże nowy, nieśledzony plik - w sekcji "Untracked files:" untracked czyli nie było go w poprzedniej migawce i nie został dołączony do poczekalni dla następnej migawki i tu istotna uwaga: takie dodanie do migawki wykonać należy samodzielnie, chodzi o to, żeby git przez przypadek nie dołączał plików niepożądanych/niechcianych, np. plików binarnych/outputów itp aby rozpocząć śledzenie nowego pliku, wystarczy użyć polecenia git add git add CZYTAJ.MNIE teraz po wywołaniu polecenia git status zobaczysz, że plik CZYTAJ.MNIE jest śledzony, umieszczony w strefie przechowywania i gotowy do zatwierdzenia (Changes to be committed: new file: CZYTAJ.MNIE) [Changes to be committed to inaczej zmiany do zatwierdzenia] jeśli teraz zatwierdzisz zmiany, w historii projektu znajdzie się nowa migawka z wersją pliku z momentu uruchomienia polecenia git add ponadto, gdybyś podał w poleceniu git add ścieżkę katalogu, wówczas rekursywnie dodanoby do śledzenia wszystkie zapisane w katalogu pliki a teraz - zmień plik, który jest już śledzony - np. plik pomiary.rb i wywołaj polecenie git status wyświetlą się "Changes not staged for commit:" czyli zmiany nieprzeznaczone do zatwierdzenia, więc plik jest śledzony i zmodyfikowany, ale nieumieszczony w strefie przechowania wystarczy teraz wywołać polecenie git add - jak widać, ma wiele zastosowań, np.: można śledzić pliki, przenosić pliki do przechowalni, czy - w przyszłości - oznaczać pliki z konfliktami po złączeniach jako oczyszczonych z tych konfliktów czyli polecenie git add można ogólnie potraktować jako narzędzie do "dodawania pewnych treści do następnej operacji zatwierdzania" (nie ogranicza się jedynie do dodawania plików do przechowalni) wywyołaj teraz polecenie git add pomiary.rb a następnie polecenie git status teraz obydwa pliki są w przechowalni i staną się częścią następnego commitu (Changes to be committed:) - ale zauważ, że pierwszy opatrzony jest jako "new file", a drugi jako "modified" - git to wykrywa załóżmy jednak, że na koniec przypominasz sobie o jeszcze jednej małej zmianie, jaka powinna zostać wprowadzona do pliku pomiary.rb otwierasz plik, zmieniasz go i wszystko wydaje się gotowe... więc wywołujesz, na wszelki wypadek, polecenie git status, a tam: plik pomiary. rb znajduje się nie tylko w poczkelani (Changes to be committed:) ale również na liście plików zmodyfikowanych (Changes not staged for commit:) dlaczego tak? okazuje się, że git umieszcza w przechowalni plik w wersji, w jakiej był, gdy wpisano polecenie git add gdybyś teraz zatwierdził zmiany poleceniem git commit, do bazy trafi wersja poprzednia - wcześniej umieszczona w przechowalni - a nie ta znajdująca się aktualnie w katalogu roboczym z tego powodu trzeba jeszcze raz wywołać polecenie git add pomiary.rb i git status zwróci teraz co oczekiwane informacje wypisywane przez polecenie git status są bardzo dokładne, ale jednocześnie sam wydruk jest dość rozwlekły istnieje opcja skróconego statusu - forma kompaktowa: git status -s lub git status --short $ git status -s M CZYTAJ.MNIE MM Rakefile A lib/git.rb M lib/prostygit.rb ?? LICENCJA.txt na takim wydruku: pliki nowe, jeszcze nieśledzone oznaczane są znakami ?? nowe pliki dodane już do strefy przechowywania oznaczane są literą A natomiast pliki zmodyfikowane literą M - po lewej plik dodany do przechowalni, po prawej plik niedodany do przechowalni choć zmodyfikowany więc, co ciekawe: w przypadku pliku Rakefile - został zmodyfikowany i przeniesiony do przechowalni, a potem został jeszcze raz zmodyfikowany w katalogu roboczym ignorowanie plików - często zdarza się, że w projekcie mamy pliki, których nie tylko nie chcemy dodawać do repo, ale też nie powinny pojawiać się na liście plików nieśledzonych (bo po co mają mącić uwagę) zwykle może chodzić o pliki generowane automatycznie w takich przypadkach wystarczy przygotować plik .gitignore z listą wzorców nazw plików do ignorowania np.: *.[oa] # ignoruje wszystkie pliki, których nazwa kończy się znakami o lub a !lib.a # ale śledź plik lib.a mimo ignorowania wszystkich innych plików .a build/ # ignoruj wszystkie pliki z katalogu build/ *~ # nakazuje gitowi ignorować wszystkie pliki, których nazwy kończą się znakiem tyldy, ponieważ te są często używane przez różne edytory tekstu do oznaczania plików tymczasowych na liście tej umieścić można też katalogi jak log, czy tmp, bądź choćby automatycznie generowaną dokumentację plik .gitignore warto przygotować przed przystąpieniem do pracy nad projektem reguły obowiązujące w plikach i rozmaite przykłady z uproszczonymi wyrażeniami regularnymi znajdziesz w książce, internecie, bądź na stronie github.com/github/gitignore polecenie git status może wydać się niedość szczegółowe - możesz chcieć wiedzieć co dokładnie zostało zmienione, a nie tylko przejrzeć listę plików i tu z odsieczą przychodzi polecenie git diff - najczęściej będzie służyło do odpowiedzi na dwa następujące pytania: co zmieniono, lecz nie przeniesiono tego do poczekalni oraz jakie zmiany staną się częścią następnego commitu aby sprawdzić, jakie zmiany nie znalazły się jeszcze w przechowalni, wystarczy uruchomić polecenie git diff nie podając mu żadnych argumentów aby porównać zmiany umieszczone już w przechowalni ze zmianami z ostatnio wykonanym commitem, trzeba użyć polecenia git diff --staged w szczególności: gdy wszystkie zmiany zostaną przeniesione do przechowalni, polecenie git diff nie pokaże żadnych zmian weźmy przykład z plikiem pomiary.rb - jako zmodyfikowanym, następnie umieszczonym w przechowalni i na koniec raz jeszcze zmodyfikowanym po wpisaniu git status mamy zmiany i w "Changes to be committed: modified ..." i w "Changes not staged for commit: modified ..." i możesz zastosować obydwa polecenia: git diff --staged (lub synonimicznie git diff --cached) albo samo git diff zatwierdzanie zmian - pamiętaj, że wszystko, co nieumieszczone w przechowalni, czyli pliki nowoutworzone albo zmodyfikowane po ostatnim uruchomieniu na nich polecenia git add, nie zostaną uwzględnione przy tworzeniu commitu pozostaną one na dysku jako pliki zmodyfikowane - w obszarze (katalogu) roboczym i można je umieścić w kolejnym commicie załóżmy, że wszystko jest już w poczekalni i wywołajmy polecenie git commit tak wywołane polecenie uruchomi skonfigurowany wcześniej edytor (albo ze zmiennej środowiskowej, albo z polecenia np. git config --global core.editor) w edytorze pojawi się domyślny tekst zawierający wyniki zwracane przez polecenie git status umieszczone w komentarzach - komentarze można usunąć i wpisać własną treść komunikatu, a nawet można zostawić komentarze bez zmian możliwe jest także wywołanie polecenia git commit z parametrem -v w wyniku czego opis zmian umieszczony po uruchomieniu edytora będzie jeszcze pełniejszy po zamknięciu edytora, git utworzy w bazie danych nowy commit i opatrzy go wpisanym komunikatem (oczywiście wszystkie komentarze są z niego usuwane) istnieje również możliwość wpisania komunikatu zatwierdzania jako części wywołania polecenia git commit, do czego służy opcja -m, jak poniżej: git commit -m "podsumowanie wprowadzonych zmian" wypisane zostaną wówczas różne informacje na temat commitu: w jakiej gałęzi został utworzony, jaki otrzymał skrót SHA-1, ile plików zmieniono oraz jaka jest statystyka - liczba dodanych i usuniętych wierszy tekstu czasami może zajść chęć/potrzeba by pominąć obszar przechowywania - wywoływanie dwóch poleceń może wydawać się uciążliwe i nadmierne żeby pominąć przechowalnię, wystarczy dopisać opcję -a do polecenia git commit, wówczas git automatycznie umieści w obszarze przechowywania wszystkie śledzone pliki aby usunąć plik z repo gita, należy usunąć go z plików śledzonych, a następnie zatwierdzić nowy commit do usunięcia pliku z plików śledzonych służy polecenie git rm, które przy okazji usuwa też plik z katalogu roboczego, zatem nie pojawia się on później na listach plików nieśledzonych samo "manualne" usunięcie pliku z katalogu roboczego sprawi, że w wyniku wywołania polecenia git status otrzymamy informację "Changes not staged for commit:" z informacją "deleted" przed nazwą pliku i wskazówką, by użyć polecenia git rm w razie, gdyby plik został przed próbą usunięcia go zmodyfikowany i umieszczony w przechowalni, jego usunięcie musi zostać wymuszone za pomocą opcji -f jest to zabezpieczenie przed przypadkowym usunięciem nieutrwalonych w migawce danych dalej: istnieje przydatna operacja zachowania pliku w katalogu roboczym lecz usunięcia go z obszaru przechowywania plik będzie wówczas wciąż zapisany na dysku, ale git nie będze go dłużej śledził zdarzyć może się to np. wówczas, gdy nie dodaliśmy jakichś plików do .gitignore, a przez przypadek umieściliśmy je w przechowalni - wystarczy posłużyć się opcją --cached git rm --cached CZYTAJ.MNIE ponadto, do polecenia git rm przekazywać można nie tylko nazwy plików, bo także całych katalogów a nawet wzorce nazw, np.: git rm log/\*.log czy git rm \*~ do zmiany nazwy pliku w gicie służy polecenie git mv plik_źródło plik_cel po takiej operacji git status poprawnie wykrywa zmianę nazwy pliku - "Changes to be comitted:" i "renamed:" okazuje się jednak, że wykonana operacja zmiany nazwy pliku równoważna jest z trzema poniższymi działaniami mv CZYTAJ.TO.md CZYTAJ.TO git rm CZYTAJ.TO.md git add CZYTAJ.TO ale prościej używać jednego polecenia zamiast trzech najprostszą i zarazem najbardziej użyteczną metodą przeglądania wprowadzonych w repo zmian jest polecenie git log załóżmy, że repo ma już przynajmniej kilka commitów (albo zostało sklonowane ze zdalnego serwera i ma swą historię) jeżeli polecenie git log zostanie uruchomione bez parametrów, wypisze commity wprowadzone do repo, podając je w odwróconej kolejności chronologicznej (od najnowszych - na górze - do najstarszych - na dole) każdy commit opisany jest sumą kontrolną SHA-1, tożsamością (imię, nazwisko, e-mail) autora, datą utworzenia oraz komunikatem polecenie git log umożliwia stosowanie wielu różnych opcji git log -p wyświetla różnice wprowadzone w danym commicie, a w przypadku dodania jeszcze parametru np. -2, będą to dwie najnowsze pozycje z listy więc git log -p -2 wyświetli, oprócz historii commitów, wyniki działania polecenia diff dla każdego z listowanych commitów, co jest przydatne przy code review jest też opcja --stat która wyświetli pod danymi każdego commitu listę zmodyfikowanych plików oraz informację: ile plików zmieniono i ile dodano/usunięto w tych plikach wierszy kolejną przydatną opcją jest --pretty która zmienia sposób wypisywania informacji i stosuje inny sposób formatowania, można podać jej kilka wartości wbudowanych już w system git log --pretty=oneline poda dane każdego commitu skrócone do wiersza (oprócz tego są opcje: short, full, fuller) najbardziej interesująca jest opcja format, bo pozwala zdefiniować własny format wypisywania informacji - szczególnie przydatne, gdy przygotowujemy wydruk na potrzeby maszynowego parsowania (ponieważ format definiujemy jawnie, mamy pewność, że nie zmieni się w przyszłych wersjach gita) opcje online i format są szczególnie przydatne w połączeniu z jeszcze jedną, inną opcją polecenia git log - --graph - która w wydruku tworzy graf zbudowany ze znaków ASCII pokazujący historię rozgałęziania i złączania w projekcie oprócz opcji formatujących wydruk, dla polecenia git log są też opcje limitujące, czyli takie, które umożliwiają wyświetlenie pewnego podzbioru commitów -n ograniczy (dla dowolnej liczby naturalnej) ilość wyświetlonych commitów do najnowszych n chociaż raczej nie korzysta się z tej opcji, bo git przesyła wydruki zazwyczaj do programów stronicujących je, a wtedy i tak widać na ekranie tylko pewien ich podzbiór bardzo przydatne są za to ograniczenia czasowe --since lub synonimicznie --after (od podanej daty) oraz --until lub --before (do podanej daty, przed nią) możliwe jest też filtrowanie listy commitów tak, aby pasowały do określoncyh kryteriów --author wybierze commity tylko określonego autora --grep pozwala poszukiwać podanych słów w komunikatach zatwierdzających (w razie użycia obydwu powyższych opcji jednocześnie, należy wywołać polecenie z dodatkowym parametrem --all-match, bo bez niego uzyskasz listę pasującą do dowolnego z kryteriów) -S"" wyświetla tylko te commity, w których dodano/usunięto kod pasujący do podanego ciągu znaków można też w poleceniu podać nazwę katalogu/pliku, a lista wypisywanych commitów zostanie ograniczona do tych, w których zmieniano wskazane pliki - opcję tą podaje się jako ostatnią i należy poprzedzić ją podwójnym minusem (--), aby oddzielić od pozostałych opcji podczas cofania zmian zachowaj szczególną ostrożność, ponieważ możesz bezpowrotnie utracić część swojej pracy jednym z najczęstszych powodów cofania zmian jest sytuacja, w której - już po zatwierdzeniu commitu - zauważasz, że zabrakło w nim kilku ważnych plików/w komunikacie znajdują się błędy aby jeszcze raz zatwierdzić ten commit, wywołaj polecenie git commit --amend (z ang. amend - popraw) tak wydane polecenie umieszcza w commicie zawartość obszaru przechowywania, a jeżeli od poprzedniego commitu nie było żadnych nowych zmian (np. wywołujesz polecenie natychmiast po zatwierdzeniu poprzedniego commitu) to migawka nie ulegnie zmianie, a Ty zyskasz możliwość poprawienia komunikatu zatwierdzania pojawi się edytor pozwalający wprowadzić komunikat zatwierdzania - z treścią poprzedniego komunikatu, którą można edytować przykładowo, po zatwierdzeniu commitu zorientujesz się, że w obszarze przechowywania nie było jednego ważnego pliku, wówczas: git commit -m "pierwotny commit" git add zapomniany_plik git commit --amend w efekcie, w repozytorium powstanie jeden commit - drugie polecenie git commit zastąpi wyniki pierwszego miłą cechą poleceń umożliwiających wycofywanie zmian istniejących w obszarze przechowywania/w katalogu roboczym jest podobieństwo do poleceń sprawdzających stan obu tych obszarów załóżmy, że zmiany z dwóch plików chcesz mieścić w repo w dwóch niezależnych commitach, ale oba zmienione pliki zostały już wcześniej umieszczone w obszarze przechowywania - jak wycofać jeden z tych plików z obszaru przechowywania? git add * git status - drukuje wskazówkę: "use "git reset HEAD " to unstage" pamiętaj, że polecenie git reset może być niebezpieczne, jeśli zostanie połączone z opcją --hard, ale w tym przypadku system nie dotyka pliku znajdującego się w katalogu roboczym - git reset wywołane bez opcji --hard nie wiąże się z żadnym ryzykiem a co, gdy chcę wycofać modyfikacje wprowadzone do pliku? przywracając plik do stanu, w jakim był przy tworzeniu ostatniego commitu git checkout -- (czyli polecenie, które pojawia się po wywołaniu git status) zapamiętaj, że polecenie git checkout -- jest naprawdę niebezpieczne, bo wszystkie wprowadzone zmiany zostają usunięte jeśli zmiany z tego pliku są nadal potrzebne, ale w tej chwili przeszkadzają w dalszej pracy, warto skorzystać z rozgałęzień lub schowka praca ze zdalnymi repozytoriami - zdalne repozytoria to wersje projektu przechowywane na serwerach w internecie albo w sieci lokalnej takich repozytoriów może być kilka, a do każdego z nich możesz mieć różne uprawnienia (tylko odczyt, albo i odczyt i zapis) współpraca z innymi osobami wymaga umiejętnego zarządzania tymi repozytoriami - pobierania i przesyłania danych umożliwiających wspólną pracę polecenie git remote wyświetla skrócone nazwy wszystkich zdalnych repozytoriów znanych już w systemie - klonujesz repo, przechodzisz do folderu z nim i wywołujesz git remote zauważ: w jednym repozytorium może być zdefiniowanych kilka zdalnych repozytoriów przeznaczonych do pracy z różnymi osobami git remote -v wyświetla dodatkowo adresy url (dwa - fetch/push czyli odczyt/zapis) aby dodać nowe repozytorium gita i nadać mu skróconą nazwę, można posłużyć się poleceniem git remote add od teraz w wierszu poleceń można posługiwać się ciągiem znaków zamiast pełnym url tego repo czyli np git fetch - pobierze z podanego repo wszystkie dane, których nie ma jeszcze w lokalnym repo w szczególności: git fetch origin pobiera wszystkie zmiany, jakie zostały przesłane na serwer źródłowy od czasu sklonowania repozytorium (albo od czasu ostatniego pobierania zmian) pamiętaj jednak, że polecenie git fetch nie wykonuje automatycznego złączenia pobranych danych z prowadzonymi przez nas pracami - takie złączenie należy wykonać samodzielnie w odpowiednim dla siebie momencie jeżeli jedna z gałęzi zostanie skonfigurowana tak, żeby śledzić gałąź zdalną, za pomocą polecenia git pull możesz automatycznie pobrać zmiany ze zdalnej gałęzi i złączyć je ze swoją gałęzią lokalną często jest to prostsza i wygodniejsza metoda pracy z tego powodu polecenie git clone automatycznie włącza dla gałęzi master opcję śledzenia zdalnej gałęzi master (bądź nazwanej inaczej, np. main) wywołanie polecenia git pull pobiera dane z serwera a następnie próbuje automatycznie złączyć te zmiany z kodem, nad którym aktualnie pracujesz gdy projekt znajduje się już na etapie, w którym można się nim podzielić z innymi, możesz wypchnąć swoje zmiany do zdalnego repozytorium składnia jest prosta: git push [nazwa-serwera] [nazwa-gałęzi] np. gałąź main do serwera o nazwie origin (klonowanie automatycznie przypisuje serwerowi tą nazwę) polecenie zadziała tylko w przypadku, gdy repo zostało sklonowane z serwera, na którym masz uprawnienia do zapisu i nikt inny w międzyczasie nie wypchnął do niego własnych zmian czyli najpierw należy pobrać zmiany przesłane przez innych i wprowadzić je do swojego repozytorium, a dopiero potem możesz przystąpić do wypychania własnych zmian - w przeciwnym razie operacja push zostanie przez serwer odrzucona polecenie git remote show [nazwa-serwera] pozwala zobaczyć dodatkowe informacje na temat zdalnego serwera polecenie to wypisuje np. adresy url i informacje o śledzeniu poszczególnych gałęzi zdalne serwery można usuwać (git remote rm [nazwa-serwera]) oraz można zmieniać ich nazwy (git remote rename [stara-nazwa] [nowa-nazwa]) w gicie istnieje również możliwość przypisywania tagów określonym elementom historii projektu zwykle możliwość tą stosujemy do oznaczania wydań tworzonego produktu - wersjonowanie (v1.0 itd) aby wypisać listę istniejących tagów wystarczy użyć polecenia git tag - polecenie wypisze wszystkie tagi w kolejności alfabetycznej są dwa rodzaje tagów: lekkie oraz opisane tag lekki przypomina gałąź, która nigdy się nie zmienia, co oznacza, że jest tylko wskaźnikiem do wybranego commitu tag opisany natomiast jest całkowicie niezależnym obiektem przechowywanym w bazie danych gita - ma sumę kontrolną i zawiera informacje o: twórcy tagu, dacie jego utworzenia, jak również komunikat zwykle zaleca się stosowanie tagów opisanych ze względu na te dodatkowe informacje tworzenie tagów opisanych jest wręcz banalne: git tag -a v1.4 -m "moja wersja 1.4" - parametr m pozwala wprowadzić komunikat do tworzonego właśnie tagu (bez zrealizowania tej opcji, git uruchomi edytor, oczekując że wpiszesz komunikat) za pomocą polecenia git show (np. git show v1.4) można wyświetlić dane tagu razem z informacjami o commicie, do którego ten tag został przypisany tagi można tworzyć również w późniejszym momencie - czyli dla starszych commitów, gdy np. zapomnimy otagować commit na bieżąco aby utworzyć tag dla wybranego commitu, należy podać jego sumę kontrolną (bądź jej część) na samym końcu wprowadzanego polecenia np.: git tag -a v1.2 9fceb02 domyślnie polecenie git push nie przesyła tagów na zdalne serwery - należy wypchnąć je samodzielnie git push origin [nazwa-tagu] bądź git push origin --tags w przypadku gdy chcesz opublikować wiele tagów (które nie istnieją jeszcze na zdalnym serwerze) jednocześnie o aliasach zaledwie wspomnienie: jeśli nie chcesz zawsze wpisywać pełnego tekstu każdego polecenia gita, możesz łatwo zdefiniować alias, wystarczy: git config --global alias.co checkout przydatny alias to np.: git config --global alias.unstage 'reset HEAD --' - rozwiąże problem z dziwnym poleceniem używanym do wycofywania plików z obszaru przechowywania wówczas obydwa następujące polecenia będą miały identyczne działanie: git unstage plikA oraz git reset HEAD plikA często spotykanym aliasem jest też pseudopolecenie last: git config --global alias.last 'log -1 HEAD' - wówczas informacja o ostatnim commicie dostępna jest bardzo szybko: git last ROZGAŁĘZIENIA rozgałęzienie oznacza, że odchodzimy od głównej ścieżki rozwoju i pracujemy bez wpływania na nią tworzenie nowych rozgałęzień w gicie jest proste, a wszystkie operacje na rozgałęzieniach są niemal natychmiastowe równie szybkie jest przełączanie pomiędzy gałęziami git wręcz zachęca do stosowania metody pracy, w której tworzymy i złączamy różne gałęzie, nawet kilka razy dziennie nauczenie się pracy z tą funkcją gita daje do rąk niezwykle wszechstronne narzędzie, które może całkowicie zmienić sposób codziennej pracy