Git Tutorial

18
Tutorial Gita Jacek Bzdak 1

description

Opis systemu git.

Transcript of Git Tutorial

Page 1: Git Tutorial

Tutorial Gita

Jacek Bzdak

1

Page 2: Git Tutorial

Spis tresci

Spis tresci 2

1 Instalacja gita 41.1 Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Instalacja dla Cygwina . . . . . . . . . . . . . . . . 4

2 Praca z GITem 52.1 Słownik gita . . . . . . . . . . . . . . . . . . . . . . . . . . . 52.2 Proste zastosowania gita . . . . . . . . . . . . . . . . . . . 6

Komitowanie . . . . . . . . . . . . . . . . . . . . . . . . . . 7Branche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Checkoutowanie . . . . . . . . . . . . . . . . . . . . . . . . 7Merge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7Scenariusz: praca z branchachami . . . . . . . . . . . . . 8Wycofywanie zmian . . . . . . . . . . . . . . . . . . . . . . 8

Scenariusz: Wycofanie nieskomitowanych zmian . 9Scenariusz: Wycofanie skomitowanych zmian 1 . . 9Scenariusz: Wycofanie skomitowanych zmian 2 . . 9

O gorliwosci gita i git-stash . . . . . . . . . . . . . . . . 92.3 Praca z wieloma repozytoriami . . . . . . . . . . . . . . . . 11

Repozytoria nazwane . . . . . . . . . . . . . . . . . . . . . 11Kopiowanie repozytoriów . . . . . . . . . . . . . . . . . . . 11Nagie repozytoria . . . . . . . . . . . . . . . . . . . . . . . 12Pobieranie danych z repozytorium . . . . . . . . . . . . . . 12Wysyłanie danych do repozytoriów . . . . . . . . . . . . . 12Scenariusz: praca ze zdalnym repozyrorium . . . . . . . . 12Scenariusz: upublicznienie repozytorium po ssh . . . . . 13Scenariusz: pobranie zawartosci repozytorium . . . . . . 13

2.4 Zaawansowana praca z branchami . . . . . . . . . . . . . 13Rodzaje mergeów . . . . . . . . . . . . . . . . . . . . . . . . 13Metody mergeowania . . . . . . . . . . . . . . . . . . . . . 14O nieumieszczanu plików IDE w repozytorium . . . . . . 15Kasowanie branchy . . . . . . . . . . . . . . . . . . . . . . 15

2.5 Zaawansowane uzycia gita . . . . . . . . . . . . . . . . . . 15Gitignore . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15Znaki konca linii . . . . . . . . . . . . . . . . . . . . . . . 16git-config . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

2

Page 3: Git Tutorial

Spis tresci 3

Punkt w historii . . . . . . . . . . . . . . . . . . . . . . . . 17Urle które obsługuje git . . . . . . . . . . . . . . . . . . . . 17Stashing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18Hardlinki a git-clone . . . . . . . . . . . . . . . . . . . . 18Czytanie historii . . . . . . . . . . . . . . . . . . . . . . . . 18Przepisywanie historii . . . . . . . . . . . . . . . . . . . . . 18

git-rebase . . . . . . . . . . . . . . . . . . . . . . . . 18Scenariusz: Wyciagniece podmodułu z kodu. . . . 18

Page 4: Git Tutorial

Rozdział 1

Instalacja gita

1.1 Linux

Prosta piłka — nalezy uzyc swojego managera pakietów.Dla ubuntu/debiana nalezy wpisac:

sudo apt-get install git-core

Dodatkowo mozna zainstalowac przydatne narzedzia

programdo mergeowania Na przykład meld, kdiff3. Te obsługiwaneprzez gita natywnie sa wypisane w manie dla git-config w opisieklucza merge.tool.

edytor tekstu do edycji messagey commiów. Ja nie lubie vi uzywamnano.

1.2 Windows

Tu juz trzeba cudowac. Oficjalny port gita dla windows jest w cygwinie.. . A jaki cygwin jest wiadomo ;)

Tak czy inaczej mamy takie opcje:

Cygwin

