Szerkesztő:Madbence/Git tutorial
Leírás
A Git egy elosztott verziókezelő rendszer, tehát SVN-nel (és társaival) ellentétben nem egy központi szerveren van meg az egész *version history*, hanem (többnyire) lokálisan is megvan az egész repository. Rengeteg git parancs van, én csak a legfontosabbakat írom le (minden platformra van GUI is hozzá, nekem ezek nem túl szimpatikusak, sokkal hatékonyabb parancssorból buzgerálni mindent)
Kezdés
Üres repó létrehozása:
$ git init
Ha nem akarunk tökölni az mkdir project; cd project; git init
unalmas folyamattal:
$ git init project
Készen is vagyunk. Jöjjön a másik módszer (a gyakoribb), amikor egy létező repóhoz akarunk hozzáférni. Ezt hívjuk klónozásnak.
$ git clone https://foo.bar/baz.git
Ez a parancs az aktuális könyvtárban csinál egy baz mappát, oda pedig mindent szépen letölt. Ha nem tetszik a baz, utolsó paraméterként odabiggyeszthetjük a célkönyvtár nevét (pl .-ot, ha az aktuális könyvtárba szeretnénk létrehozni a repót)
Kultúráltak vagyunk, úgyhogy konfigoljuk be a gitet:
$ git config --global user.name "Gipsz Jakab" $ git config --global user.email gipsz@jakab.com
Aki nem szereti a vim editort (az bizony meleg!), az beállíthajta, mivel szeretné a commitokat szerkeszteni:
$ git config --global core.editor emacs
Emacs helyett persze mást is lehet én windowson notepad++-t szoktam használni (ha panaszkodik az elérési útra windowson, akkor az idézőjelekkel kell babrálni: "'C:/npp/npp.exe' -multiInst -nosession"). De egyébként ne használjunk windowst, nagyon gáz.
Hozzáadás
Ha csinálunk egy új fájlt/mappát, az alapból nem lesz verziókezelve, ez meg is nézhetjük a status parancs segítségével:
$ touch README $ git status # Untracked files: # (use "git add <file>..." to include in what will be committed) # # README nothing added to commit but untracked files present (use "git add" to track)
A git le is lövi a poént, az add parancs fájlokat/mappákat ad hozzá a következő commithoz (akárhányat)
$ git add README
Mostmár a rendszer látja a fájlt, de még nincs benne a repóban, committolni kell.
$ git status # Changes to be committed: # (use "git rm --cached <file>..." to unstage) # # new file: README
Ezt a commit parancs el is végzi nekünk...
$ git commit
Nagyon fontos dolgunk van, mégpedig írni egy commit üzenetet. Fontos, hogy világos, érthető legyen, később is lehessen tudni, miért történt az a változtatás. Ha nem tetszik az alap szövegszerkesztő, akkor be tudunk állítani sajátot, vagy rögtön a parancs mellet az -m kapcsolóval meg is írhatjuk az üzenetet.
$ git commit -m "Initial commit"
Nem kell mindig egyesével hozzáadni a commithoz a fájlokat, az -a kapcsoló automatikusan minden változást bevesz (az új fájlokat még mindig nekünk kell fölvenni!) Ha nem vagyunk biztosak benne, mi kerül a commitba, a --verbose kapcsoló a commit üzenet megadásakor az egész diffet berakja (diff=előző és mostani változat közötti különbség)
Villámgyors alias: $ git config --global alias.civ "commit --interactive --verbose"
, ezek után a $ git civ
egy kényelmes szöveges menüt ad nekünk, ahol kényelmesen összerakhatjuk a kommitot.
Elkúrás
Mi van, ha elkúrtam az üzenetet, és már commitoltam? Semmi gond, lehet szerkeszteni:
$ git commit --amend
Az -m kapcsoló használható természetesen.
Mi van, ha nem az utolsó kommit rossz? Akkor egy kicsit nehezebb dolgod van, de semmi gond: $ git rebase -i xxx
ahol xxx a rossz kommit szülője. Kapunk egy editort, ahol szépen fel vannak sorolva a kommitok, ezt lehet bántani, átrendezni, kommitokat egybeolvasztani, stb. Ha kulturáltan akarunk fejleszteni (ilyen elég ritkán fordul elő sajnos), akkor mielőtt feltöltenénk a szerverre a változtatásokat, előtte tegyük rendbe a kommitokat.
Mi van, ha szar az egész commit? A reset pont jól fog jönni:
$ git reset --soft HEAD~
Kis magyarázat. A commitok jönnek szép sorban, az utolsó commit az ágon a HEAD, a ~ jel a HEAD szülője lesz (~2 nagyszülő, satöbbi)
A --soft kapcsoló pedig azt fogja csinálni, hogy csak a HEAD mutatót helyezi át. Nem fog fájlokat módosítani, nem bántja a fájlokat, amiket hozzáadtunk a commithoz (add)
Kicsit drasztikusabb változat:
$ git reset --mixed HEAD~
Ez megcsinálja ugyanazt, mint a --soft, de a commithoz hozzáadott fájlokat (hívjuk indexnek ezután, mert ez a neve) is visszaállítja a mutatott commitra. Ha nem adunk meg a resetnek semmilyen kapcsolót, akkor ezt csinálja alapból.
Még félelmetesebb a
$ git reset --hard HEAD~
Ez mindent visszaállít, ténylegesen a fájlokat is! Szóval csak óvatosan.
Fejlesztési ágak
Eddig a commitok szép sorban jöttek egymás után, viszont nagyobb projecteknél ez nem igazán jó ötlet, célszerű a fejlesztést ágakra lebontani. Erre van megoldás a gitben:
$ git branch feature
A "feature" az ág neve, amit létrehozunk. A gyökere az aktuális commit. De még nem használjuk, szóval ezt is meg kell mondani:
$ git checkout feature
Vagy a kettő egyben:
$ git checkout -b feature
Ezzel elhagyjuk az eredeti fejlesztési ágat (alapból a fő ág a "master"), és átlépünk a "feature" ágra. Itt commitolhatunk kedvünkre, satöbbi. Sőt, még további ágakat is létrehozhatunk. Ha egy kicsit elvesztünk, hogy most milyen ágon is vagyunk, akkor simán a git branch megmondja egyrészt milyen ágaink vannak, másrészt megmondja melyiken is vagyunk (csillag van a neve előtt)
Ha kész a fícsör lefejlesztése, szeretnénk visszavezetni a főágba a változásokat. Erre lesz jó a félelmetes merge:
$ git checkout master $ git merge feature $ git branch -d feature
Először visszaváltunk a főágra. Aztán összeolvasztjuk a két ágat. Majd töröljük a feature ágat. Sajnos irtkán ilyen szép az élet, néha a git nem tudja magától megmondani, hogy mit honnan szedjen, többen szerkesztették ugyanazt a fájlt. Ilyenkor conflict van. Ezeket manuálisan kézzel kell kijavítani, elmenteni a fájlokat, majd commitolni manuálisan (a merge ugyanis egy commit).
Ha nagy mázlink van, és a master ágon senki sem fejlesztett, amíg mi a branchon bűvészkedtünk, akkor a merge helyett fast-forward történik, a head egyszerűen előreugrik (képzeljétek el az ágakat, mint függőleges vonalak, a commitok bogyók, elég jól lehet látni, miért is lehet ezt megtenni). Szóval ennek örülünk :)
Remote
Távoli repóba is jó ha mentünk, ilyeneket tud a github vagy a bitbucket (előbbi a preferált, illetve a menő).
Ha esetleg nem klónoztuk volna a repót, hanem initet használtunk, akkor hozzá kell adni a távoli repót a remote paranccsal:
$ git remote add origin https://foo.bar/baz.git
Az add hozzáad, az origin a neve, így fogjuk hívni ezután. Tiszta sor.
Le szeretnénk kérni a repó aktuális változatát:
$ git fetch
Ha több távoli repónk is van, akkor oda lehet írni a nevét is (alapból origin-nak hívják)
Ha szeretnénk az eddigi commitokat fenyomni a szerverre:
$ git push -u origin branch
Ahol origin a remote neve, branch az ág (pl master). Ez összeköti a lokális és távoli brancheket, szóval ezek után már később elég egy sima $ git push
.
Ha esetleg lesz rá időm, majd írok a githubos pull-request alapú workflow-ról, elég kúl cucc.
Hogy is volt?
Már mindent tudunk a gitről, csak azt nem, hogy hogyan is tudjuk visszanézni, mit csináltunk. Ezt többnyire a log parancs tudja szépen megmutatni:
$ git log
Kb mindent ki lehet vele deríteni, az -n kapcsoló a bejegyzések számát limitálja, a --since="2 weeks ago" az utolsó két hét commitjait mutatja, ha egy fájlnevet adunk meg a végén, akkor csak a rá vonatkozó commitok jelennek meg (ugyanez mappanév/ változattal mappára), az -S'foo()' azokat a commitokat jeleníti meg, amiben benne volt (eltűnt/megjelent) a foo(), --stat megmutatja mennyi sor változott.
Formázni is lehet, a --pretty=online pl egysoros változatban nyomja ki.
Kismillió kapcsolója van, itt meg lehet találni mindet: http://linux.die.net/man/1/git-log
A --graph grafikusan is megjeleníti a fejlesztési ágakat. Itt egy példa:
$ git log --graph --oneline --date-order * b450119 partial * 39d69f0 Merge branch 'exp' |\ * \ 2bf5367 Merge branch 'exp2' |\ \ * | | ab5a665 6 | * | 369d10b fb2 | * | 6db3ec6 fb1 | | * 0d726e6 fa4 | | * 5064725 fa3 | |/ | * 542c972 fa2 | * ad88635 fa1 |/ * d14df30 5 * be70310 4 * 21bb204 Merge branch 'feature' |\ * | b911d4f third | * 5e6acf2 feature6 | * 577f064 feature5 |/ * 37b0e0f feature4 * 662833a feature3
Mágikus, a fentihez hasonló nagyon trendi $ git lg
alias:
$ git config --global alias.lg "log --graph --date-order --all --pretty='%C(yellow)%h%Creset -%C(red)%d%Creset %s %Cgreen(a: %ar, c: %cr) %C(bold blue)<%an>%Creset'"
Utoljára maradt a blame, ami sorran lebontva jeleníti meg egy fájl utolsó szerkesztőit:
$ git blame file
Hasznos, ha tudni akarjuk ki kúrta el a fájlt :)
Bisect, stb egy kicsit ödvenszebb téma, érdemes elolvasni a git könyvet: http://git-scm.com/book
Megjegyzés
Az írás 2012 elejéről származik, azóta kicsit jobban belemélyedtem a gitbe, de szerintem a leírás még használható. lennon (vita) 2013. január 20., 02:26 (CET)
Egy kicsit kibővítettem, bár még így is elég rövid lennon(vita) 2014. február 9., 18:26 (UTC)