]> rtime.felk.cvut.cz Git - edu/osp-wiki.git/blobdiff - cviceni/4.mdwn
Minarik Jaroslav -- git test (nahradni termin)
[edu/osp-wiki.git] / cviceni / 4.mdwn
index da827f9f9537b4add56b2e4802b28ac58cb28a85..efbb692063d881562cd66e00f75841d8a78fe13f 100644 (file)
@@ -12,7 +12,8 @@ Konkrétně nás bude zajímat:
 * 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/
 
@@ -66,15 +67,15 @@ Postup
 1. Základní nastavení. Aby vaše commity obsahovaly správné údaje o
    vás, nastavte si jméno a email:
 
-        git config --global user.name "Your Name Comes Here"
-        git config --global user.email you@yourdomain.example.com
+       git config --global user.name "Your Name Comes Here"
+       git config --global user.email you@yourdomain.example.com
 
 
 
 1. Předpokládáme, že máte zdrojové kódy midnight commanderu někde na
    disku, takže se přesuňte do adresáře s nimi.
    
-        cd ~/mc
+       cd ~/mc
 
 Lokální větve
 -------------
@@ -83,60 +84,38 @@ Lokální větve
    jí do nové větve *cviceni1*. Nejprve se ale podíváme v jakém stavu
    máme zdrojové kódy:
 
-        git status
+       git status
    Dostaneme něco jako:
    
-        # 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:   po/az.po
-        #      modified:   po/be-tarask.po
-        #      modified:   po/be.po
-        #       ...
-        #      modified:   src/cmddef.h
-        #      modified:   src/main.c
+       # On branch master
+       # Changes not staged for commit:
+       #   (use "git add <file>..." to update what will be committed)
+       #   (use "git checkout -- <file>..." to discard changes in working directory)
+       #
+       #       modified:   lib/keybind.h
+       #       modified:   src/filemanager/midnight.c
+       #
+       # Untracked files:
+       #   (use "git add <file>..." to include in what will be committed)
+       #
+       #       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ů.
 
 [mc]:http://www.midnight-commander.org/
 
-1. Midnight commander má bohužel jednu vlastnost, která může ztížit
-   vaše začátky s gitem. Při kompilaci dojde k automatickému
-   přegenerování některých souborů v repozitáři a git potom hlásí, že
-   jsme tyto soubory změnili a "otravuje" s nimi při každém commitu.
-   
-   Naštěstí existuje možnost jak gitu říct, že nás změny v některých
-   souborech nezajímají: 
-   
-        git update-index --assume-unchanged $(git ls-files po m4)
-
-   Příkaz `git ls-files po m4` vypíše všechny soubory z adresářů *po*
-   a *m4*, které jsou spravované gitem a příkazem `git update-index
-   --assume-unchanged` pak gitu sdělíme, aby si do indexu poznamenal,
-   že má tyto soubory ignorovat.
-   
-   > *Poznámka:* Možná víte o souborech *.gitignore* (viz `man
-   > gitignore`), které slouží k podobnému účelu. Ostatně midnight
-   > commander je také využívá, jak se můžete snadno přesvědčit:
-   >
-   >     cat .gitignore
-   >
-   > Soubory *.gitignore* se ale vztahují pouze na soubory, které
-   > ještě nejsou součástí repozitáře, což není případ výše zmíněných
-   > souborů.
-
 3. Vytvoříme větev *cviceni1* a přepneme se na ni:
 
-        git checkout -b cviceni1
+       git checkout -b cviceni1
 
    Nyní už by měl `git status` ukazovat že pracujeme s větví
-   *cviceni1* a vidíme pouze námi modifikované soubory.
+   *cviceni1*.
 
 4. Nyní provedeme *commit*:
 
-        git commit -a -m 'Zmeny z prvniho cviceni'
+       git commit -a -m 'Zmeny z prvniho cviceni'
        
    Parametrem `-a` říkáme, že "commitujeme" vše (all) a `-m` udává
    komentář ke commitu (message). Kdybychom `-m` vynechali, git spustí