MSGit Natywna implementacja. Ponoc szybsza niz cygwinowa. Nie wiem,nie bawiłem sie. Mozna ja porac ze strony http://code.google.com/p/msysgit/.Nie wiem nie bawiłem sie.

Instalacja dla Cygwina

Najpierw trzeba sciagnac instalator cygwina, nastepnie nalezy scia-gnac pakiety dla gita i openssh (jesli potrzebne jest wsparcie gita wspar-cia dla ssh).

Jesli potrzebujesz korzystac z ssh-agent, trzeba jeszcze w pliku$CYGWIN_FOLDER$\bin\cygwin.bat zamienic ostatnia linie na ssh-agentbash --login -i.

4

Page 5: Git Tutorial

Rozdział 2

Praca z GITem

Filozofia1 gita2 jest zasadniczo rózna od filozofii klasycznych systemowwersjonowania. Repozytorium gita to po prostu dowolny katalog w któ-rym znajduje sie podkatalog o nazwie .git zawierajacy dane wersjo-nowania. Repozytorium po stronie serwera niczym nie rózni sie od re-pozytorium kilenta — albo inaczej — w gicie nie istnieja w ogóle pojeciaserwera i kilenta, repozytoria sa równoprawne.

Zawartosc katalogu repozytorium (poza katalogiem .git) to takzwana kopia robocza3.

2.1 Słownik gita

Wówczas Budda rzekł: <<Bracia istnieja tylkodziałania oraz ich skutki, ale nie istnieje osoba,która działa (...) Nie istnieje zadne indywiduum,jest tylko umownma nazwa nadana zbiorowielementów>>

Nizeznany

Krótkie wyjasnienie pojec gita

repozytorium Struktura danych zawierajaca historie projektu (zawar-tosc katalogu .git).

kopia robocza Bierzaca wersja projektu na której pracuje programi-sta.

nazwa Nazwa obiektu Gita to 20 cyfrowy skrót SHA-1 danego obiektu.

obiekt Cos co jest w repozytorium gita. Sa nastepujace rodzaje obiek-tów gita: blob4, drzewa, komity, tagi.

1„Filozofia to legalne dragi” — madrosc ludowa2I innych tzw. rozproszonych systenów wersjonowania3(z ang.) working copy4

z ang. binary large object

5

Page 6: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 6

blob Reprezentuje plik. Najgłupszy obieky gita. Jego nazwa jest cał-kowicie determiniowana przez jego zawartosc, czyli dwa pliki oróznych nazwach i połozeniach maja jedna i dziela tego samegobloba.

drzewo Reprezentuje katalog. Zawiera odniesienia do innych drzew ido blobów. Bloby reprezentuja pliki w danym katalogu, drzewa— podkatalogi. Drzewo przechowuje tez nazwy (nie chodzi mi tuo nazwy gita, ale o filenames) plików i katalogów które zawiera.Nazwa drzewa zalezy tylko od jego zawartosci.

commit Czyli stan projektu w danej chwili czasu. Zawiera odniesieniedo drzewa które reprezentuje główny katalog projektu w chwilikomitowania i komitu rodzica. Zawiera tez komentarz, osobe kom-tujaca i autora zmian5. Komit nie posiadajacy rodzica, to takzwany root commit który reprezentuje inicjalna wersje projektu.Commit, który reprezentuje łaczenie branchy, moze miec wiecejniz jednego rodzica.

tag Czyli zrozumiała dla człowieka nazwa jakiegos obiektu. Zawierainformacje o osobie które ów obiekt otagowała i komentarz. Mozezawierac cyfrowy podpis danego tagu.

index Plik bedacy posrednikiem miedzy kopia robocza a repozytorium.Podczas komitowania skomitowana nie bedzie cała zawartosc ko-pii roboczej, a tylko zawartosc indexu.

HEAD wskaznik na bierzacego brancha

2.2 Proste zastosowania gita

Czyli jak stosowac gita na lokalnym komputerze.

Tworzenie repozytorium

By utworzyc repozytorium w bierzacym katalogu nalezy wykonac po-lecenie:

git-init

Dodawanie plików do indexu

