Git

Z GeoWikiCZ
Skočit na navigaci Skočit na vyhledávání

When I say I hate CVS with a passion, I have to also say that if there any SVN users (Subversion users) in the audience, you might want to leave. Because my hatred of CVS has meant that I see Subversion as being the most pointless project ever started, because the whole slogan for the Subversion for a while was 'CVS done right' or something like that.
--- Linus Torvalds

Git je distribuovaný systém pro správu verzí (software pro správu zdrojových kódů projektů). Git byl původně vytvořen Linusem Torvaldsem pro vývoj jádra Linux, dnes je spravován Junion Hamanem. Git je svobodný softare šířený pod GPL licencí verze 2.

Instalace

Pro Debian GNU/Linux

apt-get install git-core

Další doplňující balíčky jsou git-cvs, git-svn, git-daemon-run, git-gui, gitk a gitweb.

Poznámky pro uživatele MS Windows zde.

Vytvoření repozitáře

Nový prázdný git repozitář vytvoří příkaz

git init [--bare]

Git repozitář můžeme vytvořit pro existující projekt, například

cd /cesta/k/mému/projektu
git init                            (1)
git add .                           (2)

kde (1) vytvoří /cesta/k/mému/projektu/.git adresář a (2) přidá do projektu všechny existující soubory z běžného adresáře (symbol tečka).

Git může být takto používán i pro lokální projekty na kterých pracuje jediný uživatel.

Parametr --bare zajisti vytvoreni prazdného repozitáře, do kterého chceme (například) následně uložit repozitář z jiného počítače příkazem

git push origin master

Naklonování repozitáře

Repozitář, který máme přístupný přes ssh naklonujem příkazem git clone, například

git clone git@josef.fsv.cvut.cz:sandbox.git

URL vzdáleného repozitáře/repozitářů vypíšeme příkazem

git remote -v

Pracovní cyklus

Před samotnou prací s Gitem je vhodné nastavit minimální metadata, např.

git config user.name "Martin Landa"
git config user.email "martin.landa@fsv.cvut.cz"
git config core.editor "emacs"

Před modifikací dat v repozitáři je vždy vhodné aktualizovat jeho lokální kopii.

git pull

Před nahráním změn do repozitáře může být užitečné vypsat seznam těchto změn

git status

anebo jejich přehled.

git diff
Přidání souboru/adresáře

Přidání adresáře (rekurzivně) či souboru.

git add <soubor>
Odebrání souboru/adresáře
git rm <soubor>
Přejmenování souboru/adresáře
git mv <soubor> <soubor1>
Nahrání změn do repozitáře

Nahrání změn do lokálního repozitáře.

git commit -am "logovaci zprava"

Nahrání změn do vzdáleného repozitáře.

git push

Příklad

Přidání souboru.

git pull
git add Makefile
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   Makefile
#
git commit -am "soubor Makefile"
git push

Modifikace souboru.

git pull
emacs Makefile
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:   Makefile
#
no changes added to commit (use "git add" and/or "git commit -a")
git diff
diff --git a/Makefile b/Makefile
index 5fe6f05..af4dff4 100644
--- a/Makefile
+++ b/Makefile
@@ -5,3 +5,10 @@ default: pdf
 
 pdf:
        $(PDFLATEX) $(FILE).tex
+
+clean:
+       rm -f *.aux *.toc *.log
+
+distclean:
+       make clean
+       rm -f $(FILE).pdf
git commit -am "Makefile: clean & distclean"
git push

Odstranění souboru.

git rm Makefile
git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    Makefile
#
git commit -am "Makefile odstranen"
git push

Správa větví

Jeden git repozitář může udržovat více vývojových větví (branches). Pro vytvoření větve se jménem "experimentalni" zadáme příkaz

$ git branch experimentalni

Jestliže následně zadáme příkaz

$ git branch

získáme výpis všech lokálních větví.

  experimentalni
* master

Kde "experimentalni" je jméno právě vytvořené větve a "master" je implicitní automaticky vytvořená větev. Hvězdička označuje větev, ve které se právě nacházíme. Pro přechod k jiné větvi zadáme

$ git checkout experimentalni

Pro výpis větví umístěných na vzdáleném serveru použijeme přepínač -r.

$ git branch -r
  origin/2006-2010
  origin/HEAD
  origin/master
  origin/origin

Sledování vzdálené větve docílíme příkazem

$ git branch 2006-2010 origin/2006-2010

a do větve "2006-2010" se přepneme

$ git checkout 2006-2010

Alternativně

$ git checkout --track -b origin/2010-2011

Pro odstranění vzdálené větve poslouží příkaz

