Hogyan használjuk a Git verziókezelő rendszert

A HupWiki-ből...

(Változatok közti eltérés)
(Debian GNU/Linux és Ubuntu)
a (typo)
290. sor: 290. sor:
  $ git clone --bare <project> <project>.git
  $ git clone --bare <project> <project>.git
-
  $ touch <project>.git/git/deemon-export-ok
+
  $ touch <project>.git/git-daemon-export-ok
  $ chmod +x <project>.git/hooks/post-update
  $ chmod +x <project>.git/hooks/post-update
  $ git --bar update-server-info
  $ git --bar update-server-info

A lap 2010. február 25., 08:58-kori változata

Tartalomjegyzék

Bevezetés

A leírás nem tér ki minden részletre, az megtalálható a hivatalos dokumentációban, vagy a szabadon elérhető könyvben. A cél csupán az átlagos felhasználáshoz szükséges műveletek, és az azt biztosító környezet kialakításának bemutatása.

Telepítés

Debian GNU/Linux és Ubuntu

A git régóta elérhető Debian és Ubuntu rendszerekben. A telepítése egyszerűen, az apt-get segítségével történik:

$ sudo apt-get install git-core git-doc git-svn

Archlinux

(Az extra repot engedélyezni kell)

$ pacman -S git 

Mac OS X és MacPorts

Az Apple által készített operációs rendszeren két lehetőségünk is van. Vagy letöltjük a git hivatalos oldaláról az általuk készített bináris csomagot, és azt telepítjük, vagy használjuk a MacPorts adta lehetőségeket. (Igény szerint természetesen Fink-et is lehetne használni).

Ha a MacPorts-ot választjuk, mert szeretnénk mi lefordítani a csomagot, akkor először érdemes a curl-t telepíteni külön, mivel a git is ezt fogja használni. A curl csomag alapértelmezésben SSL támogatás nélkül fordul le. Ez azért jelent számunkra problémát, mert így a későbbiek során nem tudunk https protokollon keresztül repository-t letölteni. (A port info curl parancs kiadásával láthatjuk, hogy milyen egyéb opciókkal fordíthatjuk még le a csomagot.)

$ sudo port install curl +ssl+doc 

Ezek után telepítsük fel a git csomagot. Érdemes ezt a három opciót választani, azt hiszem, a nevük magáért beszél. Ezen kívül még egy gitweb opció van. Mivel Mac OS X szervert nem üzemeltetek, így ennek a telepítését mellőzöm, mivel függőségként Apache-ot és minden mást is lefordítana.

$ sudo port install git-core +bash_completion+svn+doc

Mutatkozzunk be a git-nek

A következő két parancs segítségével beállíthatjuk a személyazonosságunk a rendszerben. Ez szükséges ahhoz, hogy a naplóban követhető legyen, ki mikor milyen műveletet végzett.

$ git config --global user.name "<név>"
$ git config --global user.email "<e-mail cím>"

A git használata

Az ezt követő szakaszokban bemutatásra kerülnek az alapvető funkciók, amik a mindennapi munka során fontosak lehetnek.

Az első projekt

A példa kedvéért hozzunk létre egy projektet, amin dolgozni fogunk. Ehhez először egy könyvtárat kell létrehozunk, és inicializálnunk benne a git-et. Ez fog megjelenni a log-ban is. Ezek után adjuk hozzá a könyvtárat, és indítsunk egy el commit-ot.

Mindez a gyakorlatban így történik:

$ mkdir project
$ cd project
$ (a fájlok szerkesztése, importálása)
$ git init
Initialized empty Git repository in /path/to/project/.git/
$ git add .
$ git commit
# On branch master
#
# Initial commit
#
nothing to commit (create/copy files and use "git add" to track)

Fájlműveletek

A következő néhány szakaszban bemutatásra kerülnek a fájlokkal végezhető alapműveletek, mint a létrehozás, módosítás, átnevezés vagy mozgatás, és a törlés.

Fájlok hozzáadása

A szemléltetéshez hozzunk létre egy README fájlt a touch parancs segítségével.

$ touch README

Nézzük meg mi történt most a tárolónkban. Ehhez használjuk a git status parancsot. Az eredmény:

$ git status
# On branch master
#
# Initial commit
#
# 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 rendszer fel is hívja a figyelmünket, hogy a fájl nincs hozzáadva a verziókezelésben szereplő fájlok csoportjához. Javasolja a git add parancs használatát. Engedjünk neki, majd nézzük meg, hogy mi is történt.

$ git add README 
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   README
#

Ezek után végezzünk el egy commit-ot, ahol megjegyzésként jelezzük a README fájl létrehozását:

$ git commit -m 'README fájl létrehozása'
[master (root-commit) 9b0f2d8] README fájl létrehozása
0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README

Fájlok módosítása

Ezek után nézzük meg, hogy mi történik akkor, ha beleírunk egy sort a frissen létrehozott fájlba.

$ echo "Egy sor" >> README 
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   README
#
no changes added to commit (use "git add" and/or "git commit -a")

Láthatóan a módosítás nem került automatikusan kijelölésre a következő commit-hoz. Használjuk most a javasolt -a kapcsolót:

$ git commit -a -m 'Minden változást rögzítünk'
[master 7afb0aa] Minden változást rögzítünk
 1 files changed, 1 insertions(+), 0 deletions(-)

Fájlok mozgatása és átnevezése

A shell-ből már jól ismert mv parancs segítségével történik. Példaként nevezzük át a README fájl nagybetűsről kisbetűsre:

$ git mv README readme
$

Ezek után ez látszik:

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	renamed:    README -> readme
#

Fájlok törlése

A fájlok törlése szintén ismert paranccsal történik:

$ git rm README
rm 'README'

Fájlok figyelmen kívül hagyása

Előfordulhat, hogy a verziókezelés alatt álló mappában nem akarunk minden fájlt kezelni. Ez például lehet akkor, ha olyan alkalmazást fejlesztünk, melyet konfigurálni kell a teszteléshez (például adatbáziskapcsolat-hozzáférés), és nem akarjuk ezt minden commit előtt szerkeszteni. Ehhez készítsünk egy sablon fájlt, amit verziókezelés alá vonunk, és egy használt példányt, melyre megadjuk, hogy hagyja figyelmen kívül a git. Ehhez hozzuk létre a projektünk gyökerében a .gitignore fájlt, és írjuk bele a következőket:

config/db.inc.php
*~

Ha megnézzük a git status kimenetét, akkor láthatjuk, hogy a fájl nem jelenik meg a változtatottak között.

Ezek után adjuk még a tárolónkhoz a .gitignore fájlt is:

$ git add .gitignore

Fájl változási naplója

Ha kíváncsiak vagyunk arra, hogy ki és mikor szerkesztett egy adott fájlt, akkor a git blame paranccsal tehetjük meg:

$ git blame <fájl neve>

Projekt műveletek

A következő néhány szakaszban a tárolókon végezhető műveletek kerülnek bemutatásra.

Tag létrehozás

A git lehetőséget ad arra, hogy egy-egy állapotot külön címkével láthassunk el. Ennek haszna, hogy bizonyos commit-ok után bejelölhetjük például, ha azt egy verziónak szánjuk. Használata az alábbi módon történik:

$ git tag <címke>

Például:

$ git tag v0.1

Fejlesztői ágak kezelése

Ha egy új funkciót szeretnénk implementálni kísérleti jelleggel, és ezt nem a fő ágban szeretnénk tenni, akkor könnyedén hozhatunk létre neki egy újat. Ehhez csak adjuk ki a következő parancsot.

$ git branch <új branch neve>

Ha lehagyjuk a paramétert, akkor a rendszer a létező fejlesztői ágakat fogja kilistázni, és az aktuálisan kiválasztott elé pedig *-ot helyez el.

Ha meg akarjuk változtatni az aktuálisan munkára használt ágat, akkor a git checkout parancsot kell használnunk:

$ git checkout <kiválasztandó branch neve>

Ezek után, ha újra kiadjuk a git branch parancsot, akkor látjuk, hogy a csillag átkerült.

Összeolvasztás

Ha már különböző ágakat hoztunk létre, akkor felmerülhet az igény azok összeolvasztására. Erre szolgál a git merge parancs. Először válasszuk ki, hogy melyik ágba szeretnénk beleolvasztani valamit, majd tegyük meg a beolvasztást. A gyakorlatban a következő módon zajlik:

$ git checkout master
$ git merge experimental

A fenti példában a főágba olvasztottuk bele az előzőleg létrehozott fejlesztői ágat.

A log szerkesztése

Ha például valamit kihagytunk a legutolsó commit-ból, vagy elgépeltünk valamit az üzenetben, akkor azt egyszerűen javíthatjuk.

$ git commit --amend

Ha visszamenőleg több commit-ot akarunk megváltoztatni, esetleg összevonni vagy törölni, akkor már kicsit összetettebb dolgunk van.

$ git rebase -i HEAD~<ennyivel korábbi verzió>
$ git rebase --continue
$ git rebase --skip
$ git commit --amend

Archívum készítés

Ha szeretnénk a tárolókból kinyerni egy változatot tömörített formában, akkor használhatjuk a git archive parancsot. Alapértelmezésben a tar formátumot használja, de támogatja még a zip-et is. A használatához meg kell adni, hogy melyik változatot szeretnénk exportálni. A következő példában az aktuális változat tömörítése látszik:

$ git archive --format=tar HEAD | bzip2 > ../<mai dátum>.tar.bz2

Hasznos lehet, ha például naponta szeretnénk snapshot-ot elérhetővé tenni.

Az exportálás során a git fájljai (kivéve a .gitmodules) nem kerülnek bele az archívumba.

Tároló visszaállítása egy adott verzióra

Előfordulhat, hogy a változtatások során valamint elrontunk, és inkább szeretnék visszaállni egy bizonyos állapotra. Ehhez használjuk a git reset parancsot az alábbi módon:

$ git reset --hard HEAD^

Távoli tárolók

Olyan esetek bemutatása, mikor mások számára is elérhető tárolókkal dolgozunk.

Helyi változat létrehozása

A gitben ezt nem checkoutnak nevezik, mint a Subversionnél, hanem klónozásnak. A korábbiakban a curl fordítása során ezért is volt szükség az ssl támogatás bekapcsolására. A letöltés a következő módon történik:

$ git clone <a tároló helye> [cél mappa]

Ha a git hibát jelez az SSL tanúsítvánnyal kapcsolat kapcsolatban, akkor tiltsuk le az ellenőrzését:

$ export GIT_SSL_NO_VERIFY=1

Helyi változat frissítése

Ha letöltöttünk egy tárolót valamely szerverről, és később szeretnénk az frissíteni az aktuális állapotra, akkor a git pull parancsot kell kiadnunk, amely nem igényel külön paramétereket. Tehát:

$ git pull [tároló] [branch]

Előfordulhat, hogy nem szeretnénk azonnal egybe is olvasztani a letöltött változatot az éppen aktuális lokálissal, akkor használjuk a következő parancsot:

$ git fetch [tároló] [branch]

Patch készítés

Ha letöltöttünk egy tárolót, és elvégeztük rajta az általunk kívánt módosításokat, akkor a patch kinyerésége a git diff parancsot kell használnunk. A gyakorlatban a következő módon:

$ git diff > patch.diff

Ha már végeztünk commit-ot a rendszerben, akkor erre a parancsra nem kapunk eredményt. Ekkor a diff-nek megadhatjuk, hogy melyik változathoz képest kérjük a módosításokat. Például az eggyel korábbi commit-hoz képest az alábbi módon kérhetjük:

$ git diff HEAD~1 > patch.diff

Ha több commit-ot is végeztünk, akkor a HEAD utáni számot kell módosítanunk.

Ezen kívül lehetőségünk van a tag-hez képest is változást lekérni, mint például:

$ git diff v0.1 > patch.diff

Tároló hozzáadása

Ha egy távoli tárolót szeretnénk hozzáadni, akkor csak egy azonosítót kell neki adnunk és egy elérési útvonalat:

$ git remote add <azonosító> <url>

Ezek után erre a címre hivatkozhatunk a megadott névvel git parancsainál, mint például a push-nál, a pull-nál, vagy a fetch-nél.

Távoli tároló létrehozása

Egy olyan esetben, ha mondjuk weben keresztül szeretnénk elérhetővé tenni az általunk készített tárolót, akkor a következőket kell tennünk:

$ git clone --bare <project> <project>.git
$ touch <project>.git/git-daemon-export-ok
$ chmod +x <project>.git/hooks/post-update
$ git --bar update-server-info
$ scp -r <project>.git <ssh://user@szerver/path/to/project.git>
$ cd <project>
$ git remote add <azonosító> <ssh://user@szerver/path/to/project.git>

Így, ha használjuk a git push parancsot, akkor fel tudjuk tölteni a távoli tárolóba a változtatásainkat.

Fájlok feltöltése

Ezek után töltsük fel a helyi változatot a

$ git push [branch neve]

parancs alkalmazásával. Ha esetleg itt is gondunk lenne az SSL tanúsítvánnyal, akkor próbáljuk meg alkalmazni a

$ git config http.sslverify false

beállítást.

Modulok használata

Vegyünk egy tipikus esetet, például a webfejlesztést. Ilyenkor előszeretettel használunk keretrendszereket. Ám az nem tűnik jó ötletnek, ha letöltjük őket, vagy esetleg csinálunk egy példányt helyi változatként, mert akkor elvesztjük a frissítés automatikus lehetőségét. Ekkor kiválóan használható a git submodule.

Először hozzunk létre egy könyvtárat, ahol tárolni fogjuk a modulokat. Ennek a leggyakoribb neve a vendor/. A hozzáadás az alábbi módon történik:

$ git submodule add <url> vendor/<könyvtár>

Ekkor létrejön egy az általunk kért könyvtár, amit a későbbiek során a saját kódunktól függetlenül így frissíthetünk:

$ cd vendor/<könyvtár>
$ git pull

Mi a teendő akkor, ha egy olyan tárolót töltünk le, ami modulokat használ? Csak az alábbi két parancsot kell kiadnunk, és a szükséges tárolókból mindjárt rendelkezni fogunk egy példánnyal:

$ git submodule init
$ git submodule update

Gitweb

A gitweb egy Perl-ben készített webes felület git tárolók böngészésére. Egyetlen állományból áll, mely CGI-ként fut az Apache-ban. Szükséges hozzá a mod_perl modul, valamint a fast_cgi lib.

A választásom azért erre az alkalmazásra esett, mivel szinte az összes rendszerhez megtalálható csomag formájában. Ezen kívül létezik még néhány webes böngésző alkalmazás githez, de közel sem ilyen elterjedtek.

A telepítéshez használjuk az apt-get parancsot:

$ apt-get install gitweb

Példaként pedig egy Apache2 konfiguráció, ami aldomainként teszi elérhetővé a tárolóinkat.

<VirtualHost *:80>
   ServerName git.<domain.hu>
   ServerAdmin postmaster@<domain.hu>
   ErrorLog /var/log/apache2/git-error.log
   CustomLog /var/log/apache2/git-access.log common
    
   DocumentRoot /path/to/git/repos

   ScriptAlias /index /usr/lib/cgi-bin/gitweb.cgi
   Alias /gitweb.css /usr/share/gitweb/gitweb.css
   Alias /git-logo.png /usr/share/gitweb/git-logo.png
   Alias /git-favicon.png /usr/share/gitweb/git-favicon.png

   Options Indexes FollowSymlinks ExecCGI
   DirectoryIndex index
</VirtualHost>

Apache2 + WebDav

Példaként az előzőleg létrehozott virtualhost-on engedélyezzük a git használatát WebDav-on keresztül. A klónozáshoz biztosítsunk lehetőséget bárki számára, az összes többi műveletet kössük felhasználói azonosításhoz. Ehhez a következőket adjuk hozzá az előző konfigurációs fájlhoz:

<Location /<tarolo.git>>
   DAV on
   AuthType Basic
   AuthName "git repos"
   AuthUserFile /etc/apache2/git.passwd
   <LimitExcept GET OPTIONS>
       Require valid-user
   </LimitExcept>
</Location>

Ezek után már csak létre kell hoznunk a felhasználókat tároló fájlt:

# htpasswd -c /etc/apache2/git.passwd <felhasználónév>

Ha még nem létezik a fájl, akkor létrehozza, ha pedig létezik, akkor felülírja. Ha azt szeretnénk, hogy csak a végére fűzze az új felhasználó adatait, akkor hagyjuk el a -c kapcsolót.

Személyes eszközök