Git

Z FI WIKI
Přejít na: navigace, hledání

Git je distribuovaný systém správy verzí zdrojového kódu. Tutoriál je dostupný na atlassian.com.

GitHub je veřejný webový hosting pro git repositories.

GitLab na FI MU je soukromý webový hosting pro git repositories, jde o instalaci software GitLab na FI MU.


Vytvoření repository

(tutoriál)

  1. pokud ještě nemáte, vytvořte si účet na GitHubu nebo v GitLabu na FI MU
  2. v jeho webovém rozhraní vytvořte novou repository, například https://github.com/pepa/test1 nebo https://gitlab.fi.muni.cz/pepa/test1
  3. stále ve webovém rozhraní vytvořte soubor README.md a něco do něj napište
  4. na příkazovém řádku oklonujte tuto repository příkazem git clone https://github.com/pepa/test1
  5. vstupte do adresáře s oklonovanou repository příkazem cd test1

V tomto okamžiku existuje soubor README.md třikrát:

  • v původní repository na GitHubu, budeme ji nazývat origin
  • v pracovním adresáři test1, budeme ho nazývat working copy
  • v lokální repository v adresáři test1/.git

Nastavení autora

Před tím, než provedete první commit, nastavte svoje jméno a emailovou adresu, podle které bude posuzováno autorství commitů (viz Setting your email in Git). Uděláte to příkazy

git config --global user.email "pepa@example.com"
git config --global user.name "Pepa Novak"

Toto nastavení je uloženo v souboru ~/.gitconfig.

Provedení změn

  1. libovolným editorem změňte obsah souboru README.md, změny jsou zatím jen ve working copy
  2. zaregistrujte změnu tohoto souboru do příštího commitu příkazem git add README.md
  3. proveďte commit zaregistrovaných změn příkazem git commit -m "edited README" kde parameter -m přidává zprávu ke commitu, teď je změna v lokální repository
  4. pošlete poslední commity z lokální repository do origin repository na GitHubu příkazem git push

Obecně editováním měníte soubory ve working copy, příkazem git add vytváříte seznam změn, které budou v příštím commitu (tzv. staging area), a příkazem git commit připravený seznam změn uložíte do lokální repository v adresáři .git jako určitý stav souborů nazývaný commit.

Výpis stavu

  • git status zobrazí rozdíly working copy oproti repository
  • git log vypíše seznam commitů v lokální repository
  • git log --oneline --abbrev-commit --all --graph --decorate --color vypíše hezky barevný seznam commitů
  • gitg --all spustí grafický klient pro prostředí Gnome zobrazující commity i všechny existující větve v lokální repository


Nastavení ignorovaných souborů

Ne všechny soubory ve working copy budeme chtít mít i v repository, a ani nebudeme chtít, aby nás git status na jejich existenci stále upozorňoval. Jde hlavně o soubory produkované vývojovými prostředími a kompilátorem.

Proto vytvoříme soubor .gitignore s následujícím obsahem:

.idea
.settings
.project
test-output
.classpath
*.iml
*~
target

který obsahuje seznam takových souborů a adresářů pro INtelliJ IDEA, NetBeans i Maven.

Tento soubor přidáme do repository příkazy git add .gitignore; git commit -m "added list of ignored files".

Commity, větve, tagy

Pokud jste postupovali podle návodu výše, máte teď repository v následujícím stavu (zobrazeno pomocí gitg):

Gitg 1.png

kde každý řádek v horní části zobrazuje jeden commit, jeho autora a čas vytvoření. Dolní část zobrazuje změny souborů obsažené ve zvoleném commitu.

Obdobný výpis lze získat i příkazem git log:

$ git log --oneline --abbrev-commit --all --graph --decorate --color
* 475479f (HEAD -> master) added list of ignored files
* cfc6828 (origin/master, origin/HEAD) edited README
* d8e181f Create README.md