$ git push origin :2006-2010

Pro sloučení experimentalni větve s master zadáme

$ git commit -a    # v experientalni vetvi
$ git checkout master
$ git pull . experimentalni

Uložení běžné větve do vzdáleného repozitáře

$ git push origin HEAD

Další příklad:

git branch demo-klonovani

git push origin demo-klonovani
Total 0 (delta 0), reused 0 (delta 0)
To git@geo102.fsv.cvut.cz:gamalite.git
 * [new branch]      demo-klonovani -> demo-klonovani

git branch -r
  origin/HEAD -> origin/master
  origin/demo-klonovani
  origin/master

Zrušení větve ve vzdáleném repozitáři

Zrušení je jednoduché

$ git push origin :jméno-větve

větev je nutno ještě zrušit v lokální kopii

$ git branch -d jméno-větve

Příklad zrušení větve, která nebyla plně zapojena zapojena (merge), pro lepší čitelnost jsou jednotlivé příkazy odděleny prázdným řádkem.

$ git push origin :dbtout-v2
To git@geo102.fsv.cvut.cz:gamalite.git
 - [deleted]         dbtout-v2

$ git branch -d dbtout-v2
error: The branch 'dbtout-v2' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dbtout-v2'.
 
$ git branch -D dbtout-v2
Deleted branch dbtout-v2 (was b5d8d71).
$

Obnova předchozího stavu

$ git reset HEAD^ --hard
$ git push -f

Uvedené dva příkazy zruší poslední commit ve vzdáleném repozotář a obnoví původní stav.

Tipy

Ignorované soubory

Soubory, které si přejete, aby Git ignoroval např. při git status uvádějte v souboru '.gitignore'. Např.

cat .gitignore

*.aux
*.log
*.toc
git add .gitignore
git commit -am "seznam ignorovanych souboru"
git push

Expanze proměnných

Git narozdíl od SVN či CVS nepodporuje tvz. vlastnosti, např. svn:keywords. Následuje příklad pro aktivaci $Date$.

git config filter.rcs-keyword.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
git config filter.rcs-keyword.smudge 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date: `date`\\\$/"'
echo 'index.html filter=rcs-keyword' >> .gitattributes
git add .gitattributes 
git commit -am"+gitattributes"
git push
rm index.html
git checkout index.html

Jak vypsat jména změněných souborů

Pro výpis jmen souborů, které byly změněny mezi dvěma revizemi jednoduše zadáme

$ git diff --name-only foo bar

kde foo je jedna revize a bar druhá revize.

Obnova souboru v pracovní kopii

Obnova souboru foo na revizi HEAD

$ git checkout foo

obnova na předchozí revizi

$ git checkout HEAD^ foo

atd.

Obnova nechtěně zrušených souborů

Zrušené soubory zobrazíme příkazem

git ls-files -d

pro jejich obnovení stačí zadat

git ls-files -d | xargs git checkout --

Odstranění adresáře/souboru včetně historie

git filter-branch umožňuje odstranění adresáře či souboru z repozitáře včetně veškeré historie.

export OBJ="adresar"
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $OBJ" HEAD
rm -rf .git/refs/original/ && git reflog expire --expire=0 --all && git gc --aggressive --prune=0

Nebo pro starší verze gitu

rm -rf .git/refs/original/ && git reflog expire --expire=0 --all && git repack -adf --window=250 --depth=250

Přehled změn v repozitáři

Přehled změn (včetně logu) lze vypsat pomocí příkazu git whatchanged. Např.

za poslední tři dny

git whatchanged --since="3 day ago" -p --

či k určitému časovému okamžiku

git whatchanged --since="2010 July 31" -p --

Změna remote origin

git config remote.origin.url git@geo.fsv.cvut.cz:landa/web

Přechod na Git

Převod CVS repozitáře na git

Přihlásíme se pomocí ssh na server s CVS repozitářem a pomocí příkazu git import vytvoříme git kopii. Tato operace může chvíli trvat, protože jsou převáděny všechny verze souborů uložené na CVS.

ssh gin@josef.fsv.cvut.cz
git cvsimport -v -d /home2/gin/cvsroot -C git gin

Na svém počítači vytvoříme klon nového git repozitáře.

git clone gin@josef.fsv.cvut.cz:/home2/gin/git

V adresáři git (jméno adresáře použité v naší ukázce) změníme jeden soubor, zobrazíme diff a uložíme změny v lokální kopii.

cd git
edit README
git diff
git commit -a

Pro uložení změn v hlavním repozitáři musíme použít příkaz git push.

Příklad
git cvsimport -v -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/sqltutor \
              -C sqltutor sqltutor