@@ -145,28 +124,28 @@ Lokální větve
    > *Poznámka:* Pokud vám nevyhovuje výchozí editor (většinou `vi`),
    > nastavte si, že chcete používat jiný editor (např. `pico`):
    > 
-   >      git config --global core.editor pico
+   >     git config --global core.editor pico
 
 5. Nyní se přepneme zpět na větev *master*:
 
-        git checkout master
+       git checkout master
    V adresáři se vám teď objeví verze bez vašich úprav z 1. cvičení.
 
 6. Seznam větví v našem repozitáři zjistíme příkazem
 
-        git branch
+       git branch
    Aktuální větev je označena hvězdičkou `*`.
    
 Práce s více vzdálenými repozitáři
 ----------------------------------
 
-Do teď jsme pracovali pouze s jedním vzdáleným repozitářem. Mezi velké
+Doposud jsme pracovali pouze s jedním vzdáleným repozitářem. Mezi velké
 výhody gitu (a ostatních distribuovaných verzovacích systémů) patří
 schopnost pracovat s více vzdálenými repozitáři.
 
 1. Které vzdálené repozitáře máme nakonfigurované zjistíme pomocí
    
-        git remote -v
+       git remote -v
 
    Vidíme, že máme nakonfigurovaný repozitář s názvem *origin* a jeho
    URL.
@@ -175,10 +154,10 @@ schopnost pracovat s více vzdálenými repozitáři.
    vyplatí se ho pojmenovat krátkým jménem (v příkladu níže *osp*),
    abychom nemuseli pořád psát dlouhé URL:
    
-        git remote add osp ssh://git@rtime.felk.cvut.cz/osp/mc
+       git remote add osp ssh://git@rtime.felk.cvut.cz/osp/mc
 
    V tomto repozitáři je uloženo zadání dnešní úlohy. Abyste se k němu
-   dostali, musí server znát váš veřenjný SSH klíč. Jak toho docílit
+   dostali, musí server znát váš veřejný SSH klíč. Jak toho docílit
    najdete na [[samostatné stránce|rtime-git-ssh-key]]. Přístup k
    repozitářům na serveru rtime budete potřebovat i v písemce. **Proto
    vám důrazně doporučujeme zprovoznit přístup už na tomto cvičení,
@@ -186,43 +165,45 @@ schopnost pracovat s více vzdálenými repozitáři.
        
 2. Nyní můžeme stáhnout obsah právě přidaného repozitáře:
 
-        git fetch osp
+       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
    větve ze vzdálených repozitářů vypíšeme příkazem
    
-        git branch -r
+       git branch -r
    Zjednodušeně řečeno, jediný rozdíl mezi lokální a vzdálenou větví
-   je v tom, že jméno vzdálené věteve má prefix `<remote>/`.
+   je v tom, že jméno vzdálené větve má prefix `<remote>/` (v našem
+   případě `origin/` nebo `osp/`).
 
 4. Nyní nás zajímá co je ve větvích, které jsme právě stáhli:
 
-        git log osp/only-directories ^master
-        git log master..osp/only-directories
+       git log osp/only-directories ^master
+          git log master..osp/only-directories
    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ů:
 
-        git log -p osp/only-directories ^master
-        gitk osp/only-directories ^master
+       git log -p osp/only-directories ^master
+          gitk osp/only-directories ^master
 
 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:
 
-        git fetch
+       git fetch
    Co přibylo ve větvi *master* od prvního cvičení zjistíme příkazem:
    
-        git log master..origin/master
+       git log master..origin/master
 
 Slučování větví (merge)   
 -----------------------
@@ -243,36 +224,36 @@ Můžou při slučování nastat tři situace:
 Pokud došlo v případě *True merge* ke změně stejného místa v kódu v
 obou větvích, dojde k tzv. *konfliktu*, který musí být vyřešen ručně.
 
-1. Zkuste provést sloučení vaší větve *master* s *origin/master*
+1. Zkuste provést sloučení své větve *master* s *origin/master*
 
-        git merge origin/master
+       git merge origin/master
    Výsledkem bude *Fast forward* a uvidíme jaké soubory byly změněny:
 