Podczas komitowania do repozytorium trafiaja tylko pliki znajdujacesie w indeksie. By dodac plik do indeksu nalezy wykonac polecenie:

git-add lista_plików

Poniewaz git-add przyjmuje liste plików mozna przy nim uzywacznaków wieloznacznych np:

git-add *tex

5W Gicie który powtał na potrzeby jadra linuxa moga to byc dwie rózne osoby —jedna osoba poprawia bład, kto inny ma prawo do komitowania do repozytorium jadra.

Page 7: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 7

Mozna równiez dodawac drzewa katalogów, na przykład polecenie:

git-add .

Doda cały bierzacy katalog.

Komitowanie

By skomitowac dodane pliki nalezy wykonac nastepujace polecenie:

git-commit [-a] [-m tresc wiadomosci]

Wyjasnienie parametrów:

-a Bez tego parametru git skomituje tylko pliki które sa w indeksie –czyli te o zmianach w których został poinformowany poleceniemgit-add. Z tym parametrem git automatycznie doda wszystkiezmodyfikowane lub usuniete pliki o które juz sa w indeksie, leczzignoruje wszystkie nowe pliki.

-m Komentarz komitu. Jest obowiazkowy, jesli nie jest on podany gitotworzy w konsoli okno edytora w którym mozna go napisac. Otym jak wybrac odpalany przez gita edytor w 2.5 na stronie 16.

Branche

By stworzyc brancha nalezy wkonac polecenie:

git-branch nazwa_brancha punkt_w_historii

nazwa_brancha Pownna byc zrozumiała dla człowieka, nie moze za-wierac spacji. Domyslnie git pracuje w branchu master.

punkt_w_historii Czyli do czego ma sie dany branch odnosic. Jeslitego parametru nie podamy branch utworzy sie wskazujac nabierzace połozenie.

Uwaga! git-branch tylko tworzy brancha - nie zaczynamy w nim pra-cowac.

Checkoutowanie

Polecenie git-checkout przenosi do kopii roboczej jakis punkt w hi-storii.

git-checkout punkt_w_historii

Merge

Czyli łaczenie branchy. Do łaczenia branchy słuzy polecenie:

git-merge nazwa_brancha

Polecenie to przenosi zmiany z brancha nazwa_brancha do bierza-cego brancha.

Page 8: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 8

Scenariusz: praca z branchachami

Załózmy ze zaczynamy w branchu master, który ma zawierac gotowy,przetestowany kod. Chcemy dokonac jakiejs zmiany w kodzie, ale niechcemy by byla ona w tym branchu, puki jej nie przetestujemy. Moznaoczywiscie zmian nie umieszczac w repozytorium póki nie beda onegotowe, ale przeciez po to jest repozytorium, zeby w nim trzmyac kod.

Tworzymy wiec brancha work w którym beda zmiany, wprowadzamyw nim zmiany, testujemy je, a nastepnie merdzujemy do rbancha master.Musimy wiec wykonac nastepujace polecenia.

Najpierw tworzymy brancha work.

git-branch work

Mozemy sprawdzic czy rzeczywiscie go utworzylismy wywołujac ko-mende git-branch bez argumentów która po prostu wyswietla wszyst-kie branche.

$ git-branch

* masterwork

Gwiazdka zaznaczono bierzacy branch.Teraz przechodzimy do brancha work.

git-checkout work

Dokonujemy zmian i komitujemy je.

git-commit -a

Po skomitowaniu zmian checkoutujemy brancha master. Musimyto zrobic gdyz git-merge działa w ten sposób ze do bierzacego branchamergeuje inny branch.

git-checkout master

Wykonujemy mergea

git-merge work

Teraz mozemy albo przeniesc sie do brancha work i dalej pracowacalbo np skasowac brancha work.

Wycofywanie zmian

Do usuniecia nieskomitowanych zmian słuzy polecenie:

git-reset --tryb commit

Tryby sa trzy:

soft Nie resetuje indexu, ani kopii roboczej. Zmienia tylko wskaznikheada.