Převod SVN repozitáře na git

Postup pro Git >= 1.5
mkdir geoinformatics-fce-ctu
cd geoinformatics-fce-ctu
git-svn init file:///var/lib/svn/geoinformatics-fce-ctu --no-metadata
git config svn.authorsfile ../authors
git-svn fetch
cd ..

git clone --bare geoinformatics-fce-ctu geoinformatics-fce-ctu.git

Příklad skriptu:

#!/bin/sh

if test -z "$1"; then
    echo "Usage: $0 repo"
    exit 1
fi

repo=$1

mkdir $repo
cd $repo
git-svn init file:///var/lib/svn/$repo --no-metadata
git config svn.authorsfile ../authors
git-svn fetch
git-svn create-ignore
git commit -am"Adding .gitignore files"
cd ..

git clone --bare $repo ${repo}.git

rm -rf $repo

exit 0
Postup pro Git < 1.5

Převod SVN repozitáře na Git se provede pomocí příkazu git svnimport (součást balíčku 'git-svn'). Příklad:

git svnimport -r -v -C landa-ds -I .gitignore -T "" -A authors file:///home2/vs/svn/landa-ds
git clone --bare landa-ds landa-ds.git
rm -rf landa-ds

Poznámka pro SVN repozitáře bez trunku.

Příklad souboru authors.

cat authors 
landa = Martin Landa <martin.landa@fsv.cvut.cz>

Veřejný přístup k repozitáři (read-only)

Protokol http

Zprovoznění

cd /var/www
mkdir gitpub
ln -s /home/git/repositories/sqltutor-datasets.git gitpub/
cd /home/git/repositories/sqltutor-datasets.git
git --bare update-server-info
cd hooks
mv post-update.sample post-update
chmod a+x post-update

Protokol git

Příklad

git clone git://geo.fsv.cvut.cz/sqltutor-datasets.git

Instalace

apt-get install git-daemon-run

Nastavit `base-path` v souboru `/etc/sv/git-daemon/run` a restartovat

sv restart git-daemon

Veřejně dostupné repozitáře musí obsahovat soubor `git-daemon-export-ok`

touch sqltutor-datasets.git/git-daemon-export-ok

anebo lépe pomocí Gitolite

	repo    sqltutor-datasets
		R       =   daemon

Příklad konfigurace fireholu

interface any world
    server custom git tcp/9418 any accept

Git (nejen) pro MS Windows

  • Git pro Mac OS X, Windows, Linux nebo Solaris nainstalujte z http://git-scm.com/downloads
  • Při instalaci zaškrtněte "GIT Bash Here" a "GIT GUI Here", zbytek ponechte ve výchozím nastavení
  • Spustit
    • Start -> Programy -> GIT Bash pro příkazovou řádku
    • Start -> Programy -> GIT GUI pro grafické rozhraní
Git na MS Windows (Git Bash & Git GUI)

Více informací na adrese na wiki GitHub. Příkazová řádka GIT Bash mimo jiné umožňuje pod Windows používát základní příkazy pro manipulaci s adresáři a soubory na které jsou zvyklí uživatelé Linuxu.

Submoduly

Příklad práce se submoduly, více na [1], [2].

#!/bin/sh

DIR=~/smetiste/git

rm    -rf $DIR
mkdir -p  $DIR
mkdir -p  $DIR/private
mkdir -p  $DIR/public

# vytvoreni submodulu 'truhlar' a 'novak'
for student in truhlar novak; do
    mkdir $DIR/private/$student
    cd    $DIR/private/$student
    git init
    echo "module $student" > $student.txt
    git add $student.txt
    git commit -m "Initial commit, module $student"
    git clone --bare . $DIR/public/$student.git
    git remote add origin $DIR/public/$student.git
    cd ..
done

# vytvoreni repozitare 'bc'
mkdir $DIR/bc
cd $DIR/bc
git init
echo "Bakalarske prace" > Readme.txt
git add Readme.txt
git commit -m "Initial commit of empty superproject"
git clone --bare . $DIR/bc.git
git remote add origin $DIR/bc.git

# pridani submodulu 'truhlar' a 'novak' do repozitare 'bc'
cd $DIR/bc
for student in truhlar novak; do
    git submodule add $DIR/public/$student.git $student
done
ls -a

git commit -m "Add submodules"
git push
git submodule init

cd $DIR
git clone $DIR/bc.git bc2
cd $DIR/bc2
git submodule status
git submodule init
git submodule update
ls -la

Aktualizace všech submodulů

git submodule foreach git pull

Související články

Související:

Odkazy