-        git merge origin/master
-        Updating 0ebd30c..a99dc51
-        Fast forward
-         configure.ac                  |    1 +
-         contrib/Makefile.am           |    9 +-
-         ...
-   Toto je velmi častá operace a proto lze oprace `fetch` a `merge`
+       git merge origin/master
+       Updating 0ebd30c..a99dc51
+       Fast forward
+        configure.ac                  |    1 +
+        contrib/Makefile.am           |    9 +-
+        ...
+   Toto je velmi častá operace a proto lze operace `fetch` a `merge`
    nahradit jedním příkazem
 
-        git pull
+       git pull
 2. Vždy, když člověk pracuje na nějaké netriviální změně, je užitečné,
    založit si na to samostatnou větev. Dnešním úkolem bude sloučit
    větev *osp/only-directories* s větví *master* a protože to není
    triviální založte si na to novou větev:
    
-        git checkout -b homework
+       git checkout -b homework
 3. Pokud provedete sloučení
 
-        git merge osp/only-directories
+       git merge osp/only-directories
    Výsledek bude vypadat pravděpodobně takto:
 
-        Auto-merging doc/man/mc.1.in
-        Auto-merging src/filemanager/find.c
-        CONFLICT (content): Merge conflict in src/filemanager/find.c
-        Automatic merge failed; fix conflicts and then commit the result. 
+       Auto-merging doc/man/mc.1.in
+          Auto-merging src/filemanager/find.c
+          CONFLICT (content): Merge conflict in src/filemanager/find.c
+          Automatic merge failed; fix conflicts and then commit the result. 
 
    Vidíme, že se automaticky povedlo sloučit změny v souboru
    `doc/mc.1.in`, ale při slučování změn ve `src/find.c` už takové
@@ -286,14 +267,14 @@ Konflikt lze řešit několika způsoby (viz také `git merge --help`):
 
 * Vzdáme to a vrátíme se k verzi před slučováním
 
-        git reset --hard
+       git reset --hard
        
 * 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á
-Výstup zhruba takhle:
+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:
@@ -307,91 +288,80 @@ Výstup zhruba takhle:
 
 Konflikt lze řešit následujícími způsoby:
 
-* V textovém editoru najdeme sekvence `<<<<<<<<`, `=========` a
-  `>>>>>>>>`, kterými jsou označené jednotlivé konfliktní oblasti.
-  Tato místa musíme opravit tak, aby dávala smysl a poté zmíněné
-  sekvence znaků smažeme.
-* `git mergetool` je nástroj, který spouští grafický nástroj (např.
-  [kdiff3][kdiff3]), který vám se slučováním pomůže. 
+* Soubor s konfliktem otevřeme v textovém editoru a najdeme sekvence
+  `<<<<<<<<`, `=========` a `>>>>>>>>`, kterými jsou označené
+  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.
   
-  `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`.
+  `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`.
   
   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í
   pomocí tlačítek A, B a C. V tomto okně je potřeba zbavit se všech
-  řadek, které maji v levém sloupci `?` - tj. konfliktů.
-* `gitk --merge` - zobrazí pouze commity, které modifikovaly
-  konfliktní soubory.
+  řádek, které mají v levém sloupci `?` – tj. konfliktů.
 
-[kdiff3]:http://kdiff3.sourceforge.net/
+Při řešení konfliktů nám může pomoct i příkaz `gitk --merge`, který
+zobrazí pouze commity, které modifikovaly konfliktní soubory.
+Jednoduše tam můžeme zjistit, které změny konflikt způsobily.
 
-Repozitář na repo.or.cz
----------------------------
+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.
 
-K tomu, aby výsledky vaší práce na open source projektech byly snadno
-Dostupné pro ostatní je užitečné založit si vlastní repozitář, odkud
-si budou moct ostatní vaše změny stáhnout.
+[mergealg]:http://stackoverflow.com/questions/612580/how-does-git-solve-the-merging-problem/612747#612747
 
