* využití Gitu pro distribuovaný vývojový model, který je praktikován
mnoha open source projekty,
* efektivní prohledávání historie projektu, které je užitečné
- například při rozhodování, jak správně vyřešit určitý konflikt.
+ například při rozhodování, jak správně vyřešit určitý konflikt a
+* řešení konfliktů.
[git]:http://git-scm.com/
Úvod
====
-Git je velmi univerzální nástroj pro správu a synchronizaci dat
-v souborech. Kromě verzování softwaru ho lidé používají
-k [mnoha dalším činnostem][gitsurvey-usedfor]. Jedna z často
-zmiňovaných nevýhod Gitu je, že oproti jiným verzovacím systémům je
-těžší se ho naučit a používat. Možným důvodem je to, že git nabízí
-větší funkcionalitu než většina ostatních systémů, která se ale
-využije jen ve speciálních případech – například jen u extrémně
+Git je poměrně univerzální nástroj pro správu a synchronizaci dat
+v souborech. Kromě verzování softwaru ho lidé používají k mnoha dalším
+činnostem (viz [Git User's Survey 2012, otázka 8][gitsurvey]). Jedna
+z často zmiňovaných nevýhod Gitu je, že oproti jiným verzovacím
+systémům je těžší se ho naučit a používat. Možným důvodem je to, že
+git nabízí větší funkcionalitu než většina ostatních systémů, která se
+ale využije jen ve speciálních případech – například jen u extrémně
velkých projektů jako Linuxové jádro. Ať už to tak je, nebo ne, faktem
je, že Git se neustále vyvíjí a mnoho úsilí je věnováno právě zlepšení
uživatelské přivětivosti.
-[gitsurvey-usedfor]:http://www.survs.com/app/7/wo/GffJpx48NlVaG9rZZGKsI0/0.0.0.7.7.3.3.1.1.5.1.1.1.9.1
+[gitsurvey]:https://www.survs.com/results/QPESOB10/ME8UTHXM4M
Pro pochopení Gitu je důležité mít základní představu o tom, jak Git
pracuje s větvemi, což bylo popsáno v [[přednášce|prednasky/intro-to-git.pdf]]
* Příkaz `git gui` je grafický nástroj částečně nahrazující příkazy
`git status` a `git commit`. Pomocí menu je možné provádět i další
- operace jako např. vytváření větví a práce se vzdálenými repozitáři.
+ operace jako např. vytváření větví nebo pracovat se vzdálenými
+ repozitáři.
* Dále existuje ještě spousta dalších [nástrojů][tools]. Já osobně používám
kromě výše zmíněných příkazů ještě `tig` a `qgit`.
# misc/ext.d/doc.sh
# ...
no changes added to commit (use "git add" and/or "git commit -a")
- Vidíme, že pracujeme na větvi *master* a vzhledem k verzi uložené v
- repozitáři máme několik změněných souborů.
+
+ Vidíme, že pracujeme na větvi *master* a vzhledem k verzi uložené
+ v repozitáři máme několik změněných souborů.
[mc]:http://www.midnight-commander.org/
Nyní už by měl `git status` ukazovat že pracujeme s větví
*cviceni1*.
-4. Nyní provedeme *commit*:
+4. Provedeme *commit*, t.j. uložíme všechny naše změny do lokálního repozitáře:
git commit -a -m 'Zmeny z prvniho cviceni'
editor a nechá nás napsat zprávu v něm.
> *Poznámka:* Pokud vám nevyhovuje výchozí editor (většinou `vi`),
- > nastavte si, že chcete používat jiný editor (např. `pico`):
+ > nastavte si, že chcete používat jiný editor (např. `nano`):
>
- > git config --global core.editor pico
+ > git config --global core.editor nano
5. Nyní se přepneme zpět na větev *master*:
git fetch osp
V případě úspěchu bude výstup vypadat následovně:
- remote: Counting objects: 17, done.
- remote: Compressing objects: 100% (9/9), done.
- remote: Total 10 (delta 4), reused 7 (delta 1)
- Unpacking objects: 100% (10/10), done.
- From ssh://rtime.felk.cvut.cz/osp/mc
- * [new branch] master -> osp/master
- * [new branch] only-directories -> osp/only-directories
+ remote: Counting objects: 34, done.
+ remote: Compressing objects: 100% (17/17), done.
+ remote: Total 20 (delta 17), reused 6 (delta 3)
+ Unpacking objects: 100% (20/20), done.
+ From ssh://rtime.felk.cvut.cz/osp/mc
+ * [new branch] master -> osp/master
+ * [new branch] only-directories -> osp/only-directories
+ * [new branch] only-directories-old -> osp/only-directories-old
-3. Příkaz nám vypíše, že v repozitáři byly dvě nové větve. Všechny
+3. Příkaz nám vypíše, že v repozitáři byly tři nové větve. Všechny
větve ze vzdálených repozitářů vypíšeme příkazem
git branch -r
Tyto dva příkazy jsou ekvivalentní a vypisují commity, které jsou
ve větvi *osp/only-directories* a zároveň nejsou (^) ve větvi *master*.
- Chcete-li vidět i změny v kódu použijte jeden z následujících příkazů:
+ Chcete-li vidět i změny v kódu (patch) použijte jeden
+ z následujících příkazů:
git log -p osp/only-directories ^master
- gitk osp/only-directories ^master
+ gitk osp/only-directories ^master
+
+ Výše uvedené příkazy zobrazují změny provedené jednotlivými
+ commity. Pokud nás zajímá celková změna bez rozdělení na jednotlivé
+ committy, pomůže nám příkaz `git diff`:
+
+ git diff master..osp/only-directories
+ git diff master osp/only-directories
+
+ První příkaz zobrazí změny, které obsahuje verze *only-directories* a
+ nejsou ve větvi master. Druhý příkaz zobrazí kompletní rozdíl, tj.
+ i změny, které jsou ve větvi *master* a ne v *only-directories*.
6. Podobně můžeme postupovat i s původním repozitářem. Jméno *origin*
je výchozí a proto ho nemusíme zadávat:
-----------------------
Operace slučující dvě a více větví do jedné se nazývá *merge*. V Gitu
-Můžou při slučování nastat tři situace:
+můžou při slučování nastat tři situace:
* *Already up-to-date* je situace, kdy už je větev, kterou chceme
sloučit, dosažitelná z aktuální větve (už byla sloučena v
* Vzdáme to a vrátíme se k verzi před slučováním
- git reset --hard
+ git merge --abort
* Konflikt vyřešíme a oznámíme to gitu příkazy `git add` a `git
commit` (jak nám git napovídá v hláškách)
V průběhu řešení konfliktu je užitečné používat příkaz `git status`,
-Abychom zjistili, co je ještě potřeba vyřešit. V našem případě vypadá
+abychom zjistili, co je ještě potřeba vyřešit. V našem případě vypadá
výstup zhruba takto:
- # On branch homework
- # Changes to be committed:
- #
- # modified: doc/man/mc.1.in
- #
- # Unmerged paths:
- # (use "git add/rm <file>..." as appropriate to mark resolution)
- #
- # both modified: src/filemanager/find.c
+ On branch homework
+ You have unmerged paths.
+ (fix conflicts and run "git commit")
+
+ Changes to be committed:
+
+ modified: doc/man/mc.1.in
+
+ Unmerged paths:
+ (use "git add <file>..." to mark resolution)
+
+ both modified: src/filemanager/find.c
Konflikt lze řešit následujícími způsoby:
jednotlivé konfliktní oblasti. Tato místa musíme opravit tak, aby
kód dával smysl a poté zmíněné sekvence znaků smažeme.
* Použijeme příkaz `git mergetool`, který spouští grafický nástroj
- (např. [kdiff3][kdiff3]), který nám se slučováním pomůže.
+ (např. [kdiff3][kdiff3] nebo `meld`), který nám se slučováním
+ pomůže.
`kdiff3` vedle sebe zobrazuje 3 různé verze projektu: poslední
- společná verze (base), verzi z větve před slučováním (local) a verzi
- ze slučované větve (remote), tj. té uvedené jako parametr v příkazu
- `git merge`.
+ společnou verzi (base), verzi z větve před slučováním (local) a
+ verzi ze slučované větve (remote), tj. té uvedené jako parametr
+ v příkazu `git merge`.
Ve spodní části obrazovky je pak vidět výsledek slučování, který
můžeme měnit buď přímou editací a nebo výběrem jednotlivých verzí
zobrazí pouze commity, které modifikovaly konfliktní soubory.
Jednoduše tam můžeme zjistit, které změny konflikt způsobily.
+Git obsahuje poměrně jednoduchý algoritmus (v porovnání s jinými
+verzovacími systémy) pro slučování různých verzí souborů. Některým
+studentům se to nelíbí a stěžují si. Přečtěte si
+[názor Linuse Torvaldse][mergealg], proč tomu tak je.
+
+[mergealg]:http://stackoverflow.com/questions/612580/how-does-git-solve-the-merging-problem/612747#612747
+
[kdiff3]:http://kdiff3.sourceforge.net/
Repozitář na GitHubu
Pro účely tohoto cvičení si [založte fork][forkmc]
[Midnight commanderu][osp-mc]. Do takto vytvořeného repozitáře pak
- nahrajete úkol z dnešního cvičení.
+ nahrajete vypracovaný úkol z dnešního cvičení.
3. Do svého repozitáře na GitHubu nahrajete větev z lokálního
repozitáře některým z těchto způsobů:
- git push https://github.com/<mujlogin>/mc.git homework
+ git remote add github https://github.com/<mujlogin>/mc.git
+ git push github HEAD:homework
nebo
- git push ssh://git@github.com/<mujlogin>/mc.git homework
+ git push https://github.com/<mujlogin>/mc.git homework
nebo
- git remote add github https://github.com/<mujlogin>/mc.git
- git push github homework
+ git push ssh://git@github.com/<mujlogin>/mc.git homework
[new]:https://github.com/new
[osp-mc]:https://github.com/CTU-OSP/mc
[forkmc]:https://github.com/CTU-OSP/mc/fork
+
Zadání
======
Proveďte sloučení větve `ssh://git@rtime.felk.cvut.cz/osp/mc
only-directories` s aktuální vývojovou větví Midnight Commanderu
-(`origin/master`). Výsledek musí jít zkompilovat a musí nabízet
+(`origin/master`). Výsledek musí jít zkompilovat a musí obsahovat
funkcionalitu přidanou do větve `only-directories`. Výsledek uložte do
[vámi vytvořeného repozitáře (forku) na GitHubu][forkmc] do větve
`homework`.