mixed Resetuje indeks, nie dotyka kopii roboczej. Po wywołaniu tegopolecenia zaden z plików nie bedzie oznaczony jako gotowy doskomitowania.

Page 9: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 9

hard Resetuje indeks i kopie robocza.

Parametr commit to commit na który bedzie wskazywac HEAD po wy-wołaniu tego polecenia, jesli nie podamy tego paramtetru HEAD niebedzie zmieniony.

Scenariusz: Wycofanie nieskomitowanych zmian

Załózmy ze robie refractoring kodu, przy czym decyduje ze jakas zmianajednak jest nietrafiona. Zeby wycowac wszystkie zmiany musze napi-sac:

git-reset --hard

Scenariusz: Wycofanie skomitowanych zmian 1

Podobnie jak ostatnio, z tym ze zmiany zostały skomitowane. Ciaglemoge je wycofac poleceniem git-reset, jednak jest to potencjalnie doscgrozne. Najpierw jednak polecenie:

git-reset --hard HEAD^

HEAD^ — znaczy rodzic HEAD. Wiecej o nazwach gita w sekcji 2.5na stronie 17.

Niebezpieczenstwo jest takie ze jesli gdy któs ów commit wychec-koutuje i bedzie nad nim dalej pracowac zaczniecie miec niespójna hi-storie, a wtedy git zgłupieje, ziemia sie otworzy i wyjdzie z niej szatan;).

Scenariusz: Wycofanie skomitowanych zmian 2

Do wycofania opublikowanego commitu słuzy polecenie git-revert.Wykonuje ono commit cofajacy zmiany.

Róznica miedzy git-reset a git-revert jest taka ze jesli uzyjeszpierwszego to w historii nie pozostanie sladu po złym commicie.

O gorliwosci gita i git-stash

Git nigdy nie nadpisze zmian nieznajdujacych sie w repozytorium —czyli nigdy nie wykona nieodwracalnych zmian. Cos takiego moze siezdarzyc w kilku przypadkach. Przykładowo mamy w kopii roboczej plikbaz.txt, który jest poza repozytorium (nie był dodany), a w branchu B(czyli automatycznie w repozytorium) jest plik o tej samej nazwie z innazawartoscia.

Mozna to zobaczyc na własne oczy:

jb@lucy:~/foo$ git-initInitialized empty Git repository in /home/jb/foo/.git/jb@lucy:~/foo$ echo "xxx" > foo.txtjb@lucy:~/foo$ git-add foo.txtjb@lucy:~/foo$ git-commitCreated initial commit c073b2e: sa1 files changed, 1 insertions(+), 0 deletions(-)

Page 10: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 10

create mode 100644 foo.txtjb@lucy:~/foo$ git-branch workjb@lucy:~/foo$ git-checkout workSwitched to branch "work"jb@lucy:~/foo$ echo "zzz" > baz.txtjb@lucy:~/foo$ git-add baz.txtjb@lucy:~/foo$ git-commitCreated commit 44e60cc: baz1 files changed, 1 insertions(+), 0 deletions(-)create mode 100644 baz.txtjb@lucy:~/foo$ git-checkout masterSwitched to branch "master"jb@lucy:~/foo$ echo "yyy" > baz.txtjb@lucy:~/foo$ git-checkout workerror: Untracked working tree file ’baz.txt’ would be

overwritten by merge.jb@lucy:~/foo$ git-merge workUpdating c073b2e..44e60ccerror: Untracked working tree file ’baz.txt’ would be

overwritten by merge.

By problem rozwiazac nalezy plik baz.txt dodac do repozytorium:

jb@lucy:~/foo$ git-add baz.txtjb@lucy:~/foo$ git-commitCreated commit df1cf44: foo1 files changed, 1 insertions(+), 0 deletions(-)create mode 100644 baz.txtjb@lucy:~/foo$ git-checkout workSwitched to branch "work"jb@lucy:~/foo$ git-checkout masterSwitched to branch "master"jb@lucy:~/foo$ git-merge workAuto-merged baz.txtCONFLICT (add/add): Merge conflict in baz.txtAutomatic merge failed; fix conflicts and then commit