-1. [Zaregistrujte se][reg] na [repo.or.cz][roc]. K repozitáři na
-   repo.or.cz se přistupuje protokolem SSH a autorizace se provádí na
-   základě veřejných klíčů.
-   
-   1. Pokud žádný klíč nemáte, vytvořte si ho příkazem 
-   
-            ssh-keygen
+[kdiff3]:http://kdiff3.sourceforge.net/
 
-      Příkaz se vás zeptá kam klíč uložit. Výchozí volba vám zpočátku
-      bude stačit. Dále se zeptá na heslo (passphrase) k vašemu
-      privátnímu klíči. Pokud žádné heslo nezadáte, bude se moct
-      kdokoli, kdo se dostane k souboru s vaším klíčem (např.
-      administrátor školních serverů), autorizovat jako vy.
-   
-   2. Pokud jste se rozhodli chránit klíč heslem, je otravné zadávat
-      heslo vždy, když klíč používáte. Naštěstí existuje program
-      `ssh-agent`, který uchovává odheslované klíče v paměti a
-      poskytuje je vždy, když je nějaký oprávněný program potřebuje.
-      Vy tak zadáte heslo jen jednou a to když předáváte klíč
-      ssh-agentovi příkazem
+Repozitář na GitHubu
+--------------------
 
-            ssh-add
+K tomu, aby výsledky vaší práce na open source projektech byly snadno
+dostupné pro ostatní je užitečné založit si vlastní repozitář, odkud
+si budou moct ostatní vaše změny stáhnout.
 
-[reg]:http://repo.or.cz/reguser.cgi
-[roc]:http://repo.or.cz/
+1. Zaregistrujte se na [GitHubu](https://github.com/). V závislosti na
+   tom, jakým protokolem chcete k repozitářům na GitHubu přistupovat
+   si nastavte buď [password caching][passcache] (pro HTTP) nebo
+   [SSH klíče][sshkeys] (pro SSH).
 
-2. Vytvoření repozitáře na repo.or.cz.
+[passcache]:https://help.github.com/articles/set-up-git#password-caching   
+[sshkeys]:https://help.github.com/articles/generating-ssh-keys
 
-   Můžete založit buď [nový projekt][new] a nebo udělat tzv.
-   [fork existujícího projektu][forkmc]. Pro oba typy projektů můžete
-   zvolit zda bude repozitář pouze automaticky aktualizovanou kopií
-   jiného repozitáře (*mirror mode*) a nebo zda-li bude možné do něj přímo
-   ukládat nové commity (*push mode*).
+2. Vytvoření repozitáře na GitHubu. Můžete založit buď
+   [nový projekt][new] nebo udělat tzv. "fork" existujícího projektu.
    
-   Pro účely tohoto cvičení si
-   [založte fork][forkmc] [Midnight commanderu][w/osp.git] v *Push módu*, který se
-   bude jmenovat podle vašeho loginu. Do tohoto repozitáře pak
+   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í.
    
-3. Do vašeho vzdáleného repozitáře můžete nahrát vaší větev některým z
-   těchto způsobů
+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 ssh://<mujlogin>@repo.or.cz/srv/git/midnight-commander/osp/<mujfork>.git homework
-   nebo        
+       git remote add github https://github.com/<mujlogin>/mc.git
+       git push github HEAD:homework
+   nebo
 
-        git remote add repo-or-cz ssh://<mujlogin>@repo.or.cz/srv/git/midnight-commander/osp/<mujfork>.git
-        git push repo-or-cz homework
+       git push https://github.com/<mujlogin>/mc.git homework
+   nebo
 
-[new]:http://repo.or.cz/regproj.cgi
-[forkmc]:http://repo.or.cz/regproj.cgi?fork=midnight-commander/osp.git
+       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_select
 
 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í `origin/master`. Výsledek
-uložte do [vámi vytvořeného repozitáře (forku) na repo.or.cz][forkmc]
-do větve `homework`.
-
-[w/osp.git]:http://repo.or.cz/w/midnight-commander/osp.git
+only-directories` s aktuální vývojovou větví Midnight Commanderu
+(`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`.