-
1. Úvod
- 1.1 Správa verzí
- 1.2 Stručná historie systému Git
- 1.3 Základy systému Git
- 1.4 Příkazový řádek
- 1.5 Instalace systému Git
- 1.6 První nastavení systému Git
- 1.7 Získání nápovědy
- 1.8 Shrnutí
-
2. Základy práce se systémem Git
-
3. Větve v systému Git
- 3.1 Větve v kostce
- 3.2 Základy větvení a slučování
- 3.3 Správa větví
- 3.4 Postupy při práci s větvemi
- 3.5 Vzdálené větve
- 3.6 Přeskládání
- 3.7 Shrnutí
-
4. Git na serveru
- 4.1 Protokoly
- 4.2 Zprovoznění Gitu na serveru
- 4.3 Generování veřejného klíče SSH
- 4.4 Nastavení serveru
- 4.5 Démon Git
- 4.6 Chytrý HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Možnosti hostování u třetí strany
- 4.10 Shrnutí
-
5. Distribuovaný Git
- 5.1 Distribuované pracovní postupy
- 5.2 Přispívání do projektu
- 5.3 Správa projektu
- 5.4 Shrnutí
-
6. GitHub
-
7. Git Tools
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Ladění v systému Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Shrnutí
-
8. Customizing Git
- 8.1 Git Configuration
- 8.2 Atributy Git
- 8.3 Git Hooks
- 8.4 An Example Git-Enforced Policy
- 8.5 Shrnutí
-
9. Git a ostatní systémy
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Shrnutí
-
10. Git Internals
- 10.1 Plumbing and Porcelain
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Balíčkové soubory
- 10.5 The Refspec
- 10.6 Přenosové protokoly
- 10.7 Správa a obnova dat
- 10.8 Environment Variables
- 10.9 Shrnutí
-
A1. Appendix A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Eclipse
- A1.4 Git in Bash
- A1.5 Git in Zsh
- A1.6 Git in Powershell
- A1.7 Shrnutí
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
3.1 Větve v systému Git - Větve v kostce
Nějakou formu větvení podporují téměř všechny systémy pro správu verzí. Větvení znamená, že se můžete odloučit od hlavní linie vývoje a pokračovat v práci, aniž byste do hlavní linie zasahovali. V mnoha nástrojích pro správu verzí jde o poněkud náročný proces, který často vyžaduje vytvoření nové kopie adresáře se zdrojovým kódem, což může u velkých projektů trvat dlouho.
Někteří lidé mluví o modelu větvení Gitu jako o „převratné vlastnosti“ a mezi systémy pro správu verzí se jím Git určitě odlišuje. V čem je tak zvláštní? Způsob, jakým Git větvení provádí, je neuvěřitelně snadný a operace větvení probíhají téměř okamžitě. A stejně rychlé je většinou i přepínání mezi větvemi. Na rozdíl od ostatních systémů pro správu verzí vybízí Git ke způsobu práce, kdy se větvení a slučování provádí často, dokonce i několikrát za den. Pochopení a zvládnutí tohoto rysu vám dává do rukou výkonný a jedinečný nástroj a může zcela změnit způsob, jakým budete realizovat vývoj.
Větve v kostce
Abychom skutečně pochopili, jak v Gitu funguje větvení, musíme poodstoupit a podívat se, jak Git ukládá data.
Jak si možná vzpomínáte z kapitoly Úvod, Git neukládá data jako sérii změn nebo rozdílů, ale jako sérii snímků.
Když zapíšete revizi, uloží Git objekt revize (commit object), který obsahuje odkaz na snímek obsahu, který jste připravili k zapsání. Tento objekt obsahuje také jméno a e-mail autora, zprávu, kterou jste napsali, a odkazy na jeden nebo víc objektů revize, které této revizi přímo předcházely (jeho rodiče): na žádného rodiče pro počáteční revizi, na jednoho rodiče pro běžnou revizi a na více rodičů pro revizi, která je výsledkem sloučení dvou nebo více větví.
Pro ilustraci předpokládejme, že máte adresář s třemi soubory, které připravíte k zapsání a následně zapíšete. Při přípravě souborů k zapsání je pro každý z nich vypočítán kontrolní součet (o otisku SHA-1 jsme se zmínili v kapitole Úvod), daná verze souborů se uloží v repozitáři Gitu (Git jim říká bloby [10]) a přidá jejich kontrolní součet do oblasti připravených změn:
$ git add README test.rb LICENSE
$ git commit -m 'The initial commit of my project'
Když příkazem git commit
vytváříte revizi, vypočítá Git kontrolní součet každého podadresáře (v tomto případě pouze kořenového adresáře projektu) a uloží tyto objekty stromu (tree) do repozitáře Gitu.
Poté Git vytvoří objekt revize (commit) s metadaty a s ukazatelem na kořen stromu projektu, aby mohl v případě potřeby tento snímek obnovit.
Váš gitovský repozitář nyní obsahuje pět objektů: jeden blob pro obsah každého z vašich tří souborů, jeden strom, který zaznamenává obsah adresáře a udává, které názvy souborů jsou uloženy jako který blob, a jeden objekt revize s ukazatelem na kořenový objekt stromu a se všemi metadaty revize.
![Objekt revize a jeho strom.](png/commit-and-tree.png)
Jestliže v souborech provedete změny a zapíšete je, další objekt revize uloží ukazatel na bezprostředně přecházející objekt revize.
![Objekty revize a jejich rodiče.](png/commits-and-parents.png)
Větev je v Gitu jen snadno přemístitelným ukazatelem na jeden z těchto objektů revize.
Výchozím názvem větve v Gitu je master
(hlavní větev).
Když vytváříte objekt revize, máte k dispozici větev master
, která ukazuje na váš minulý objekt revize.
Pokaždé, když zapíšete novou revizi, větev se automaticky posune vpřed.
Note
|
Větev „master“ se v Gitu nechápe jako speciální větev.
Je úplně stejná jako všechny ostatní.
Jediným důvodem, proč ji najdete skoro v každém repozitáři, je to, že ji standardně vytváří příkaz |
![Větev a historie jejích objektů revize.](png/branch-and-history.png)
Vytvoření nové větve
Co se stane, když vytvoříte novou větev?
Znamená to vytvoření nového ukazatele, s nímž můžete pohybovat.
Řekněme, že vytvoříte novou větev a nazvete ji testing.
Učiníte tak příkazem git branch
:
$ git branch testing
Vytvoří se tím nový ukazatel na stejný objekt revize, na kterém se právě nacházíte.
![Dvě větve ukazují na stejnou sérii objektů revize.](png/two-branches.png)
Jak Git pozná, na jaké větvi se právě nacházíte?
Používá speciální ukazatel zvaný HEAD
.
Poznamenejme, že tento koncept HEAD
se velmi liší od těch, na které můžete být zvyklí z jiných systémů pro správu verzí, jako jsou Subversion nebo CVS.
V Gitu se jedná o ukazatel na lokální větev, na níž se právě nacházíte.
V tomto případě jsme stále na větvi master
.
Příkaz git branch
pouze vytvořil novou větev — nepřepnul do ní.
![HEAD ukazující na větev.](png/head-to-master.png)
Snadno to můžeme zviditelnit spuštěním příkazu git log
, který vám ukáže, kam reference větví ukazují.
Potřebná volba se jmenuje --decorate
.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) add feature #32 - ability to add new formats to the central interface
34ac2 Fixed bug #1328 - stack overflow under certain conditions
98ca9 The initial commit of my project
Vedle otisku revize f30ab
vidíte větve master
a testing
.
Přepínání větví
Chcete-li přepnout na existující větev, spusťte příkaz git checkout
.
Přepněme se na novou větev testing
:
$ git checkout testing
Tím se HEAD
se přesune a ukazuje na větev testing
.
![HEAD ukazuje na aktuální větev.](png/head-to-testing.png)
A jaký to má význam? Dobře, zapišme další revizi:
$ vim test.rb
$ git commit -a -m 'made a change'
![Větev HEAD se při zápisu revize posune vpřed.](png/advance-testing.png)
Výsledek je zajímavý z toho důvodu, že se větev testing
posunula vpřed, zatímco větev master
stále ukazuje na revizi, na níž jste se nacházeli před přepnutím větví příkazem git checkout
.
Přepněme zpět na větev master
.
$ git checkout master
![Při checkout se HEAD přesune.](png/checkout-master.png)
Příkaz provedl dvě věci.
Přemístil ukazatel HEAD
zpět, takže nyní ukazuje na větev master
, a vrátil soubory ve vašem pracovním adresáři zpět ke snímku, na který ukazuje větev master
.
To také znamená, že změny, které od tohoto okamžiku provedete, vedou k odklonu od starší verze projektu.
V podstatě vrátíte změny, které jste provedli ve větvi testing
, takže se můžete vydat jiným směrem.
Note
|
Přepnutí větví mění soubory ve vašem pracovním adresáři
Považuji za důležité poznamenat, že v Gitu se při přepnutí větví změní soubory ve vašem pracovním adresáři. Pokud se přepnete na starší větev, váš pracovní adresář bude změněn do podoby z doby, kdy jste v oné větvi zapsali poslední revizi. Pokud by se to Gitu nemělo podařit čistě, nedovolí vám přepnout vůbec. |
Proveďme pár změn a zapišme další revizi:
$ vim test.rb
$ git commit -a -m 'made other changes'
Nyní se historie vašeho projektu rozdělila (viz obrázek Rozbíhající se historie).
Vytvořili jste novou větev, přepnuli se na ni, provedli změny a poté jste přepnuli zpět na hlavní větev, v níž jste provedli další změny.
Oboje tyto změny jsou oddělené na samostatných větvích. Můžete mezi nimi přepínat tam a zpět, a až uznáte za vhodné, můžete je sloučit.
To vše jste provedli pomocí jednoduchých příkazů branch
, checkout
a commit
.
![Rozbíhající se historie.](png/advance-master.png)
Můžete si to snadno zviditelnit příkazem git log
.
Když spustíte git log --oneline --decorate --graph --all
, zobrazí se historie revizí, která ukazuje polohu ukazatelů na větve a jak se historie rozdělila.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) made other changes
| * 87ab2 (testing) made a change
|/
* f30ab add feature #32 - ability to add new formats to the
* 34ac2 fixed bug #1328 - stack overflow under certain conditions
* 98ca9 initial commit of my project
A protože větev je v Gitu ve skutečnosti obyčejným souborem, který obsahuje 40 znaků kontrolního součtu SHA-1 revize, na kterou větev ukazuje, dají se větve snadno vytvářet i odstraňovat. Vytvořit novou větev je právě tak snadné a rychlé jako zapsat 41 bytů do souboru (40 znaků plus jeden pro nový řádek).
Ostře to kontrastuje se způsobem větvení ve většině starších systémů pro správu verzí, který zahrnoval kopírování všech souborů projektu do druhého adresáře. To může zabrat několik sekund nebo dokonce minut — v závislosti na velikosti projektu --, zatímco v Gitu tento proces proběhne vždy okamžitě. A protože při zapisování objektů revize zaznamenáváme i jeho rodiče, probíhá automaticky i vyhledání správných zdrojů pro slučování, které se pak většinou dělá velmi snadno. Tyto vlastnosti pomáhají k tomu, aby se vývojáři nebáli větve často vytvářet a používat.
Podívejme se, proč byste to měli dělat také tak.