the result.jb@lucy:~/foo$ git-mergetoolMerging the files: baz.txtjb@lucy:~/foo$ git-commitCreated commit 5fa91f9: Merge branch ’work’

Analogicznie Git sie zachowa jesli spróbujemy wykonac mergea/com-mita przy nieskomitowanych zmianach w kopii roboczej.

jb@lucy:~/foo$ git-checkout workSwitched to branch "work"jb@lucy:~/foo$ echo "jjj" > foo.txtjb@lucy:~/foo$ git-commit -aCreated commit b04a588: das1 files changed, 1 insertions(+), 1 deletions(-)jb@lucy:~/foo$ git-checkout master

Page 11: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 11

Switched to branch "master"jb@lucy:~/foo$ echo "ppp" > foo.txtjb@lucy:~/foo$ git-merge workfoo.txt: needs updateerror: Entry ’foo.txt’ not uptodate. Cannot merge.fatal: merging of trees

62c4cf4f82d52932a4d2148efa7e80f1807ac6aa and9923cc607172ca543cb5115f0ce25178a033651a failed

Merge with strategy recursive failed.

Na pierwszy rzut oka jest to upierdliwe, lecz z drugiej strony: chroniprzed nieodwracalnym usunieciem zmian.

2.3 Praca z wieloma repozytoriami

Repozytoria nazwane

Git posiada mechanizmrepozytoriów nazwanych, które choc to koniecznedo pracy ze zdalnymi repozytoriami bardzo ja ułatwia.

By utworzyc nadac jakiemus zdalnemu repozytroum nazwe nalezywykonac polecenie:

git-remote add nazwa url

nazwa to nazwa zdalnego repozytorium. Nie moze zawierac spacji.

url to url do danego repozytrorium. Przykładowo moze byc to Urlemmoze byc na przykład: ssh://skimbleshanks.ath.cx/var/git/diesIrae6,urlem moze tez byc sciezka lokalnego systemu plików.

Kopiowanie repozytoriów

Sa dwie metody na kopiowanie repozytoriów.Pierwsza jest Pierwsza jest polecenie git-clone. Pozwala ono sko-

piowac zawartosc całego repozytorium.

git-clone url

Po wykonaniu tego polecenia z podanym urlem git zrobi nastepu-jace rzeczy:

1. utworzy w bierzacym katalogu katalog diesIrae

2. zainicjalizuje w nim repozytorium

6Skimbleshanks is a cat character in T. S. Eliot’s book of poetry Old Possum’s Bookof Practical Cats and in Andrew Lloyd Webber’s musical Cats:

Saying ‘Skimble where is Skimble has he gone to hunt the thimble?We must find him or the train can’t start.’All the guards and all the porters and the stationmaster’s daughtersThey are searching high and low,Saying ‘Skimble where is Skimble for unless he’s very nimbleThen the Night Mail just can’t go.’

Zródło: http://en.wikipedia.org/wiki/Skimbleshanks

Page 12: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 12

3. sciagnie zawartosc z zadanego repozytorium

4. W repozytorium na tym komputerze utworzy odniesienie o nazwieorigin wskazujace na danego urla.

Nagie repozytoria

Sa to repozytoria nie majace kopii roboczej. Maja bardzo ograniczonafunkcjonalnosc — nie mozna na nich wykonywac wielu operacji (wzasadzie wszystkich poza komitowaniem kodu i pobieraniem zmian).Nadaja sie natomiast całkiem niezle rpeopzytoria w serwerze. Twozysie je poleceniem:

git-init --bare

Pobieranie danych z repozytorium

By pobrac zawartosc repozytorium nalezy wykonac polecenie:

git-fetch nazwa_repozytorium

Spowoduje to pobranie wszystkich branchy z danego repozytorium izapisanie ich jako branchy o nazwach: nazwa_repozytorium/nazwa_brancha

Przykładowo, w repozytorium skimbleshanks znajduje sie branchmaster wiec po wykonaniu polecenia:

git-fetch skimbleshanks

powstanie branch o nazwie skimbleshanks/master.

Wysyłanie danych do repozytoriów