Barevné obdélníčky označují tzv. větve (branches). Větev je pojmenovaný ukazatel na nějaký commit, který se automaticky posune, když vznikne následovník commitu.

V této ukázce označuje

  • HEAD ukazuje na současný commit v lokálním repository
  • master ukazuje na poslední commit ve výchozí větvi
  • origin/HEAD ukazuje na současný commit v origin repository (ze které lokální repository vznikla klonováním)
  • origin/master ukazuje na poslední commit výchozí větve v origin repository

Je vidět, že lokální repository je napřed o jeden commit oproti origin repository.

Vývoj nové funkce

Vývoj bychom měli dělat vždy v nové větvi, kterou později spojíme (merge) s větví master. Dejme tomu, že chceme začít psaním dokumentace v souboru REAME.md. Nejdřív vytvoříme novou větev příkazem

git checkout -b writing_docs

a provedeme několik commitů v této větvi. Stav repository pak vypadá třeba takto:

Gitg 2.png

Je to důsledek častého commitování. Před tím, než změny spojíme do větve master, bylo by vhodné trošku uklidit a spojit více commitů do jednoho, aby to vypadalo, že jsme celou práci na této větvi udělali naráz. Historii přepíšeme tak, že zadáme příkaz

git rebase -i master

který říká, že budeme chtít upravit všechny commity mezi ukazatelem master a HEAD. Zobrazí se editor se seznamem commitů:

pick 40cb59b wrote description
pick ddd9e23 added copyright year
pick 44ce228 some more edits
pick eb63f1b even more edits

# Rebase 475479f..eb63f1b onto 475479f (4 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit

Změníme všechna slova pick kromě prvního na squash:

pick 40cb59b wrote description
squash ddd9e23 added copyright year
squash 44ce228 some more edits
squash eb63f1b even more edits

uložíme, zavřeme editor a následně zvolíme nový popis nově vzniklého commitu. Historie pak bude vypadat takto:

Gitg 3.png

Sloučení do větve master

Před tím, než provedeme sloučení změn z větve writing_docs do větve master,musíme zjistit, zda některý jiný vývojář neprovedl změny ve větvi master. Přepneme se na větev master:

git checkout master

a přitáhneme změny:

git pull

Běda, jiný vývojář změny udělal, kolidují s naší změnou (přidání .gitignore), provedeme tedy merge. Výsledkem je nelineární struktura:

Gitg 4.png

Zkusíme teď sloučit writing_docs do master:

$ git merge writing_docs
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.

Došlo ke konfliktu v souboru README.md. Ten musíme naeditovat a uvést do stavu, ve kterém ho chceme mít, provedeme commit a push do vzdálené repository:

git add README.md
git commit
git push

Ve výsledku tak bude historie vypadat takto:

Gitg 5.png

Nyní lokální i vzdálená (origin) repository mají stejné větve master, které obsahují změny z lokální větve writing_docs. Teď můžeme smazat lokální větev writing_docs:

git branch -d writing_docs

Tag

Zatímco větev je pohyblivý ukazatel na poslední ze série commitů, tag je neměnný ukazatel na konkrétní commit. Označme třeba současný commit jako první vydání dokumentace projektu a pošleme tento tag do origin repository:

git tag -a "Doc_rel_1" -m "Documentation release 1"
git push --tags

Pak uvidíme tento tag jako vydání verze projektu na https://github.com/pepa/test1/releases a v historii projektu takto:

Gitg 6.png

Práce v týmu

GitHub umožňuje dva způsoby spolupráce v týmu:

  • sdílená repository
  • fork and pull

Pro malé týmy je vhodná jednodušší jedna sdílená repository, do které mohou zapisovat všichni zúčastnění vývojáři.

U větších týmů je vhodnější vytvořit jednu hlavní repository a určit jejího správce, ostatní vývojáři si vytvoří tzv. fork této repository, a nabízí změny ze své repository do hlavní repository ve formě tzv. pull request, správce je schvaluje.