okrojone streszczenie książki Learning Git Anna Skoulikari (2023) książka ta jest zaledwie prostym wstępem oswajającym gita polecenia w linii komend mogą mieć opcje z argumentami opcje to ustawienia zmieniające zachowanie komendy (poprzedzone są pojedynczym lub podwójnym myślnikiem) argumenty natomiast przekazują komendzie jakieś wartości np.: git commit -m "" git version repozytorium - repo - to inaczej kopia projektu kontrolowana przez gita może być lokalne i zdalne program git bash - na windowsie - do obsługi gita git init git init -b -- nie tylko inicjalizuje repo ale także ustala nazwę początkowej gałęzi cztery istotne obszary gita: working directory (katalog roboczy) - the staging area (index, przechowalnia) - the commit history (historia wersji) - the local repository (repo .git) git status - drukuje stan katalogu roboczego i przechowalni git add git add ... git add -A - dodaje wszystkie pliki do indeksu (nowe, zmodyfikowane, usunięte) git commit -m "" - do zapisania wersji plików, zmian uznanych za istotne git log - wyświetla listę, historię commitów w odwroconym porządku chronologicznym (najnowsze na górze) (hash, tożsamość - imię/mail, data/czas, wiadomość) gałęzie pomagają w pracy zespołowej będąc różnymi liniami rozwoju są de facto ruchomymi wskaźnikami na commity, można zobaczyć informacje o nich po wykonaniu polecenia git log git branch - listuje (lokalne) gałęzie git branch - tworzy gałąź o podanej nazwie zawsze znajdujesz się w jakimś konkretnym commicie - HEAD wskazuje na ten commit do zmiany gałęzi służą polecenia: git switch - działa tylko powyżej wersji 2.23 git checkout złączać, scalać gałęzie można za pomocą poleceń merge (fast-forward merges i three-way merges) oraz rebase chodzi o integrowanie zmian wprowadzonych w jednej gałęzi ze zmianami wprowadzonymi na innej gałęzi gałąź źródłowa (source) -> gałąź docelowa (target) sposób w jaki dokonane zostanie scalenie gałęzi zależy od tego czy historie rozwoju rozeszły/rozbiegły się fast-forward merge jest banalny i polega na przeniesieniu wskaźnika - bo z jednej gałęzi, idąc po historii commitów, można osiągnąć drugą - i nie ma żadnych dodatkowych merge commitów czyli jestem na mainie za którym jest np. feature i wpisuję git merge feature three-way merge tworzy dodatkowy tzw. merge commit który zintegruje dwie rozbieżne historie rozwoju git log --all - wyświetla historię commitów dla wszystkich gałęzi z lokalnego repo, nie tylko od head git checkout - HEAD przeskakuje na konkretny commit + wypełnia przechowalnię i katalog roboczy odpowiednimi plikami ze skompresowanej bazy danych git switch -c lub git checkout -b - tworzy nową gałąź i za jednym poleceniem przełącza na nią zacząć pracę z repo można lokalnie (git init) lub klonując (kopiując) repo z internetu (git clone) do wysyłania danych z lokalnego repo na zdalne służy komenda git push interakcje pomiędzy repozytoriami nie wykonują się automatycznie - nie istnieją żywe połączenia, wszystko jest rezultatem wyraźnie wykonanych poleceń warto korzystać ze zdalnego repo - backup oraz praca z różnych komputerów nad projektem (więc także współpraca różnych osób) najpierw tworzysz zdalne repo na stronie githuba, następnie dodajesz połączenie pomiędzy lokalnym i zdalnym repo, po czym wysyłasz dane więc na początek zdalne repo jest puste git remote add - ustanawia połączenie pomiędzy lokalnym a zdalnym repo nadając mu nazwę shortname (nie jest to jeszcze wrzucenie danych na serwer) (można ustalić wiele zdalnych repozytoriów, choć nie jest to zbyt powszechne) po ustanowieniu połączenia można łączyć się ze zdalnym repo poprzez nazwę, nie poprzez url zauważ: gdy klonujesz repo ze zdalnych źródeł, git automatycznie dodaje połączenie lokalne-zdalne o domyślnej nazwie origin (ta nazwa to tylko konwencja) git remote - listuje połączenia pomiędzy lokalnym a zdalnymi repo wyświetlając nazwy git remote -v - od "verbose" - listuje pary nazwa-URL połączenie pomiędzy repo lokalnym a zdalnym jest "jednokierunkowe" gdy pushujesz lokalną gałąź do repo zdalnego, tworzysz zdalną gałąź - zdalna gałąź to gałąź w zdalnym repo te zdalne gałęzie nie aktualizują się samoistnie każda zdalna gałąź, o której wie lokalne repo, ma także wskaźnik na siebie w tymże lokalnym repo (remote-tracking branch) jest to referencja w lokalnym repozytorium na commit na który zdalna gałąź wskazywała ostatnim razem gdy nastąpiła komunikacja pomiędzy repozytoriami kiedy przesyłasz pracę z gałęzi lokalnej do zdalnej, git musi wiedzieć, do której gałęzi zdalnej chcesz przesłać dane jeśli gałąź lokalna ma zdefiniowaną "upstream branch" (gałąź nadrzędną?) możesz użyć polecenia git push bez argumentów a więc możesz skonfigurować relację śledzenia pomiędzy gałęzią lokalną a zdalną - jest to własnie "upstream branch" po wywołaniu push za pierwszym razem, zdalna gałąź tworzona jest w zdalnym repo i w lokalnym repo tworzony jest wskaźnik remote-tracking branch git branch --all - listuje wszystkie i lokalne i remote-tracking branches zauważ, że gdy masz np. dwie gałęzie wskazujące na ten sam commit, to tylko jedna (main a nie feature) jest pushowana wystarczy więc wykonać: git switch feature i potem git push origin feature aby móc kontrybuować w projekcie, muszę przyznać współpracownikowi, który najpierw musi założyć konto w githubie, dostęp do repo - uprawnienia git clone - klonuje zdalne repozytorium polecenie to tworzy katalog, inicjalizuje lokalne repo, pobiera dane z repo zdalnego i na koniec ustanawia połączenie z repo zdalnym (domyślnie o nazwie origin) git musi wiedzieć na jakiej gałęzi być klonując repozytorium, co definiuje wskaźnik origin/HEAD który wskazuje na gałąź origin/main (dlatego po sklonowaniu repo współpracownik będzie na gałęzi main) ponadto, choć po sklonowaniu repo będzie wiele remote-tracking branches - dla wszystkich gałęzi obecnych w zdalnym repo - tylko jedna lokalna gałąź jest tworzona (ta wskazywana przez origin/HEAD) ale spokojnie, można łatwo przejść na dowolną z istniejących-"nieistniejących" gałęzi, wystarczy wpisać polecenie git switch tworzona jest wówczas nowa gałąź lokalna odpowiadająca wskazującej przez zdalną i na nią git przeskakuje w gicie można ponadto usuwać gałęzie, celem utrzymania projektu jako zorganizowanego jednak przed usunięciem gałęzi, należy upewnić się, czy została scalona z inną, czy faktycznie nie będę więcej potrzebował pracy wykonanej na tej gałęzi uwaga: commity dalej istnieją w historii, usuwasz tylko gałąź będącą wskaźnikiem, więc tracisz łatwy dostęp do commitów git branch -d - usuwa gałąź lokalną (nie można być na gałęzi usuwanej) git push -d - usuwa gałąź zdalną wraz z połączoną z nią remote-tracking branch oczywiście fakt że jedna osoba usunie gałąź zdalną nie znaczy, że w innych repozytoriach zostanie wykonana taka operacja usuwania odpowiadających gałęzi remote-tracking różne zespoły mają różne konwencje pracy, nazewnictwa itp - np. każdy powinien pracować tylko na jego własnej gałęzi aby unikać zamętu (merge conflits) aktualizacja jednego repo lokalnego zmianami wykonanymi w drugim to proces dwukrokowy: push i potem fetch jak już wcześniej pisałem, git musi wiedzieć, gdy wykonujesz push z gałęzi lokalnej na zdalną, na jaką gałąź zdalną pushujesz gdy upstream branch nie jest zdefiniowany, trzeba wyraźnie podać w poleceniu git push gałąź zdalną podczas klonowania repo, upstream branch jest ustawiany automatycznie aby zobaczyć czy upstream branches są zdefiniowane wystarczy wywołać git branch -vv ("very verbose") polecenie to informuje także o tym, czy lokalna gałąź jest przed czy za upstream branch, o ile takowa jest zdefiniowana są dwie główne korzyści płynące ze zdefiniowania upstream branches: możesz sprawdzać czy repo jest przed/za zdalnym repo używając zarówno komendy git branch -vv lub git status upraszczasz pracę (git push bez argumentów) wprowadzanie zmian z gałęzi zdalnej na lokalną jest dwuetapowe: fetch i potem integracja git fetch pobiera commity i aktualizuje wszystkie remote-tracking branches w lokalnym repo aby odzwierciedlić stan zdalnych gałęzi w zdalnym repo git fetch - bez podania domyślnie wywołuje się z origin komenda ta wpływa tylko na remote-tracking branches, a na lokalne nie, czyli nie dokonuje się żadna integracja danych git fetch -p ("prune" czyli okroić) - usuwa remote-tracking branches które wskazują na usunięte zdalne gałęzie i pobiera dane ze zdalnego repo three-way merges tworzą merge commit i mogą prowadzić do konfliktu, który pojawia się, gdy na dwóch różnych gałęziach dokonano zmian w tych samych częściach tych samych plików lub gdy na jednej gałęzi plik usunięto a na drugiej go zedytowano więc merge commit ma więcej niż jednego rodzica (niektórzy nie lubią three-way merges twierdząc że historia wygląda na skomplikowaną i sugerują używanie rebase) oczywiście definiując upstream branch w lokalnym repo, także inne komendy, jak git pull, można wykonywać bez argumentów aby ustawić upstream branch: komenda git branch -u / (-u to skrót od --set-upstream-to) czyli: git branch -vv -> git branch -u origin/main -> git branch -vv edycja pliku -> umieszczenie go w staging area -> kolejna zmiana -> git oznacza tą zmianę jako nową i trzeba ponownie dodać ten plik do przechowalni gdy chcesz wykonać git push do zdalnego repo ale repozytorium zdalne z lokalnym nie są zsynchronizowane, pit push zwróci error historie rozwoju lokalnej i zdalnej gałęzi main rozbiegły się i git nie może tego samoczynnie rozwiązać - są zmiany, commity (jakiś kolega je spushował w międzyczasie) na zdalnej gałęzi main których ty nie sfetchowałeś zamknięcie vima: esc -> :wq (write & quit) komunikat-zwrotka z gita po zescaleniu: "Merge made by the 'ort' strategy." - oznacza three-way merge pamiętaj o git log --all żeby wyświetlić, po sfetchowaniu aktualnych danych, wszystkie commity, w tym te rozbieżne, a nie tylko od HEAD jak dotąd aktualizacja lokalnego repo danymi ze zdalnego była dwuetapowa: fetch -> merge natomiast git pull umożliwia wykonanie tych dwóch kroków za jednym zamachem czyli git pull (z jakiego repo pobieramy jaką gałąź) lub git pull o ile upstreambranch jest zdefiniowana dla obecnej, lokalnej gałęzi jednak: poleceniu git pull należy powiedzieć jak ma zintegrować dane: jeśli historie rozwoju nie rozbiegły się, wykonany zostanie domyślny merge fast-forward jeśli historie lokalnej i zdalnej gałęzi w komendzie git pull rozbiegają się, należy jawnie zadeklarować, czy chcemy merging czy rebasing (w przeciwnym razie: error) czyli git pull = git fetch + git merge OR git rebase wybieramy opcją --no-rebase lub --rebase zauważ: często git pull używany jest w przypadku fast-forward, a gdy historia rozwoju gałęzi lokalnych-zdalnych rozbiega się, użytkownicy gita wybierają fetch i osobne scalenie/rebase