By wysłac zmienione pliki do repozytorium nalezy wykonac:

git-push nazwa_repozytorium wysylany_branch

Polecenie git-push zadziała poprawnie tylko jesli merge zmian dobrancha na zdalnym repozytrium bedzie typu fast forward, czyli niktinny w miedzyczasie nie zmieni zalnego brancha. Jesli tak nie bedziegit-push zwróci bład.

Scenariusz: praca ze zdalnym repozyrorium

Zakładam ze pracuje na repozytorium skimbleshanks, w branchuunstable.

Rano sciagam ewentualne zmiany z repozytorium:

git-fetch skimbleshanks unstable

Podczas całego dnia wykonuje zmiany w kodzie. Chce teraz mojezmiany wysłac do zdalnego repozytorium.

Polecenie git-push zadziała poprawnie tylko jesli merge zmian dobrancha na zdalnym repozytrium bedzie typu fast forward (dokłanie otypach merdzy w 2.4 na nastepnej stronie), czyli nasz branch bedziezawierał w swojej hisorii HEADa zdalnego brancha. Bedzie tak jesli

Page 13: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 13

albo nikt nie komitował w miedzyczasie do zdalnego brancha, albo myw naszym repozytorium zmergeowalismy nowe zdalne zmiany.

Załózmy ze w miedzyczasie ktos skomitował cos do tego repozyto-rium. Musimy zatem nowe zmiany pobrac raz jeszcze:

git-fetch skimbleshanks unstable

Teraz owe zmiany mergeujemy:

git-merge skimbleshanks/unstablegit-mergetool

Po mergeowaniu mozna juz wysłac zmiany:

git-push skimbleshanks unstable

Scenariusz: upublicznienie repozytorium po ssh

Powiedzmy ze mam repozytorium na moim lokalnym komputerze, re-pozytorium zawiera program nad którym mój kolega Adam chce pra-cowac. Moze on bezposrednio pobierac zmiany z mojego repozytorium(o ma dostep), ale mozemy tez ustawic repozytorium na zdalnym ser-werze i obaj do niego komiowac, rozwiazanie to jest lepsze o tyle o ilelepiej sie skaluje.

Powiedzmy ze serwer nazywa sie skimbleshanks.Najpierw na zdalnym komputerze tworze nagie repozytorium (ma to

sens poniewaz nikt nie bedzie na tym repozytorium pracowac bezpo-srednio).

jb@skimbleshanks$ git-init --bare

Nastepnie, u siebie, tworze repozytorium nazwane:

jb@lucy$ git-remote add skimbleshanksssh://skimbleshanks.ath.cx/var/git/diesIrae

Potem przesyłam do repozytorium na skimbleshanks zawartosc mo-jego repozytorium. Wykonuje u siebie polecenie:

jb@lucy$ git-push --all skimbleshanks

Scenariusz: pobranie zawartosci repozytorium

Teraz Adam chce pobrac zawartosc tego repozytorium. Wykonuje wiecpolecenie:

git clone ssh://skimbleshanks.ath.cx/var/git/diesIrae

2.4 Zaawansowana praca z branchami

Rodzaje mergeów

Sa trzy roadzaje mergeów:

Page 14: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 14

Rysunek 2.1: Ilustracja mergea already up to date.

Rysunek 2.2: Ilustracja fast forward merge

Rysunek 2.3: Ilustracja mergea

already up to date Jesli próbujemy zmergeowac commita który juzjest czescia historii HEADa. W tym wypadku merge nie wykonujezadnej czynnosci.

fast_forward Odwrotnie: HEAD jest czescia historii mergeowanego com-mita. W tym przypadku nie jest tworzony komit mergeujacy (bo inie ma zadnych nowych zmian w repozytorium), po prostu HEADjest updejtowany tak ze wskazuje na komit merdzowany.

prawdziwy_merge Nie zachodzi zadna z powyzszych alternatyw. Trzebamergeowac recznie i (opcjonalnie) rozwiazywac konflikty.

Obrazki powinny rozjasnic sytuacje, opisane merdze sa na obrazkach.Kropki reprezentuja komity. Jestesmy w pukcie zaznaczonym zółtakropka i mergeujemy kropke niebieska.

