Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.
Poslední aktuality jsou v issue #112 (z 15. dubna).
- Předstartovní kontrola
- Než začneme …
- Průběžný příklad
- Issues v GitLabu
- Větve v Gitu (pojďme opravit chyby)
-
Propojení commitů s issue a
git commit --amend
- Nahrání (push) nové větve
- Cvičení
- Graf commitů
- Merge requests (žádosti o začlenění)
- Mergování z příkazové řádky
- Zobrazení seznamu větví a mazání větví
- Začleňování změn z upstreamu (udržování vaší větve aktuální) a práce s remotes
- Konflikty při merge (a jak je řešit)
- Shrnutí větvení
- Zcela nesouvisející témata :-)
- Úlohy k ověření vašich znalostí
- Učební výstupy a kontrola po cvičení
- Seznam změn na této stránce
Cílem tohoto cvičení je ukázat klíčovou vlastnost Gitu: větve. Je to mocný nástroj pro každodenní programování softwaru vyvíjeného v týmu. Ale hodí se i pro jednotlivce.
Dnešní software je málokdy tvořen jedinou osobou: je to týmová činnost a členové týmu potřebují spolupracovat na vývoji. Na tomto cvičení si ukážeme, co Git nabízí v tomto směru pro týmy v podstatě libovolné velikosti. Také se podíváme, jak je GitLab propojený s Gitem a jaké nástroje nabízí pro manažerskou část práce.
Obvykle týmová práce na sdíleném kódu znamená, že potřebujete, aby:
- práce každého člena týmu byla oddělená,
- ale bylo možné jednoduše výsledky jednotlivých členů kombinovat (alespoň v okamžiku, kdy jsou části skutečně nezávislé)
Tyto vlastnosti Git nabízí pomocí větví (branches). Ve skutečnosti je koncept větví mnohem silnější a hodí se i pro projekty s jedním vývojářem. V tomto cvičení se podíváme, jak se používají.
Předstartovní kontrola
- Znáte základní Gitové příkazy zpaměti (
clone
,pull
,push
,log
,status
,diff
,add
,commit
). - Nahráli jste váš veřejný klíč do jednoho ze souborů
keys/key.[0-9].pub
. - Jste odpočinutí a čerství: tohle je asi nejužitečnější cvičení z celého předmětu: nemůžete se stát vývojáři, aniž byste tohle všechno znali :-)
Než začneme …
Mnoho věcí, které zde zmíníme, už znáte z předchozích cvičení. To je v pořádku a je to naschvál: teď se je pokusíme představit najednou jako ucelený obrázek toho, co Git umí a jak se s ním pravděpodobně setkáte ve svých budoucích zaměstnáních.
Pokud už větve z Gitu znáte, asi si všimnete, že spousty věcí zjednodušujeme. Formálně jsou větve ukazatele na uzly acyklického grafu commitů atd., ale to není podstatné pro pochopení tohoto textu (a do detailů se tím zabývá NSWI154).
Průběžný příklad
Vytvořte fork projektu teaching/nswi177/2025/common/group-sum.
Fork je kompletní kopie repozitáře původního projektu. Při forkování se stanete vlastníkem nového projektu a můžete cokoliv měnit, aniž by se to dotklo původního projektu.
Doporučujeme, abyste změnili viditelnost vašeho forku na privátní.
V průběhu celého cvičení budeme pracovat s příkladem v tomto repozitáři. Nezapomeňte naklonovat svůj fork (nikoli původní repozitář). Budete v něm provádět poměrně hodně změn.
Tento příklad se pokusí napodobit práci v týmu – kdykoli budeme mluvit o nějaké funkci (nebo chybě), představte si, že pracujete ve velkém týmu a funkce/chyby nejsou jednořádkové opravy, ale několikadenní práce jednotlivých členů týmu.
Podívejte se na implementaci uvnitř souboru group-sum.py
. Později
uvidíme, že soubor group-sum.py
by měl být v adresáři src
a projekt by
měl být správně nakonfigurován pro Pythoní program, ale zatím zůstaneme u
jednodušší varianty.
Implementace je mírně rozšířenou verzí našeho předchozího skriptu, který uměl sčítat celá čísla na základě obsahu řádku.
Především používá modul
argparse
pro lepší
parsování parametrů příkazového řádku. To nám umožnilo rozšířit funkci o
použití vlastních oddělovačů a dalších drobnosti.
Vzhledem k tomu, že celý nástroj je poměrně malý, je výpočetní jádro programu zakrslík v porovnání s částí konfigurující parser voleb z příkazové řádky. Tohoto kódu se však nebojte. Parser parametrů v Pythonu je poměrně užitečný modul, který s minimálním úsilím udělá programy v Pythonu mnohem čitelnějšími (především z hlediska jejich spuštění).
Issues v GitLabu
Všimněte si, že skript se ukončí s výjimkou, pokud vstupní soubor neexistuje (místo vypsání nějaké hezké chybové zprávy).
To rozhodně není uživatelsky přívětivé. Pojďme to napravit.
Lidé však (nemá smysl to zastírat) málokdy mají čas řešit problém okamžitě. Proto je docela užitečné poznamenat si všechny nevyřešené problémy v projektu, aby se na ně nezapomnělo.
Abychom si udrželi přehled o nevyřešených problémech v našich projektech, je dobré je zaznamenávat. V postranní liště každého Gitlabového projektu je odkaz na Issues: pokud na něj kliknete, uvidíte, že The Issue Tracker is the place to add things that need to be improved or solved in a project. To je to, co potřebujeme ;-).
Vytvořte novou Issue popisující problém.
Každá issue má nadpis – něco jako předmět v e-mailu –, který by měl shrnout, co je špatně nebo co se musí udělat. Také musíte dodat popis – v některých případech si můžete myslet, že nadpis Chyba když chybí soubor úplně stačí. Nestačí! Vždy přidejte příklad a postup, jak problém zreprodukovat.
Tohle platí i v případě, že hlásíte problémy se zadáním apod. nám :-).
Vraťme se k našemu příkladu. Chyby se často houfují. Problémů s kódem je více. Co se stane při následujícím vstupu:
alpha 45
charlie 32
alpha HELLO
Jejda, další výjimka.
Vytvořte proto ve svém projektu další issue. Opět: použijte popisný nadpis, uveďte smysluplný popis. Opravdu. Použijte to jako cvičení pro hodnocený úkol.
Zobrazte si seznam svých issue. Každá issue by měla mít vedle sebe číslo, na které se můžeme později odkázat.
Něco navíc
Mnohé projekty mají dokonce šablony, aby uživatele navedly, které všechny informace jsou potřeba. My je používat nebudeme, ale pro velké projekty jsou užitečné. GitLab je umí také.
Všimněte si odkazu Markdown, který obsahuje nápovědu pro formátování
pomocí Markdownu (v nových verzích GitLabu je odkaz částečně schován a nahrazen ikonou s písmenem M a šipkou dolů): znalost `
a
```
je prostě nutnost pro každého programátora :-).
Pro další čtení si do vyhledávače zadejte jak napsat dobrý bugreport (how to write a good bug report) a alespoň jeden článek si přečtěte. Stojí to za to. Doopravdy.
Větve v Gitu (pojďme opravit chyby)
Git má koncept větví, které reprezentují řadu commitů. Zatím byla tato řada lineární – každý commit (kromě úplně prvního a posledního, pochopitelně) měl jeden předchozí a jeden následující commit. Jejich pořadí bylo určeno tím, jak commity vznikaly v čase.
Větve v Gitu vám umožní tuto linearitu rozbít – commit může mít více následníků: práce se rozdělí a každá větev má svou vlastní cestu: do programu přidáváme nové funkce. Commit také může mít dva rodiče: provádíme tzv. merge dvou větví (slití, spojení).
Typický příklad je práce v týmu. Alice a Bob pracují oba na stejném projektu a sdílí jeden repozitář. Alice pracuje na funkci A, Bob na funkci B. Oba začali na stejném commitu (řekněme hned po vydání poslední verze), ale jejich práce se rozchází: každý pracuje na svém úkolu a přidává své funkce. Jakmile jsou se svojí prací spokojeni, provedou tzv. merge – tj. spojí svoje verze dohromady a získají tak verzi, která obsahuje funkce A i B.
Následující obrázek ukazuje příklad jednoduchých větví (v MSIMu), ale i komplikovanější situaci ve středně velkém open-source projektu (HelenOS).
Ve skutečnosti jste už s Gitovými větvemi pracovali, aniž byste o tom
věděli.
Když uděláte clone
repozitáře, vytvoříte přesnou kopii stavu na serveru.
Když jste přidali nové commity lokálně, objevili se vlastně na větvi, která
je odlišná
od větve na serveru.
Pak push
tyto větve zase spojil.
A pull
pracuje v opačném směru: přitáhne nové commity ze serveru a připojí
je k vaší místní větvi.
Ale zatím tyto větve nikdy nedivergovaly – jedna větev byla vždy prefixem
té druhé. Takže spojování nevyžadovalo žádnou
extra činnost a bylo pro vás transparentní.
Commit zprávy (už zase)
Přečtěte si článek How to Write a Git Commit Message od Chrise Beams, pokud jste ho ještě nečetli. A pokud jste ho už četli, klidně si ho přečtěte znovu.
Fázi, kdy Git byl nepřítel, máme teď už za sebou a můžeme tedy pracovat na zlepšení našich návyků.
Od teď začněte psát rozumné commit zprávy. Jsou součástí vývoje a jsou téměř tak důležité jako kód, na který odkazují. Hlavně ve velkých týmech.
Feature branches (větve pro nové funkce)
Aby se kód udržel v rozumném stavu, mnoho projektů má jednoduché pravidlo:
commitujte co nejčastěji, ale kód v hlavní větvi (tohle jméno můžete změnit,
ale obvykle se potkáte s názvy jako master
nebo main
) musí být vždy v
pořádku (ve smyslu, že všechny testy prochází).
Pokud pracujete na nové funkci, vytvořte si novou větev.
Pracujte v této větvi a spojte ji s master
em jen, když bude funkce hotová.
Pro některé projekty je povinnou částí před vlastním mergem recenze kódu
(code review) nebo dokonce zátěžové testy (load testing).
Má to skvělou výhodu: když někdo začne novou větev, můžete si být celkem jistý, že začíná s funkčním kódem.
Budeme se tím ale řídit i v tomto cvičení. Pro každou novou funkci (nebo opravu chyby) budeme mít novou větev a do hlavní větve ji zamergujeme až po otestování.
Vytváření nových větví v Gitu
Začneme opravou problému s vyhozenou výjimkou, když soubor neexistuje. Vytvoříme pro ni větev a přepneme se na ni.
Větší týmy mají často zavedené konvence pro pojmenování větví. Zjednodušme
si to a používejme issue/
N-jmeno
pro větve, které mají opravit problém
v issue s číslem N.
Pro vytvoření větve použijeme příkaz git branch
.
git branch issue/1-hide-traceback-file-not-found
K vytvoření jedinečného názvu větve používáme id issue (abychom zabránili případným kolizím s ostatními vývojáři), ale také připojujeme krátké shrnutí, abychom my sami věděli, na čem pracujeme.
Tento příkaz neudělá žádnou viditelnou změnu. Pouze označí aktuální (poslední) commit jako výchozí bod pro novou větev.
Abychom skutečně přepnuli na novou větev, musíme provést příkaz
git checkout issue/1-hide-traceback-file-not-found
V tuto chvíli nemá přepnutí žádný viditelný efekt – obě větve master a issue/1-hide-traceback-file-not-found odkazují na stejný stav souborů.
Nyní opravte tento problém. Řešení.
Commitněte změnu.
Propojení commitů s issue a git commit --amend
Git je při práci s commity poměrně pružný. Pokud zjistíte, že chcete změnit
poslední commit, můžete soubory přidat pomocí git add
a poté zavolat git commit --amend
. Otevře se vám textový editor s již vyplněnou commit
zprávou, kterou můžete změnit.
Použijte tuto funkci a přidejte k poslednímu commitu do zprávy fixes #1
.
Jakmile tuto verzi odešlete na GitLab, stanou se dvě věci. Zaprvé, issue
bude obsahovat odkaz na commit a na #1
ve zprávě o commitu bude možné
kliknout a otevřít zmíněnou issue.
Protože náš commit tento problém opravil, přidali jsme speciální klíčové slovo
fixes
do zprávy, aby se issue automaticky uzavřela
(existuje spousta
vzorů pro uzavírání issues).
Issue bude uzavřena, jakmile bude commit začleněn do větve master
. To dává
velký smysl: problém může být opraven, ale dokud není kód ve větvi master
,
program stále obsahuje chybu (vzpomeňte si, že ve větvi master
je obvykle
kód, který je dodáván zákazníkovi).
Všimněte si, že to slouží ke dvěma účelům – šetříme čas (nemusíme vůbec přepínat do prohlížeče) a poskytujeme také cenný odkaz na to, který commit byl skutečně zodpovědný za opravu chyby. Všimněte si, že issue na GitLabu zatím není označena jako opravená (vyřešená), protože jsme zatím na GitLab nic nenahráli.
V projektu byste teď neměli mít žádné necommitnuté změny.
Přepneme se zpět do větve master
.
Zkontrolujte, zda skript (po přepnutí) neobsahuje vaši opravu.
Nápověda.
Zkontrolovali jste to? Dobře, můžeme pokračovat.
Všimněte si, že pokud máte skript otevřený v textovém editoru, měl by vás upozornit na změnu souboru na disku. Pokud tomu tak není, načtěte soubor (reload) znovu ručně.
Nahrání (push) nové větve
Přepněte zpět na větev issue/1-hide-traceback-file-not-found
a odešlete ji
na GitLab. Pokud spustíte git push
(jak jste byli zvyklí), bude si Git
stěžovat, že aktuální větev nemá žádnou větev v upstreamu. Znamená to
(víceméně), že tuto větev nahráváte poprvé a Git se chce ujistit, jak má
větev na serveru pojmenovat.
Příjemné je, že Git vám nabídne příkaz, který můžete spustit, abyste zajistili nahrání (push) větve.
git push --set-upstream origin issue/1-hide-traceback-file-not-found
Odkaz, který vám GitLab poslal zpět, prozatím ignorujte.
Znovu otevřete projekt v prohlížeči. Zkontrolujte, zda vaše issue nyní obsahuje odkaz na commit, který ji zmiňuje; a na domovské stránce projektu můžete vybrat, která větev se má zobrazit.
Cvičení
Vyzkoušejte si to sami.
Graf commitů
V prohlížeči otevřete stránku Repository -> Graph (z projektu). Měly by se vám graficky zobrazit vaše větve.
Vedle větve master byste měli vidět novou větev
issue/1-hide-traceback-file-not-found
, která vychází ze stejného commitu.
Grafické zobrazení je dobrým pomocníkem, pokud se ztratíte ve složitém modelu větvení a nejste si jisti, zda by některé změny měly být v konkrétní větvi viditelné, nebo ne.
Účelem není vytvářet složité grafy, i když někdy mohou být docela divoké.
Pro git log
můžete také použít parametr --graph
, abyste získali grafické
zobrazení v terminálu.
Merge requests (žádosti o začlenění)
Žádosti o začlenění (merge requests) jsou pokročilou vychytávkou GitLabu
pro větší týmy.
Ve velkých týmech je code review vyžadováno vždy před tím, než je nějaký kód
odeslán do větve master
.
Code review obvykle znamená, že zkušený vývojář si prohlédne váš kód, okomentuje ho a může po vás chtít další úpravy. Představte si pod tím přejmenování funkcí, použití jiných datových struktur nebo opravy dokumentace. Cokoliv od skutečných funkčních chyb po styl zdrojáku.
Merge requesty se hodí přesně na tohle. Než dojde k vlastnímu začlenění (tj. než vaše změny odejdou do hlavní vývojové větve), můžete otevřít tzv. žádost (merge request).
Merge request se hodně podobá issue: ve skutečnosti jsou oba formuláře velmi podobné. To je proto, že Issues popisují známý problém (nebo žádost o novou funkci), zatímco merge requesty popisují, jak byl problém vyřešen. Jak říká GitLab, merge requests are a place to propose changes you’ve made to a project and discuss those changes with others.
Je dobrým zvykem zmínit, které issue daný merge request uzavře (nebo se kterými souvisí).
Opět, pro formátování lze použít Markdown.
Ve velkých týmech budou ostatní vývojáři komentovat váš kód právě během merge requestu a také budou spuštěny automatické testy nad vaším kódem (což se naučíte v některém z dalších cvičení).
Merge requesty mohou dávat smysl i pro osobní projekty: umožní vývojáři rychle zkontrolovat, že je vše v pořádku (třeba, že byly commitnuty všechny soubory apod.).
Pokračování průběžného příkladu
Přepněte se na větev druhé issue a odešlete ji také na GitLab. Budete muset
znovu použít přepínač --set-upstream
.
Všimněte si, že po push by se měl zobrazit text informující o možnosti otevřít merge request s odkazem.
Otevřete si tento odkaz v prohlížeči.
Všimněte si, že merge request ještě nebyl odeslán. Název a popis jsou předvyplněny a vypadají podobně jako formulář, který jsme viděli u issues.
Vytvořte nyní merge request.
Udělejme nyní merge daného merge requestu (je tam na to velké tlačítko).
Zachovejte výchozí nastavení a proveďte merge (tj. ne rebase ani squash).
Po uzavření merge requestu bychom měli vidět nový commit ve větvi master.
Můžete se také znovu podívat na graf commitů a zjistit, jak commity vypadají po mergi.
Zkontrolujte nyní issues u svého projektu a všimněte si, že druhá issue by měla být již uzavřena. Můžete také zkontrolovat podrobnosti u issue a všimnout si, jak je commit pěkně propojen s issue.
Zpět v místním klonu repozitáře: nezapomeňte si stáhnout (pull) nejnovější změny z masteru (GitLab vytvořil commit pouze na serveru). Nápověda.
Mergování z příkazové řádky
Nyní zmergujeme první issue přímo z příkazového řádku, aniž bychom museli otevírat merge request. Protože merge request je vždy vázán na nějakou větev, můžete také vždy mergovat i na příkazovém řádku.
Všimněte si opět dvojího přístupu, který je v Linuxu všudypřítomný: můžete používat pěkné grafické uživatelské rozhraní, ale také plně automatizovatelné rozhraní příkazového řádku.
Samotný merge je vskutku jednoduchý.
# musíme být na hlavní větvi (git checkout master)
git merge issue/1-hide-traceback-file-not-found
A je hotovo. Znovu odešlete větev master a zkontrolujte graf commitů.
Všimněte si, že merge
je vlastně jen commit, který má jako rodiče dva
různé commity (předchozí verze). Většina voleb je tak v obou dílčích
příkazech (tj. commit
a merge
) podobná.
Zobrazení seznamu větví a mazání větví
Abychom viděli seznam větví, stačí spustit následující příkaz.
git branch
Někdy je užitečné zobrazit si všechny větve včetně těch na vzdáleném serveru
(vizte též dále) přidáním -a
.
Když je větev zmergovaná, můžeme ji odstranit, abychom udržovali seznam kratší.
git branch -d issue/1-hide-traceback-file-not-found
Odstraněním větve se vlastně jen odstraní štítek, který uváděl, že konkrétní
commit patří do určité větve. Proto Git nepožaduje potvrzení při použití
-d
, protože neodstraňujete žádný skutečný kód ani žádné commity. Pokud
však větev ještě není zmergována, Git ji odmítne odstranit (s chybovým
hlášením, že větev je not fully merged, a s nápovědou, abyste použili
velké -D
, pokud ji skutečně chcete smazat).
Začleňování změn z upstreamu (udržování vaší větve aktuální) a práce s remotes
Feature branch vám umožní pracovat na nové funkci bez zásahů do hlavní větve. Ale práce v hlavní větvi dál pokračuje a vy potřebujete udržet vaší novou větev aktuální.
To je velmi obvyklá úloha.
Nechcete přijít o důležité aktualizace, které se dějí v master
u.
Často může přeskočení takových aktualizací výrazně zkomplikovat mergování
zpátky.
Podle velikosti a aktivity projektu může dávat smysl mergovat změny z hlavní
větve každý týden nebo dokonce každý den.
Udržování vaší větve aktuální se obvykle označuje jako mergování z upsreamu, protože se tím odkazuje na rodičovský projekt (větev).
Uvidíte, že se to vlastně vůbec neliší od jiného mergování. Je to jen o určení správného směru (tj. změny do hlavní větve nebo změny v hlavní větve do vaší feature větve).
Git vám s tímto procesem vždy pomůže a často to bude zcela automatizovaná záležitost.
Budeme simulovat, že práce v tzv. upstream projektu (tj. v repozitáři, ze kterého jste forknuli) pokračuje, a vy chcete, aby váš repozitář (váš fork) byl aktuální.
V Gitu je toto vše možné a (možná překvapivě) je velmi malý rozdíl mezi tím, zda mergujete svou vlastní (lokální) větev nebo změny někoho jiného, kdo pracuje v úplně jiném forku.
Pro mergování změn z jiného repozitáře, než je ten výchozí (např. jiný projekt na GitLabu), musíme nastavit tzv. remotes.
Remote je pojmem, který říká, že váš místní klon ví i o jiných forcích a může vám říct, zda se liší. Opět se jedná o docela zjednodušený pohled na věc, ale je dostačující pro první seznámení s Git remotes. Obvykle očekáváte, že remotes mají společného předka, tj. počáteční commit je ve všech remotech stejný.
Chcete-li zobrazit své remotes, spusťte (v místním klonu svého forku repozitáře s příkladem) následující příkaz
git remote
Pravděpodobně by vypsal pouze origin
. To je výchozí remote: když provedete
git pull
nebo git push
, použije se origin
. Tudíž jste již používali
remotes, i když jste o tom nevěděli ;-).
Spuštění s -v
(pro verbose) vypíše konkrétní adresy URL, na kterých se
nachází vzdálený server. Ve skutečnosti nyní pravděpodobně uvidíte dva
remotes: jeden pro push, druhý pro fetch (pull). Dokonce můžete Git
nakonfigurovat tak, aby stahoval z jiného projektu, než do kterého
nahráváte. Pro nás to však v tuto chvíli není příliš užitečné.
Chcete-li zjistit ještě více podrobností, zkuste git remote show origin
.
Přidání dalšího remote
Před pokračováním se ujistěte, že váš veřejný klíč funguje pro naše
repozitáře na adrese gitolite3@linux.ms.mff.cuni.cz:lab05-LOGIN
(podrobnosti u cvičení 05).
Přidejme do našeho repozitáře nový remote. Ten bude odkazovat na jiný projekt, abychom mohli porovnat naše změny se změnami v něm (opět zjednodušený pohled na věc).
git remote add upstream gitolite3@linux.ms.mff.cuni.cz:lab06-group-sum-ng.git
Ale počkat. Tohle není repozitář GitLabu! To je ale v pořádku. Přidáme remote, který žije někde jinde. Budou sdílet stejnou historii Gitu a vše bude fungovat.
Výše uvedený příkaz přidal remote s názvem upstream
, který ukazuje na
zadanou adresu. Všimněte si, že příkaz nic nevypsal.
Znovu spusťte git remote
. Co se změnilo?
Všimněte si, že náš repozitář obsahuje příponu -ng
pro novou generaci,
tj. (tak trochu) simulujeme, že původní projekt, ze kterého jste forknuli,
je zastaralý, ale někdo jiný ho převzal a pokračuje ve vývoji jinde.
Práce s remotes
Přidáním remote ještě nedošlo k výměně dat. Gitu musíte říct, aby vše provedl, nic se neděje automaticky. Poznamenejme, že pokud se někdy setkáte s jiným verzovacím systémem, bude vám používání systému Git připadat velmi nízkoúrovňové a možná i zdlouhavé. Je to daň za jeho efektivitu a flexibilitu.
Pojďme stáhnout změny z našeho nového remote.
git fetch upstream
Mělo by se zobrazit typické shrnutí jako při klonování/stahování změn v systému Git. Tentokrát odkazuje na data z upstreamového repozitáře.
Ve vaší pracovní kopii (tj. v adresáři s vaším projektem) se však nic nezměnilo. To je v pořádku, žádali jsme pouze o stažení změn, nikoli o jejich uplatnění.
Spusťte však git branch
a git branch --all
, abyste zjistili, ke kterým
větvím máte nyní přístup.
Všimněte si, že přidáním remote nezačne žádná komunikace se vzdáleným
serverem, Git pouze zapíše konfiguraci. Až git fetch
pak skutečně načetl
změny ze vzdáleného serveru. Bez git fetch
bychom neměli žádné informace
o skutečném kódu dostupném na daném vzdáleném serveru.
Porovnávání větví (a jejich mergování)
Nyní prozkoumáme, jak se liší nově přidaný remote.
Začněme zobrazením commitů na remote:
git log remotes/upstream/topic/tests
Jak vidíte, git log
může zobrazit commity pouze v určité větvi (ano,
remotes/...
je ve skutečnosti název větve: koneckonců jste ho viděli v
git branch --all
). A funguje také na souborech (např. git log -- README.md
). Je to vskutku mocný příkaz.
Chtěli jsme se ale podívat, jak se kód liší. To je vlastně ještě důležitější: chcete vidět, jaké změny v kódu byly provedeny a zda bude vůbec možné je mergovat.
git diff remotes/upstream/topic/tests
Měl by se zobrazit patch, kde uvidíte, že nově přidaný remote se liší pouze v jednom: byly přidány automatizované testy.
Vypadají docela dobře – takže je chceme mít i v našem projektu.
Mergněme tedy vzdálenou větev (topic/tests
):
git merge remotes/upstream/topic/tests
Protože nedochází ke konfliktům (tj. obě větve – master
a
remotes/upstream/topic/tests
– změnily různé soubory), mergování by mělo
být automaticky dokončeno.
Zkontrolujte adresář projektu: je v něm soubor tests.bats
?
Všimněte si, že (commit) zprávu o mergování můžete změnit pomocí --amend
.
Konflikty při merge (a jak je řešit)
Stejným způsobem se připravte na mergování (tj. ještě nespouštějte git merge
) s upstream/hotfix/readme-typo
.
Jak jste si pravděpodobně všimli, druhá větev obsahuje opravu překlepu. Ale to už jste opravili (pokud ne, opravte to před mergováním!).
Merge povede k takzvanému konfliktu: dva vývojáři upravili stejný souboru a provedli své individuální úpravy. To musíme vyřešit ručně.
To je zcela běžné a není třeba se toho bát. Git vám dokáže hodně pomoci – pokud dojde ke změnám v různých částech souboru, dokáže je bez problémů sloučit. Když ale obě větve změní stejné řádky, je na vás, abyste to vyřešili. Je to zcela přirozené a byli byste překvapeni, kolikrát je Git schopen sloučit věci automaticky.
Dost bylo teorie, nyní spusťte příkaz merge
:
git merge remotes/upstream/hotfix/readme-typo
Toto mergování skončí chybou a Git vás bude informovat o konfliktu.
Zkontrolujte výstup příkazu merge
. Všimněte si, jak se vám Git snaží
poradit, co lze udělat…
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
Spusťte také git status
a prozkoumejte jeho výstup.
On branch master
[...]
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: README.md
no changes added to commit (use "git add" and/or "git commit -a")
Nyní přichází složitější část celého postupu: je třeba vyřešit konflikt.
Otevřete si README.md
a všimněte si, jak jej pro vás Git
připravil. Označil, kde došlo ke konfliktům a co bylo v každé verzi.
# Group sum utility
<<<<<<< HEAD
This utility allows to sum values in a text file based on their key.
=======
This utility allows to sum values in a text file based on their key; the input
file is expected to be a column-based data file.
>>>>>>> remotes/upstream/hotfix/readme-typo
Imagine `example-data.txt` contains the following.
[...]
Jakmile konflikt vyřešíte (tj. změníte zdrojáky), musíte zavolat git add
(jako při normálním commitu – mergování je koneckonců stále jen
commit), abyste konflikt označili jako vyřešený (resolved).
V tomto případě prostě převezmeme verzi z hotfix/readme-typo
: odstraníme
značky, naší verzi a pak můžeme označit konflikt jako vyřešený
(resolved). Pro programy bude toto zahrnovat typicky i spuštění testů nebo
nějaký jiný způsob, jak zajistit, že byl konflikt správně vyřešen.
git add README.md
Chcete-li mergování dokončit, spusťte příkaz git commit
jako při běžném
commitu.
Nezapomeňte změny nahrát na server.
Jak by nyní vypadalo grafické znázornění commitů v GitLabu?
Před otevřením stránky Graphs v GitLabu si ji zkuste načrtnout na papír.
Shrnutí větvení
Výše uvedená témata představují přibližně 90 % toho, co budete vůbec kdy potřebovat vědět o větvích pro každodenní vývoj.
Nezabývali jsme se pokročilými tématy, jako je přepisování historie, rebasování atd. Vždy si je můžete najít v Git knize.
Zbytek cvičení je věnován některým dalším rozšiřujícím tématům, která ale můžete klidně přeskočit :-).
Konec cvičení obsahuje další příklad, na kterém si můžete vyzkoušet větvení zcela sami.
Zkontrolujte si zda všemu rozumíte
Zcela nesouvisející témata :-)
Následující příklady berte jako exkurzi, že skripty nejsou jen o nudných textových souborech, ale že jejich možnosti jsou nekonečné.
Úlohy k ověření vašich znalostí
Očekáváme, že následující úlohy vyřešíte ještě před příchodem na cvičení, takže se budeme moci o vašich řešeních na cvičení pobavit.
Učební výstupy a kontrola po cvičení
Tato část podává zhuštěný souhrn základních konceptů a dovedností, které byste měli umět vysvětlit a/nebo použít po každém cvičení. Také obsahují absolutní minimum, které je potřebné pro pochopení navazujících cvičení (a dalších předmětů).
Znalosti konceptů
Znalost konceptů znamená, že rozumíte významu a kontextu daného tématu a jste schopni témata zasadit do většího rámce. Takže, jste schopni …
-
vysvětlit rozdíl mezi forkem projektu a klonem (pracovní kopií) repozitáře
-
vysvětlit, co je větev v Gitu
-
vysvětlit, co je feature branch
-
vysvětlit, co je mergování větví v Gitu
-
vysvětlit, co je to merge (pull) request a kdy je užitečný
-
vysvětlit, co je to Git remote
-
vysvětlit, kdy může dojít ke konfliktu při slučování (merge) v Gitu a jak jej lze vyřešit
-
vysvětlit, co se obvykle míní tzv. upstream repozitářem (projektem)
Praktické dovednosti
Praktické dovednosti se obvykle týkají použití daných programů pro vyřešení různých úloh. Takže, dokážete …
-
vytvořit větev v Gitu lokálně pomocí příkazu
git branch
-
nahrát novou větev v Gitu na vzdálený server
-
vytvořit merge request (žádost o začlenění) z feature větve v GitLabu
-
přepínat mezi větvemi (
git checkout
) -
sloučit (merge) lokální větve Gitu pomocí
git merge
-
řešit konflikty při mergování
-
nastavit Git remotes
-
volitelné: používání prográmku
youtube-dl
-
volitelné: používání VLC z příkazové řádky
Seznam změn na této stránce
- 2025-03-24: Poznámka o zvláštních chybách v GitLabu.