Git Tutorial
description
Transcript of Git Tutorial
Tutorial Gita
Jacek Bzdak
1
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
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
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
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
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.
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.
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.
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(-)
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
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
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
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:
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:
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.
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.
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.
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