Metody mergeowania

Jesli w merdzu beda konflikty (ten sam plik wyedytowany w obu gałe-ziach) to stana sie nastepujace rzeczy:

• Git przejdzie w specjalny stan który zabrania wykonywac komitypuki merge nie bedzie wykonany

• Do plików z konfliktami zosana wyplute conflict markery, którewygladaja mniej wiecej tak:

Page 15: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 15

<<<<<<< HEAD:file.txtHello world=======Goodbye>>>>>>>

77976da35a11db4580b80ae27e8d65caf5208086:file.txt

Teraz pora na git-mergetool jest to narzedzie pozwalajace na roz-sadzenie konfliktów.

O nieumieszczanu plików IDE w repozytorium

Taka krótka sprawa. Nieumieszczanie plików generowanych przez IDEw repozytorium jest dobrym pomysłem w ogóle. Jednak przy uzywaniuGITa umieszczanie tych plików ma dodatkowe wady szczególnie jesliuzywamy branchy.

Przy mergeowaniu branchów czesto w tych plikach beda konflikty,co wiecej podczas rozwiazywania takiego mergea moze sie okazac zeprzestanie działac. Git wypluje do plików konfiguracyjnych markerykonfliktów, przez co IDE moze ich nie umiec odczytac! Brrr.

No i jesli sie okaze ze dodamy plik IDE w trakcie pisania projektumoze sie okazac ze merge nie wychodza w ogóle — mamy taka sytuacje:w branchu work dodajemy do repozytorium jakis plik IDE, który przyokazji jest modyfikowany przez owo IDE, i od tej pory merdz branchamaster i work bedzie wypluwac bład (patrz. 2.2):

jb@lucy:~/foo$ git-merge workfoo.txt: needs updateerror: Entry ’.classpath’ not uptodate. Cannot merge.

Kasowanie branchy

Branche mozna tez kasowac.

git-brach -d nazwa_brancha

Polecenie to ze switchem -d ma wbudowane zabezpieczenie — wy-kona sie tylko jesli ten branch nazwa_brancha jest juz wmergeowanyw HEADa.

Jesli chcemy skasowac bracha bez tego sprawdzenia, bo na przy-kład zawiera on kod którego nie chcemy mergeowac nalezy uzyc para-metru -D:

git-brach -D nazwa_brancha

2.5 Zaawansowane uzycia gita

Gitignore

Nie wszystko powinno byc w repozytorium. Jesli jednak mamy grupyplików których w repozytorium nie chcemy polecenie git-add z argu-mentem . zaczyna byc bezuzyteczne.

Page 16: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 16

Mozemy zatem nakazac Gitowi ignorowanie pewnych wzorców nazwplików. Zainteresowanych odsyłam do

man gitignore

Znaki konca linii

Znaki konca linii sa zmora jesli nad programem w jednym repozyto-rium pracuja uzytkownicy *nixów i windowsów.

Git jednak jest w stanie sobie z tym poradzic (z pewnymi ale). Jesliustawimy w konfiguracji klucz core.autoclf na wartosc true to gitprzy zapisywaniu bedzie podmieniał sekwencje CRLF na samo LF, aprzy odczycie na odwrót. Warto od razu ustawic opcje core.safeclf,która pilnuje ze konwertowane sa tylko pliki dla których konwersjajest odwracalna.

Zasadniczym problemem z tym mechanizmem jest to ze git mozetak potraktowac pliki binarne (generalnie stara sie je wykrywac i nawetmu to wychodzi — jednak mozliwosc jest ze sie pomyli). Git w obiek-tach blob nie pamieta nazw plików (wszak jeden blob moze miec kilkanazw w róznych momentach historii), wiec wykrywanie binarnosci pli-ków musi działac majac tylko jego zawartosc. Opcja core.safeclfpilnuje ze nawet jesli plik jest jest przez gita uszkadzany zmiana jestodwracalna (potem sa jakies mechanizmy oznaczania plików jako pli-ków binarnych)7.

git-config

Narzedzie pozwalajace konfigurowac gita.

