Programowanie w językach skryptowych - Python i Linux Bash Maciej Wielgosz Wydział Informatyki, Elektroniki i Telekomunikacji 2015, semestr zimowy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 1 / 138
Część II Git M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 2 / 138
Git 1 Systemy kontroli wersji 2 Systemy scentralizowane a rozproszone 3 Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami 4 Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów 5 Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja 6 Organizacja pracy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 3 / 138
VCS System kontroli wersji (ang. Version Control System) Program służacy do śledzenia zmian w kodzie/dokumencie źródłowym oraz ułatwiajacy łaczenie modyfikacji pochodzacych z wielu źródeł. Obecnie VCS stały się standardem przy pracy nad różnego typu projektami informatycznymi, ale za VCS można uznać także np. śledzenie zmian w systemach typu Wiki czy pakietach biurowych. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 4 / 138
Dlaczego warto używać VCS? Do najważniejszych zalet VCS można zaliczyć: proste przegladanie i przywracanie poprzednich wersji plików, łatwość synchronizacji źródeł pomiędzy różnymi maszynami i członkami zespołu, możliwość rozwijania projektu w wielu kierunkach jednocześnie (np. naprawianie błędów z ostatniej wersji przy równoczesnej pracy nad nowa funkcjonalnościa), opcje integracji z automatycznymi narzędziami do np. testowania czy deploymentu. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 5 / 138
Popularne systemy W chwili obecnej najczęściej można spotkać się z następujacymi systemami: Apache Subversion (SVN) stworzony w roku 2000 jako (w większości kompatybilny) następca Concurrent Version System (CVS), Mercurial (Hg) pojawił się w roku 2005; jego zamierzonym pierwotnym zastosowaniem była praca nad rozwojem jadra Linuksa, jednak w tym celu ostatecznie wybrano Git, Git stworzony kilka dni przed Mercurialem i w tym samym celu; obecnie prawdopodobnie najpopularniejszy system kontroli wersji. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 6 / 138
Git 1 Systemy kontroli wersji 2 Systemy scentralizowane a rozproszone 3 Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami 4 Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów 5 Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja 6 Organizacja pracy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 7 / 138
Systemy lokalne Proste bazy danych, która przechowuja wszystkie zmiany w plikach jako kolejne wersje, jednym z pierwszych systemów tego typu był RCS (Revision Control System), systemy te działaja na zasadzie przechowywania różnic pomiędzy plikami tzw. patchy, można odtworzyć jak plik wygladał w dowolnym momencie czasu poprzez zsumowanie wszystkich patchy. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 8 / 138
Systemy scentralizowane Systemy scentralizowane powstały z potrzeby współdzielenia kodu pomiędzy różnymi developerami i maszynami, oparte sa na idei głównego serwera przechowujacego cała historię i dowolnej ilości klientów, którzy kopiuja z centralnego serwera pliki, jednym z najpopularniejszych przykładów takich systemów jest Apache Subversion (SVN), przez wiele lat systemy scentralizowane były standardem w obszarze kontroli wersji. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 9 / 138
Zalety i wady systemów scentralizowanych Zalety (w stosunku do systemów lokalnych): każdy do pewnego stopnia orientuje się, co robia inni członkowie zespołu, szczegółowa kontrola uprawnień użytkowników, łatwiejsze zarzadzanie (łatwiej zarzadzać jednym repozytorium niż wieloma lokalnymi). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 10 / 138
Zalety i wady systemów scentralizowanych Wady: niedostępność centralnego repozytorium powoduje paraliż pracy całego zespołu, ze względu na brak komunikacji z baza danych, awaria centralnego serwera powoduje utratę całej historii pracy (chyba że były tworzone kopie zapasowe). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 11 / 138
Systemy rozproszone Zasada działania Systemy rozproszone przechowuja lokalnie cała historię zmian, co pozwala użytkownikowi na pracę niezależnie od dostępności innych węzłów. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 12 / 138
Zalety systemów rozproszonych Zalety: każda kopia repozytorium służy jednocześnie jako kompletne repozytorium, istnieje możliwość używania kilku zdalnych ( centralnych ) serwerów, taka architektura umożliwia stosowanie wielu modeli organizacji pracy, obecnie najpopularniejszym przykładem systemu rozproszonego jest git. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 13 / 138
Podsumowanie Systemy scentralizowane sa tworzone z założeniem, że istnieje jedno właściwe (absolutne) źródło. Systemy rozproszone: zostały stworzone z założeniem, że każde repozytorium jest tak samo dobre jak inne, dzielenie i scalanie repozytoriów jest po prostu forma komunikacji, decyzja o znaczeniu danego repozytorium jest podejmowania indywidualnie i nie jest kontrolowana przez oprogramowanie. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 14 / 138
Git 1 Systemy kontroli wersji 2 Systemy scentralizowane a rozproszone 3 Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami 4 Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów 5 Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja 6 Organizacja pracy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 15 / 138
Git jako system lokalny Główna zaleta systemów rozproszonych jest ich autonomiczność: aby z nich korzystać, nie jest potrzebny żaden serwer, w podstawowej wersji wszystko może odbywać się tak, jak przy stosowaniu najprostszego lokalnego systemu. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 16 / 138
Git CLI Program git działa na zasadzie komend (podprogramów), z których niemal każda ma odrębny zestaw argumentów. Listę wspólnych opcji oraz najczęściej używanych komend można zobaczyć wpisujac: $ git --help Szczegółowe opcje poszczególnych komend można zobaczyć używajac: $ git <command> --help M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 17 / 138
Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 18 / 138
Nowe repozytorium Założenie nowego, lokalnego repozytorium w wybranym katalogu (moga wcześniej istnieć w nim jakieś pliki; w przykładach używany będzie katalog acai): $ cd acai $ git init Initialized empty Git repository in /[...]/acai/.git/ M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 19 / 138
Dodanie istniejacych plików Stworzone w ten sposób repozytorium nie śledzi jeszcze żadnych zmian w plikach. Aby rozpoczać kontrolowanie wersji dla już istniejacych w katalogu plików należy wydać dwa polecenia. Pierwsze z nich to: $ git add. Powoduje ono dodanie do kontroli wersji wszystkich plików z bieżacego (.) katalogu. Co dokładnie zostało dodane można sprawdzić wydajac polecenie git status. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 20 / 138
Dodanie istniejacych plików $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: new file: new file:....gitignore LICENSE.txt README.md M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 21 / 138
Pierwszy commit Druga komenda instruuje gita, aby zapamiętał ten punkt w historii. W wersji podstawowej wyglada ono tak: $ git commit Po wykonaniu polecenia otwierany jest domyślnie skonfigurowany edytor tekstowy w którym należy podać opis właśnie tworzonego punktu. Standardowo opis ten musi zostać dodany w przeciwnym razie tworzenie punktu zostanie anulowane. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 22 / 138
Pierwszy commit Często opis (wiadomość, ang. message) podaje się bezpośrednio z linii poleceń: $ git commit -m "Project skeleton" [master (root-commit) 6048090] Project skeleton 19 files changed, 718 insertions(+) create mode 100644.gitignore create mode 100644 LICENSE.txt create mode 100644 README.md... M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 23 / 138
Pełna inicjalizacja Podsumowujac, rozpoczęcie lokalnej pracy z gitem najczęściej przebiega następujaco: $ cd <project_dir> $ git init... $ git add. $ git commit -m "Initial commit"... M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 24 / 138
Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 25 / 138
Możliwe stany plików Pliki w gicie moga znajdować się w jednym z 2 stanów: nieśledzone (ang. untracked) pliki, których stanu git nie przechowuje śledzone (ang. tracked) takie, o których git wie Aby plik był śledzony, należy go dodać do gita, np. używajac polecenia git add. Usunięcie pliku z listy śledzonych (i z dysku!) po stworzeniu commita odbywa się za pomoca git rm. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 26 / 138
Śledzenie zmian Śledzone pliki moga być: niezmodyfikowane (ang. unmodified) takie, które nie zmieniły się od czasu ostatniego zapisu stanu zmodyfikowane (ang. modified) takie, w których sa wprowadzone jakieś zmiany M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 27 / 138
Śledzenie zmian Każdy zmodyfikowany plik zawiera jedna lub więcej zmian. Warto pamiętać, że git ma możliwość zapisu stanu każdej zmiany z osobna. Każda zmiana może być zatwierdzona (w nomenklaturze gita staged) lub nie. Zwykle jednak nie rozpatruje się każdej zmiany pojedynczo, tylko zatwierdza wszystkie w danym pliku. To, na jakim etapie cyklu życia jest dana zmiana można podejrzeć używajac komendy git status. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 28 / 138
Status pliku $ git status On branch master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: modified: LICENSE.txt README.md no changes added to commit (use "git add" and/or "git commit -a") M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 29 / 138
Zatwierdzenie zmian Zatwierdzenie (wszystkich) zmian w danych plikach odbywa się przy użyciu polecenia git add: $ git add LICENSE.txt README.md $ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: modified: LICENSE.txt README.md M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 30 / 138
Zatwierdzenie zmian Do zatwierdzenie wszystkich zmian we wszystkich zmodyfikowanych plikach, a także dodania do kontroli wersji nowych (i usunięcia z niej już nieistniejacych), przydatna jest opcja -A: $ git add -A Oznacza ona w skrócie zatwierdź wszystko. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 31 / 138
Wycofanie zmian Jeśli któraś z zatwierdzonych zmian jednak nie powinna zostać zapisana, można użyć git reset, aby ja wycofać: $ git reset README.md Unstaged changes after reset: M README.md Polecenie to (w tej formie) nie powoduje żadnych zmian w pliku informuje tylko gita, że dana zmiana (zmiany) maja jeszcze nie być zapisywane. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 32 / 138
Podejrzenie zmian Do podgladania, co zostało zmienione od ostatniego zapisu stanu (ogólnie lub w danym pliku) służy polecenie git diff: $ git diff README.md Otworzy ono edytor, w którym zaznaczone będa miejsca wystapienia zmian. W najprostszym przypadku lista różnic będzie miała postać pliku tekstowego, zawierajacego informacje o tym, które linie i w jakich plikach zostały zmienione. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 33 / 138
git diff 1 diff --git a/readme.md b/readme.md 2 index e69de29..1edb8e1 100644 3 --- a/readme.md 4 +++ b/readme.md 5 @@ -0,0 +1,3 @@ 6 +ACAI - ACcelerated AI 7 + 8 +Suite of Artificial Intelligence algorithms implemented with future hardware acceleration (via OpenCL) in mind. git diff README.md M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 34 / 138
Podwójny status pliku Czasami może zdarzyć się, że plik znajduje się zarówno na liście zmian zatwierdzonych do zapisu (staged), jak i na liście zmian jeszcze nie zatwierdzonych (unstaged). Wynika to ze wspomnianego wcześniej śledzenia pojedynczych zmian jeśli zatwierdzony był cały plik, to tak naprawdę zatwierdzone były wszystkie zmiany znajdujace się w nim w danym momencie. Jeśli uległ on dalszej modyfikacji (nawet nadpisujacej zatwierdzone zmiany), to nowe modyfikacje również trzeba zatwierdzić, by mogły być zapisane. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 35 / 138
Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 36 / 138
Komenda commit Zatwierdzone zmiany zapamiętuje się używajac polecenia git commit. Tworzy ono opisany punkt na osi czasu, do którego można powracać. Każdy commit identyfikowany jest przez unikalny hash, automatycznie generowany na podstawie danych takich jak bieżacy czas, autor commita czy wprowadzony opis. Hash ten pozwala stwierdzić, czy dwa commity posiadajace ten sam opis faktycznie sa takie same. Wiele poleceń gita przyjmuje hash jako jeden ze swoich argumentów. Cały identyfikator jest jednak kłopotliwy w użyciu (SHA1 generuje ciagi o długości 40 znaków), więc często stosuje się tylko 7 pierwszych jego znaków. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 37 / 138
Always commit, you must Stworzony commit zabezpiecza przed utrata wyników pracy. Często okazuje się, że poprzednie rozwiazanie było tym właściwym... Jeżeli zapisany został tylko stan po wszystkich poprawkach, nie ma jak podejrzeć i/lub wykorzystać w tym celu pierwotnego rozwiazania trzeba napisać je od nowa. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 38 / 138
Always commit, you must Jeżeli natomiast stan był zapisywany po każdym etapie pracy, to z łatwościa można przywrócić plik do poprzedniego stanu czy to w celu zastapienia obecnej wersji, czy tylko podejrzenia i ekstrakcji potrzebnych fragmentów. Miedzy innymi z tego powodu warto jest wyrobić sobie nawyk tworzenia częstych i dobrze opisanych commitów. Przyda się to także w późniejszej, zespołowej pracy z gitem a czasami może okazać się jedyna deska ratunku w przypadku wystapienia jakichś problemów. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 39 / 138
Podstawowe użycie $ git commit Uruchomienie powyższej komendy otworzy domyślny edytor (vim), w którym należy wprowadzić opis. Standardowo plik ten zawiera komentarz, dostarczajacy dodatkowych informacji o tworzonym właśnie commicie. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 40 / 138
Podstawowe użycie 1 2 # Please enter the commit message for your changes. Lines starting 3 # with # will be ignored, and an empty message aborts the commit. 4 # On branch master 5 # Changes to be committed: 6 # modified: LICENSE.txt 7 # 8 # Changes not staged for commit: 9 # modified: README.md 10 # Domyślna zawartość pliku z opisem M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 41 / 138
Podstawowe użycie Domyślnie, jeśli nie wpiszemy treści opisu, commit zostanie anulowany: Aborting commit due to empty commit message. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 42 / 138
Opis z linii poleceń Często używa się parametru -m, aby wprowadzić opis bezpośrednio z linii poleceń: $ git commit -m "Change license to MIT" [master 3278ed2] Change license to MIT 1 file changed, 21 insertions(+), 1 deletion(-) rewrite LICENSE.txt (100%) M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 43 / 138
Zatwierdzenie wszystkich zmian przy zapisie Aby nie dodawać ręcznie zmian w każdym śledzonym już pliku, można użyć opcji -a: $ git commit -a -m "Add basic repo description" [master fc13f88] Add basic repo description 1 file changed, 3 insertions(+) Opcja ta dotyczy tylko już śledzonych plików. Jeżeli w repo zostały stworzone nowe, należy dodać je normalnie, używajac np. git add -A. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 44 / 138
Edycja commita Zdarza się, że przy tworzeniu commita nastapiła pomyłka, np. literówka w opisie czy pominięty plik. Z pomoca przychodzi wtedy opcja --amend, pozwalajaca na łatwa edycję ostatniego commita: $ git commit --amend -m "Add basic project description" [master bb3823f] Add basic project description Date: Wed Oct 14 13:45:38 2015 +0200 1 file changed, 3 insertions(+) M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 45 / 138
Edycja commita To, co tak naprawdę git robi, to usuwa ostatni commit i w jego miejsce tworzy nowy, zawierajacy wszystkie zmiany z tego usuniętego oraz nowo zatwierdzone. Można to zaobserwować porównujac ich identyfikatory. W wyniku edycji powstaje nowy commit. Nie ma to wielkiego znaczenia w przypadku lokalnego użycia gita, jest jednak ważne przy bardziej zaawansowanych zastosowaniach. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 46 / 138
Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 47 / 138
Ostatni commit Opis i zmiany zapisane w ostatnim commicie można zobaczyć korzystajac z polecenia git show. Analogicznie jak git diff otworzy ono edytor z plikiem zawierajacym listę zmian i dodatkowo informacjami o commicie: 1 commit bb3823f63f1254108238951a60b319fcc3a1b1a7 2 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 3 Date: Wed Oct 14 13:45:38 2015 +0200 4 5 Add basic project description 6 7 diff --git a/readme.md b/readme.md M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 48 / 138
Ostatni commit 8 index e69de29..8dd37ac 100644 9 --- a/readme.md 10 +++ b/readme.md 11 @@ -0,0 +1,3 @@ 12 +ACAI - ACcellerated AI 13 + 14 +Suite of Artificial Intelligence algorithms implemented with future hardware acceleration (via OpenCL) in mind. git show M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 49 / 138
Przeglad historii Skrócona historię commitów można przegladać przy użyciu polecenia git log. Będzie ona otworzona w domyślnym edytorze. 1 commit bb3823f63f1254108238951a60b319fcc3a1b1a7 2 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 3 Date: Wed Oct 14 13:45:38 2015 +0200 4 5 Add basic project description 6 7 commit 3278ed255627fa64ede6ab587e0d2c8c2711d203 8 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 9 Date: Wed Oct 14 13:23:57 2015 +0200 10 11 Change license to MIT M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 50 / 138
Przeglad historii 13 commit 6048090a0ce0997025957d5fd88224d9582aaa0a 14 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 15 Date: Mon Oct 12 22:28:43 2015 +0200 16 17 Project skeleton git log Pełna informację o zmianach można wyświetlić podajac argument w postaci hasha do polecenia git show, np. git show 3278ed2. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 51 / 138
Historyczne wersje pliku Aby zobaczyć, jak wygladał dany plik w konkretnym punkcie historii lub przywrócić go do tego stanu, można użyć komendy git checkout podajac hash interesujacego commita i ścieżkę do pliku. $ git checkout 6048090 LICENSE.txt Przywrócenie go do bieżacej wersji (z najnowszego commita) odbywa się analogicznie (HEAD odpowiada ostatniemu commitowi): $ git checkout HEAD LICENSE.txt M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 52 / 138
Historyczne wersje pliku Dostępne sa również pewne skróty, np. $ git checkout HEAD~2 LICENSE.txt cofa plik LICENSE.txt o 2 wersje. Należy zauważyć, że wynikiem polecenia git checkout nie jest tylko podglad dokonywane sa faktyczne zmiany w pliku, które w razie potrzeby można zatwierdzić i zapisać. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 53 / 138
Podglad historycznej wersji pliku Jeżeli pożadany jest tylko podglad, bez wprowadzania zmian do pliku, można skorzystać z wariantu polecenia git show: $ git show HEAD~2:./LICENSE.txt Jako separatora pomiędzy identyfikatorem wersji, a ścieżka do pliku używa się : (bez spacji!). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 54 / 138
Znaczace opisy Dobre opisy commitów znaczaco ułatwiaja prace z historia zmian. Moga pomóc znacznie zawęzić przeszukiwany przedział czasu w przypadku np. pojawienia się nowych błędów czy ułatwić znalezienie konkretnej wersji pliku. Czytelne opisy sa istotne zwłaszcza w przypadku pracy w grupie oraz korzystania z narzędzi automatycznie generujacych listę zmian (changelog) w projekcie. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 55 / 138
Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami Tworzenie Łaczenie Konflikty Usuwanie Rebase M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 56 / 138
Branch Branch Odgałęzienie projektu, zwykle wydzielone w celu realizacji konkretnej funkcjonalności. Wszystkie repozytoria git maja domyślny, główny branch o nazwie master. Zwykle stanowi on bazę, na podstawie której tworzy się inne branche. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 57 / 138
Istniejace branche Sprawdzenie, jakie branche istnieja w projekcie odbywa się za pomoca polecenia git branch. $ git branch * master W momencie stworzenia nowego repozytorium branch master nie jest widoczny na liście branchy pojawia się on tam dopiero po pierwszym commicie. Aktywny branch (czyli ten, do którego przynależa wersje plików znajdujace się obecnie na dysku) oznaczony jest *. W danej chwili aktywny może być tylko jeden branch. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 58 / 138
Tworzenie Jednym ze sposobów stworzenia nowego brancha jest: git branch <branch_name> Polecenie to tworzy nowy branch, ale go nie aktywuje. Aby zaczać pracę należy się na niego przełaczyć: git checkout <branch_name> Jest to standardowy sposób przełaczania się między branchami. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 59 / 138
Tworzenie Wygodniejszym sposobem jest stworzenie nowego brancha równocześnie z jego aktywacja, przy użyciu opcji -b: $ git checkout -b documentation Switched to a new branch documentation Nowo stworzony branch domyślnie poczatkowo znajduje się w tym samym punkcie, co obecnie aktywny. Można także podać, który branch ma stanowić bazę nowo tworzonego: $ git checkout -b docs master Switched to a new branch docs M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 60 / 138
Merge Po zakończeniu pracy nad dana funkcjonalnościa i jej przetestowaniu przychodzi czas na właczenie jej do głównego brancha. Jednym ze sposobów, by to zrobić, jest użycie polecenia git merge. Aby połaczyć branche za jego pomoca, należy najpierw przełaczyć się na docelowy branch (zwykle master ). $ git checkout master Switched to branch master $ git merge docs Updating 0903642..48e8690 Fast-forward README.md 5 +++++ 1 file changed, 5 insertions(+) M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 61 / 138
Merge M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 62 / 138
Konflikty Nie zawsze merge przebiega bez problemów. Jeśli dany plik został zmieniony zarówno w branchu, który chcemy dołaczyć, jak i w branchu docelowym, moga pojawić się konflikty, z którymi git nie poradzi sobie automatycznie. $ git checkout documentation Switched to branch documentation $ git merge docs Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 63 / 138
Konflikty W takim wypadku dostępne sa dwie opcje postępowania: 1 anulowanie operacji: $ git merge --abort 2 manualne rozwiazanie konfliktów i stworzenie commita łacz acego konfliktowe zmiany w pożadany sposób. Wykorzystywane w tym celu sa polecenia git add i git commit. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 64 / 138
Rozwiazywanie konfliktów Git dodaje do pliku charakterystyczne znaczniki w miejscach, w których nastapił konflikt: 1 ACAI - ACcellerated AI 2 ====================== 3 4 <<<<<<< HEAD 5 Lorem ipsum dolor sit amet, consectetur [...] 6 ======= 7 Suite of Artificial Intelligence algorithms [...] 12 >>>>>>> docs Plik README.md z konfliktami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 65 / 138
Rozwiazywanie konfliktów Przy wystapieniu konfliktu jako pierwsze wyświetlane sa zmiany, które były zapisane na aktywnym branchu. Następnie (po =======) wyświetlane sa zmiany, które pochodza z dołaczanego brancha. Rozwiazywanie konfliktów polega na wyszukania wszystkich wystapień takich alternatyw i zastapieniu ich (łacznie z markerami ograniczajacymi) pożadan a zawartościa. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 66 / 138
Rozwiazywanie konfliktów 1 ACAI - ACcellerated AI 2 ====================== 3 4 Suite of Artificial Intelligence algorithms [...] 5 6 Lorem ipsum dolor sit amet, consectetur [...] 7 8 ## Idea 9 10 [...] README.md z rozwiazanymi konfliktami M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 67 / 138
Rozwiazywanie konfliktów Rozwiazanie konfliktu oznaczamy używajac git add. $ git add README.md Jeśli wszystkie konflikty zostały rozwiazane, to można zakończyć merge: $ git commit [documentation 33693fc] Merge branch docs into documentation M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 68 / 138
Rozwiazywanie konfliktów M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 69 / 138
Usuwanie Jeśli chcemy usunać jakiś branch, nie może on być aktywny. Aby usunać branch, który został dołaczony do bieżacego ( bezpieczne usunięcie ), używa się opcji -d: $ git checkout master Switched to branch master $ git branch -d docs Deleted branch docs (was 48e8690). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 70 / 138
Usuwanie Aby usunać branch, który już nie jest potrzebny, a nie jest dołaczony do bieżacego (np. w międzyczasie powstała zupełnie inna koncepcja rozwiazania danego problemu), należy skorzystać z opcji -D (-d zwróci bład): $ git branch -d documentation error: The branch documentation is not fully merged. If you are sure you want to delete it, run git branch -D documentation. $ git branch -D documentation Deleted branch documentation (was 33693fc). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 71 / 138
Rebase Alternatywnym podejściem do scalania zmian jest stosowanie komendy git rebase. Jej działanie polega na edycji kolejności commitów (a co za tym idzie, na edycji zawartości samych commitów) tak, by commity z brancha podlegajacego operacji rebase wydawały się stworzone chronologicznie po wszystkich commitach brancha bazowego. Pozwala to na późniejsze bezkonfliktowe zastosowanie polecenia git merge. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 72 / 138
Rebase Załóżmy, że przed merge brancha docs został na bazie brancha master stworzony branch setup. Porównanie historii commitów w branchach master i setup pozwala stwierdzić, że różnia się one jednym commitem. $ git checkout setup Switched to branch setup $ git log M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 73 / 138
Rebase 1 commit 8e4bd6bf762a577795c42a33fb5ca27f9d2d43d7 2 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 3 Date: Wed Oct 14 22:28:05 2015 +0200 4 5 Correctly configure console entry point 6 7 commit 0903642a4b1118f7a75e10dad7f8271d2d28e4ed 8 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 9 [...] git log dla brancha setup M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 74 / 138
Rebase 1 commit 48e8690b2f7019dfc811bcc6f88e6d197198f796 2 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 3 Date: Wed Oct 14 19:42:20 2015 +0200 4 5 Added some formatting & idea description 6 7 commit 0903642a4b1118f7a75e10dad7f8271d2d28e4ed 8 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 9 [...] git log dla brancha master M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 75 / 138
Rebase Chcielibyśmy, by docelowa kolejność commitów w branchu master zawierała najpierw commit 48e8690, a następnie 8e4bd6b bez żadnych dodatkowych commitów wynikajacych z merge (tzw. merge fast-forward). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 76 / 138
Rebase M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 77 / 138
Rebase Oznacza to, że przed właczeniem brancha setup do master musimy zawrzeć wszystkie commity z master (będacego baza) w setup. Innymi słowy: ustalić nowa bazę dla setup (branch setup musi być aktywny): $ git rebase master First, rewinding head to replay your work on top of it... Applying: Correctly configure console entry point M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 78 / 138
Rebase M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 79 / 138
Rebase Po rebase historia brancha setup wyglada następujaco: 1 commit 3fe7e9e09628669e39f17c8cef6e4031326b4223 2 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 3 Date: Wed Oct 14 22:28:05 2015 +0200 4 5 Correctly configure console entry point 6 7 commit 48e8690b2f7019dfc811bcc6f88e6d197198f796 8 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 80 / 138
Rebase 9 Date: Wed Oct 14 19:42:20 2015 +0200 10 11 Added some formatting & idea description 12 13 commit 0903642a4b1118f7a75e10dad7f8271d2d28e4ed 14 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> 15 [...] git log dla brancha setup po rebase Warto zwrócić uwagę na identyfikatory commitów nawet w przypadku braku konfliktów (które rozwiazuje się analogicznie jak przy użyciu merge) git tak naprawdę zastępuje wszystkie unikatowe commity stworzone w branchu podlegajacemu rebase nowymi. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 81 / 138
Rebase Ostatnim krokiem jest właczenie brancha setup do master : $ git checkout master Switched to branch master $ git merge setup Updating 48e8690..3fe7e9e Fast-forward acai/main.py 2 +- setup.cfg 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 82 / 138
Używanie rebase Zalety: bardziej przejrzysta historia (unika się potencjalnie sporej ilości merge commitów ), ponieważ rebase de facto tworzy nowe commity, może on zostać wykorzystany do uporzadkowania historii brancha podlegajacego tej operacji (np. edycja starych opisów, łaczenie i rozdzielanie commitów). Aby skorzystać z tej możliwości używa się trybu interaktywnego (git rebase -i <base_branch>). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 83 / 138
Używanie rebase Wady i niebezpieczeństwa: w przeciwieństwie do merge, rebase jest potencjalnie destrukcyjna operacja. Oznacza to, że w razie pomyłki można zaprzepaścić wyniki pracy, nigdy nie powinno się używać rebase na tzw. publicznych branchach czyli takich, których w jakimś celu używa też ktoś inny (albo na podstawie którego powstały inne branche). Z punktu widzenia gita commity przepisane po rebase i oryginalne commity to dwie zupełnie różne rzeczy (nawet jeśli prowadza do tego samego rezultatu). W efekcie próba połaczenia oryginalnych i nowych zmian wygeneruje ogromna ilość konfliktów. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 84 / 138
Używanie rebase Przydatne uwagi: nigdy nie powinno się przeprowadzać operacji rebase na branchu master, przed nieudanym rebase można się w pewnym stopniu zabezpieczyć, tworzac tymczasowy branch: $ git checkout feature-branch $ git checkout -b temporary-branch $ git rebase -i master $ git checkout master $ git merge temporary-branch M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 85 / 138
Git 1 Systemy kontroli wersji 2 Systemy scentralizowane a rozproszone 3 Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami 4 Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów 5 Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja 6 Organizacja pracy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 86 / 138
Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 87 / 138
Zdalne repozytorium W większości zastosowań jedno z repozytoriów dostępne dla całego zespołu służy jako repozytorium centralne, analogicznie jak w systemach scentralizowanych. Repozytorium takie zwykle tworzone jest zanim zacznie się jakakolwiek praca na kodem lub tuż po stworzeniu minimalnego szkieletu projektu. Pozwala to na zminimalizowanie późniejszego konfigurowania lokalnych kopii. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 88 / 138
Remote Remote Repozytorium, najczęściej zdalne, które jest powiazane z dana instancja repo (nie musi być to repozytorium centralne, może to być np. kopia na maszynie innego developera). Przyjęło się, że domyślny remote dla danego repozytorium nosi nazwę origin. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 89 / 138
Ustawienie remote w istniejacym repo Aby dodać remote do istniejacego repo (przykładowo, gdy cała praca odbywała się lokalnie, a teraz została podjęta decyzja o upublicznieniu wyników) należy posłużyć się wariantem komendy git remote: $ git remote add origin git@bitbucket.org:maciekwielgosz/acai.git Aby zobaczyć dostępne remote y wraz z ich URLami, można użyć: $ git remote -v origin git@bitbucket.org:maciekwielgosz/acai.git (fetch) origin git@bitbucket.org:maciekwielgosz/acai.git (push) M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 90 / 138
Ustawienie remote w istniejacym repo Samo dodanie remote jednak nie wystarczy. Dla wygody użytkowania powinno się także ustawić dodany właśnie remote jako domyślny przy żadaniu synchronizacji pomiędzy repozytoriami (tzw. upstream). W przeciwnym razie będzie trzeba go podawać przy każdym tego typu żadaniu. Dalsze postępowanie zależy od tego, czy zdalne repozytorium ( origin ) zawiera już jakieś dane, czy też jest puste. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 91 / 138
Puste zdalne repozytorium Jeśli użyte ma być puste repozytorium, to pierwsza czynnościa po dodaniu remote do istniejacego projektu powinno być powielenie istniejacej lokalnej struktury w zdalnym repozytorium. Równocześnie w trakcie tej operacji można ustawić nowy remote jako domyślny do synchronizacji dla istniejacych branchy (opcja -u lub --set-upstream). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 92 / 138
Puste zdalne repozytorium Wysłanie (push) na remote origin wszystkich (--all) istniejacych lokalnie branchy: $ git push -u origin --all Counting objects: 50, done. Delta compression using up to 8 threads. Compressing objects: 100% (41/41), done. Writing objects: 100% (50/50), 12.84 KiB 0 bytes/s, done. Total 50 (delta 13), reused 0 (delta 0) To git@bitbucket.org:maciekwielgosz/acai.git * [new branch] master -> master Branch master set up to track remote branch master from origin. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 93 / 138
Zdalne repozytorium z zawartościa Jeśli w zdalnym repozytorium już istnieje branch, który ma być ustawiony jako domyślny przy synchronizacji, można zastosować to samo polecenie (wysłanie lokalnych zmian z równoczesnym zapamiętaniem remote): $ git push -u origin master Branch master set up to track remote branch master from origin. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 94 / 138
Zdalne repozytorium z zawartościa Alternatywa jest skorzystanie z wariantu polecenia git branch (nie dokonuje ono równocześnie synchronizacji): $ git branch -u origin/master Branch master set up to track remote branch master from origin. Warto zwrócić uwagę na różnicę w składni powyższych poleceń. git branch przyjmuje jako argument tylko nazwę brancha (origin/master traktowane jest jako całość). Pozwala ono na ustawienie jako upstream zdalnego brancha o nazwie innej niż lokalna, podczas gdy przy użyciu push nazwy musza się zgadzać. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 95 / 138
Klonowanie Jeżeli chcemy dopiero zaczać pracę z repo, które już gdzieś zdalnie istnieje, najprostszym sposobem jest użycie git clone. Pobierze ono automatycznie wszystkie istniejace branche, pozwalajac na natychmiastowe rozpoczęcie pracy (będa one domyślnie skonfigurowane, by pobierać i wysyłać zmiany na origin, czyli repo, z którego sklonowano instancję). M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 96 / 138
Klonowanie $ git clone git@bitbucket.org:maciekwielgosz/acai.git acai-clone Cloning into acai-clone... remote: Counting objects: 50, done. remote: Compressing objects: 100% (41/41), done. remote: Total 50 (delta 13), reused 0 (delta 0) Receiving objects: 100% (50/50), 12.84 KiB 0 bytes/s, done. Resolving deltas: 100% (13/13), done. Checking connectivity... done. Dodatkowy argument ustawia nazwę lokalnego katalogu na acai-clone. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 97 / 138
Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 98 / 138
Wysyłanie zmian Zmiany wysyłane sa do zdalnego repo przy użyciu znanego już git push. To, jakie branche git będzie próbował wysłać na serwer zależy od konfiguracji. Od wersji 2.0 git domyślnym zachowaniem (przy braku innych parametrów) jest wysyłanie zmian tylko z aktywnego brancha. Branch ten musi mieć ustawiony upstream i ta sama nazwę lokalnie, jak i w zdalnym repo. Wcześniejsze wersje wysyłały zmiany do wszystkich branchy, których nazwy lokalne pokrywały się ze zdalnymi. Mogło prowadzić to do opublikowania niechcianych zmian, więc zachowanie to zostało zmienione. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 99 / 138
Wysyłanie zmian $ cd ~/acai $ git status On branch master Your branch is ahead of origin/master by 1 commit. (use "git push" to publish your local commits) nothing to commit, working directory clean $ git --no-pager show --no-patch commit 3c7730e1860259cd79daf925a568e36c8fca06c8 Author: Maciej Wielgosz <wielgosz@agh.edu.pl> Date: Thu Oct 15 20:13:30 2015 +0200 Add acai ASCII art M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 100 / 138
Wysyłanie zmian $ git push Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (5/5), 1.17 KiB 0 bytes/s, done. Total 5 (delta 2), reused 0 (delta 0) To git@bitbucket.org:maciekwielgosz/acai.git 3fe7e9e..3c7730e master -> master M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 101 / 138
Pobieranie zmian Zmiany ze zdalnego repozytorium pobiera się poleceniem git fetch. Aby jednak zostały one zaaplikowane (faktycznie wprowadzone w plikach), należy następnie użyć git merge. $ cd ~/acai-clone $ git fetch remote: Counting objects: 5, done. remote: Compressing objects: 100% (5/5), done. remote: Total 5 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (5/5), done. From bitbucket.org:maciekwielgosz/acai 3fe7e9e..3c7730e master -> origin/master M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 102 / 138
Pobieranie zmian $ git merge Updating 3fe7e9e..3c7730e Fast-forward acai/acai.txt 31 +++++++++++++++++++++++++++++++ acai/main.py 13 ++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 acai/acai.txt M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 103 / 138
Pobieranie zmian Częściej używany jest git pull, będacy ich połaczeniem: $ git pull remote: Counting objects: 3, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From bitbucket.org:maciekwielgosz/acai 3c7730e..6c207ea master -> origin/master Updating 3c7730e..6c207ea Fast-forward.env 1 + 1 file changed, 1 insertion(+) create mode 100644.env M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 104 / 138
Możliwości fetch/pull fetch pobiera zmiany dla wszystkich branchy istniejacych na domyślnym remote, domyślny remote dla polecenia fetch może różnić się od domyślnego remote a dla polecenia push, pull może zostać tak skonfigurowany, by opierać swoje działanie na rebase zamiast na merge. Należy wtedy wziać pod uwagę te same punkty, które dotycza rebase. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 105 / 138
Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 106 / 138
Fork Fork Kopia repozytorium, zwykle stworzona w tym samym serwisie co repozytorium centralne. Może posłużyć do rozwijania odrębnej wersji projektu, jako sposób kontroli uprawnień użytkowników czy też dodatkowy poziom zabezpieczenia głównego repozytorium przed błędami. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 107 / 138
Kontrola dostępu Często, zwłaszcza w większych projektach, każdy z pracujacych developerów ma uprawnienia do pobrania zmian z głównego repozytorium (read access), ale tylko część z nich może bezpośrednio dokonywać w nim zmian (write access). Każdy z członków zespołu pracuje na swoim forku (jest to jego origin ), co jakiś czas synchronizujac go z głównym repozytorium (remote ten przyjęto nazywać upstream ). Gdy zakończy implementować dana funkcjonalność, stworzone przez niego zmiany sa zatwierdzane i właczane do głównego repozytorium przez kogoś posiadajacego odpowiednie uprawnienia. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 108 / 138
Pull request Proces zgłaszania, akceptowania (badź odrzucania) i właczania zmian do głównego repozytorium zazwyczaj odbywa się przy pomocy tzw. pull requestów. Pull requesty pozwalaja na łatwe przegladanie zmian, ich komentowanie, automatyczne testy kodu czy też prosta synchronizację z główna wersja kodu. W możliwość łatwego tworzenia forków i pull requestów wyposażona jest obecnie większość serwisów udostępniajacych usługę przechowywania repozytoriów. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 109 / 138
Tworzenie forka M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 110 / 138
Tworzenie forka M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 111 / 138
Praca z forkiem $ git clone git@bitbucket.org:yuijim/acai.git acai-fork Cloning into acai-fork... [...] $ cd acai-fork $ git remote add upstream git@bitbucket.org:maciekwielgosz/acai.git $ git remote origin upstream $ git branch * master M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 112 / 138
Praca z forkiem W czasie pracy z forkiem zwykle nie robi się zmian bezpośrednio na branchu master. Ma on służyć jako branch referencyjny, który można łatwo synchronizować z głównym repozytorium ( upstream ) przed rozpoczęciem kodowania. $ git pull upstream master remote: Counting objects: 4, done. remote: Compressing objects: 100% (4/4), done. remote: Total 4 (delta 3), reused 0 (delta 0) Unpacking objects: 100% (4/4), done. From bitbucket.org:maciekwielgosz/acai * branch master -> FETCH_HEAD * [new branch] master -> upstream/master [...] M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 113 / 138
Praca z forkiem Wszystkie zmiany wprowadzane sa na dedykowanych branchach. W ten sposób można pracować nad kilkoma poprawkami/funkcjonalnościami jednocześnie, zawsze majac jako bazę aktualna wersję kodu z głównego repozytorium. Dzięki takiemu postępowaniu nie ma problemów, jeśli np. część zmian zostanie zaakceptowana, a część odrzucona. $ git checkout -b fix-autoenv Switched to a new branch fix-autoenv M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 114 / 138
Pull request Gdy proponowane zmiany znajda się już na forku danego developera, należy stworzyć pull request, który następnie będzie oczekiwał na akceptację. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 115 / 138
Pull request M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 116 / 138
Pull request M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 117 / 138
Git 1 Systemy kontroli wersji 2 Systemy scentralizowane a rozproszone 3 Git jako system lokalny Inicjalizacja Stany plików Zapis stanu Historia Praca z branchami 4 Git jako system rozproszony Zdalne repozytorium Podstawowa synchronizacja Model pracy oparty o wiele repozytoriów 5 Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja 6 Organizacja pracy M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 118 / 138
Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 119 / 138
Ignorowanie plików Plik.gitignore pozwala na ignorowanie niektórych plików i katalogów w projekcie, np. plików wynikowych kompilacji czy automatycznych kopii zapasowych plików. Zazwyczaj tworzy się go w głównym katalogu projektu. Może on zawierać konkretne ścieżki lub ogólne wzorce nazw plików. Działa on tylko dla nieśledzonych plików pliki które zostały dodane przed jego stworzeniem (lub ich dodanie zostało wymuszone pomimo ustawień w.gitignore) w dalszym ciagu będa śledzone. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 120 / 138
Ignorowanie plików 1 # Filesystem helper files 2.DS_Store 3 4 # Temporary and binary files 5 *~ 6 *.py[cod] 7 *.so 8 *.cfg 9!setup.cfg 10 *.orig 11 *.log Fragment przykładowego.gitignore M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 121 / 138
Inne możliwości Ignorowanie plików Konfiguracja Więcej o komendach i opcjach Dodatkowa dokumentacja M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 122 / 138
Konfiguracja Konfiguracja zachowania gita odbywa się na trzech poziomach, z których każdy nadpisuje ustawienia poprzedniego: systemowy przechowywany w /etc/gitconfig, definiuje zachowanie gita dla wszystkich użytkowników, globalny zwykle zapisany w $HOME/.gitconfig, definiuje zachowanie dla danego użytkownika, lokalny znajduje się w pliku.git/config w każdym repozytorium i definiuje specyficzne dla niego ustawienia. M. Wielgosz (AGH - IET) Programowanie w językach skryptowych - Python i Linux Bash 2015 123 / 138