Konfiguracja edytora W 2.2 na stronie 7 dowiedzielismy sie zejesli poleceniu git-commit nie podac komentarza do komita git odpaliedytor. Poniewaz kazdy ma swój ulubiony edytor mozna skonfigurowacpolecenie ów edytor właczacy. Słuzy do tego klucz w konfiguracji onazwie: core.editor. Na przykład:

git-config --global core.editor emacs

.Opcje konfiguracji sa dobrze udokumentowane w manie

man git-config

Znaki konca linii Do zarzadzania traktowaniem znaków koncalinii słuza klucze: core.autoclf i core.safeclf. Patrz akapit 2.5.

7Dla mnie cała ten wywód to wyzsza magia i jest on mało interesujacy — w moichrepzoytoriach nie ma plików binarnych (poza wyjatkami w stylu: wrappery .exe ktoreodpalaja moje programy javy, które to wyjatki i tak da sie łatwo odtworzyc). Zalezno-sciami zajmuje sie maven i ich nie ma w repozytorium.

Page 17: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 17

Punkt w historii

Historia gita sklada sie z grafu komitów, historia brancha to linia co-mitów. Kazdy punkt historii jest dostepny po nazwie komitu. Nazwygita sa raczej nieporeczne — wszak to 20 cyfrowe hasze SHA-1. Za-miast całeho SHA-1 mozna podac jego poczatek — o ile poczatek jestunikalny w repozytorium. Tak wiec zamigit-resetast

git-checkout 980e3ccdaac54a0d4de358f3fe5d718027d96aae

Mozna napisac:

git-checkout 980e3cc

Jest tez kilka innych mozliwosci:

nazwa barancha Punktem w historii jest tez nazwa brancha — wska-zuje on na najswiezszy commit w branchu.

nazwa tagu Tag to de facto commit.

HEAD Czyli najswiezszy comit w aktualnym branchu.

Rodzice Mozna odniesc sie tez do rodziców danego commita. HEAD^ torodzic HEADa. Mozna tez zapytac o dalszych rodziców horzystajacz HEAD@{n}, gdzie n to poszukiwane pokolenie.

Urle które obsługuje git

Git obsługuje rózne i rózniaste rodzaje urli:

lokalne pliki Podajemy po prostu absolutna sciezke do danego kata-logu.

git-clone /var/git/diesIrae

ssh Przykłady były

http Choc ustawienie repozytorium HTTP gita nie jest bardzo łatwe8,to mozna łatwo pobierac repozytorium gita za pomoca tego pro-tokołu.

http://foo/git/diesIrae

Wszystkie mozliwosci urla sa opisane w manie dla git-clone.

8Nie jest tez jakos trudne ;) po prostu sie na tym nie znam totalnie.

Page 18: Git Tutorial

ROZDZIAŁ 2. PRACA Z GITEM 18

Stashing

Hardlinki a git-clone

Czytanie historii

Przepisywanie historii

git-rebase

Scenariusz: Wyciagniece podmodułu z kodu.

Mam projekt który stanowi gui dla takiego sprzetu spektrometrycz-nego. Kawałkiem projektu jest biblioteka, i teraz owa biblioteke chcez projektu wyciac i przeniesc do własnego repozytorium, tak by za-chwoac cała historie owej biblioteki.

W zasadzie git ma standardowe narzedzia do zarzadzanai podmo-dułami, ale ja jestem na to troszke za głupi.

Znalazłem wiec projekt git-subtree, który robi dokładnie to, nie jestto czesc standardowego gita, ale działa.

Najpierw trzeba to sobie sciagnac i umiescic gdzies w pathu. Scia-gamy z http://github.com/apenwarr/git-subtree. Interesuje nas plikgit-subtree.sh.

Zakładamy ze biblioteka jest w podkatalogu o nazwie libdir.

git-subtree --prefix libdir -b lib-export

Utworzy to nam brancha o nazwie lib-export zawierajacego wszyst-kie commity dotykajace katalogu libdir.

Teraz tworzymy repozytroium i wykonujemy:

git-push url_repozytorium lib-export