Git
Na přednášce jste se dozvěděli o pokročilejších funcích Gitu, které si nyní vyzkoušíte v praxi. Git už byste měli mít nastavený z minulého cvičení (pokud ne, následujte návod z minulého týdne).
Práce s větvemi
Větve umožňují paralelně pracovat na různých částech projektu, nejčastěji se hodí při spolupráci více vývojářů na jednom projektu.
-
Otevřete si stránku https://learngitbranching.js.org/?NODEMO, kde si můžete interaktivně vyzkoušet práci s větvemi v Gitu a ihned uvidíte, jak vaše příkazy ovlivní historii repozitáře.
- Vytvořte několik commitů na hlavní větvi (
main):git commit - Vytvořte nad větví
mainalespoň dvě nové větve, v každé vytvořte alespoň jeden commit:git branch,git switch- Pozor, aby obě větve začínaly z větve
main(před vytvořením druhé větve se vraťte zpět namain).
- Pozor, aby obě větve začínaly z větve
- Obě větve slučte do větve
mainpomocí příkazugit merge.- Nejdříve se musíte přepnout na větev
main.
- Nejdříve se musíte přepnout na větev
- Vytvořte několik commitů na hlavní větvi (
-
Nyní si práci s větvemi vyzkoušejte v reálném repozitáři:
- Vytvořte nový adresář
ls-pythona inicializujte v něm nový Git repozitář:git init - Stáhněte si soubor ls.py, soubor umístěte do vytvořeného repozitáře a commitněte:
git add,git commit - Script spusťte a ověřte, že funguje, seznamte se se strukturou kódu.
- Vytvořte větev
reverse-order, ve které implementujete podporu pro přepínač-r, který vypíše soubory v opačném pořadí (od Z do A). Změny commitněte. - Vytvořte z větve
maindruhou větevlist-hidden, ve které implementujete přepínač-a, se kterým příkaz vypíše i skryté soubory (začínající tečkou). Změny také commitněte.
- Vytvořte nový adresář
-
Slučte obě větve do větve
main:- Vraťte se zpět na větev
maina pomocígit mergeslučte změny z větvereverse-orderdo hlavní větve. - Slučte i druhou větev
list-hiddendo hlavní větve a vyřešte případné konflikty. - Ověřte, že výsledný kód korektně implementuje oba přepínače.
- Vraťte se zpět na větev
Úpravy historie
Občas se stane, že omylem commitnete změnu, kterou jste v historii nechtěli, například omylem přidanou binárku, nebo soubor s hesly. Git nabízí několik nástrojů, jak historii opravit, které si nyní vyzkoušíte.
-
Stáhněte si archiv pages.zip s připraveným repozitářem a rozbalte do složky
pages. -
Seznamte se zběžně s historií repozitáře:
git log --oneline -
Opravte překlep v posledním commitu (
dvem→dvěma):git commit --amend -
Smažte z posledního commitu omylem přidaný soubor
credentials.json:- Nejdříve commit odstraňte pomocí
git reset --soft HEAD~ - Následně soubor smažte a zbylé změny znovu commitněte
- Nejdříve commit odstraňte pomocí
-
V 5. commitu (od
HEADu) je překlep v commit message (module→modules), pomocígit rebase --interactivepřeklep opravte. -
Vypadá to, že někdo omylem nahrál privátní SSH klíč do repozitáře:
src/labs/08-ssh/ssh-key- Zjistěte, ve kterém commitu byl klíč přidaný.
- Pomocí
git rebase --interactiveagit commit --amendklíč z historie odstraňte. - Ověřte, že už soubor v historii není, porovnejte změny pomocí
git diff ORIG_HEAD.
-
V 6. commitu (
labs/08-ssh: for interested individuals) kolega upravuje stránku cvičení o SSH. Zkombinujte commit s původním commitem, který tuto stránku přidal (výsledkem tedy bude jeden commit). -
Přesuňte commit
labs/08: More detailed SSH key setup descriptionhned za commitlabs/08: Add SSH lab page, reorder labs.
Konflikty a jejich řešení
Konflikt je událost, která nastane, když ve dvou odvětveních modifkujeme soubor na stejném místě, se kterém si algoritmy mergování nedokážou poradit. Za vyřešení konfliktu je poté zodpovědná osoba, která merge dělá (vývojář, project manager, ...).
Na konflikt Vás git upozorní tak, že konfliktní místa označí v příslušných kolidujících souborech. Úkolem zodpovědné osoby je poté konflikt vyřešit.
⚠️ Je potřeba se vždy zamyslet, jaký má být výsledek po mergi. Výsledek si představíme na tom, že mergujete větev do main a vznikne Vám konflikt.
- Představte si, že větev v konfliktu lépe implementuje danou funkcionalitu (např. to v
mainmůžete považovat za zastaralé) - přijmete tedy změnu z větve. - V rámci vaší větve jste experimentálně a dočasně něco změnili, např. aby Vám to lokálně fungovalo, ale víte, že se jedná o dočasnou změnu - přijmete tedy to, co je v
main. - Obě změny jsou správné (v průběhu práce se změnila business logika jak v
maintak ve větvi či jsou oběma případy lépe pokryté okrajové případy) - vyřešení konfliktu je kombinace obou přístupů.
Ponaučení: Řešení konfliktu není jen mechanická záležitost.
Vyřešení konfliktu si ukážeme na příkladě. K tomu si stáhněte soubor conflicts.zip a rozbalte jej do nějakého lokálního adresáře. Objeví se Vám adresář conflicts.
- Koukněte se, co dělají oba soubory. Ve větvi
main(git switch main) se koukněte na funkcisqrt_ratioa zamyslete se nad tím, kde může matematika selhat. - Opravy jsou implementované ve dvou větvích, vylistujte je pomocí
git branch. Obě opravy vycházejí z posledního commitu ve větvimain. - Prohlédněte si jednotlivé úpravy pomocí příkazů
git show <jmeno-featury>. - Slučte tyto změny do
maintak, že se přepnete domaina provedetegit merge <feature-1> <feature-2>. Můžete také provéstgit merge <feature-1>a potégit merge <feature-2>. - Sledujte, co se stalo. Jaké jsou důvody, proč se to stalo? Cvičící Vám ukáže způsoby, jak to vyřešit.
- Nyní si vyzkoušíme příkaz
rebase. Stáhněte si adresář znovu a slučte POUZE jednu z větví namain. Poté se přepněte do větve, kterou jste nesloučili a proveďtegit rebase main. Co nastalo? - Po vyřešení konfliktů v druhé větvi se přepněte zpět do
maina udělejtegit merge <jmeno-vetve>. Merge by měl proběhnout bez konfliktů.
ℹ️ Dodatečná poznámka: příkaz rebase slouží obecně ke změně historie, kdy se série commitů naaplikuje na jiný startovací bod. V režimu -i toho dokáže více, viz minulé cvičení.
Často se tento příkaz využívá, když:
- Pracujete s větvemi, ale potřebujete do své větve zahrnout novější historii, kterou tam nemáte. Řešením je posunout začátek vaší větve na mladší historii.
- (Případ v 6. a 7.): Pokud provedete také rebase vůči větvi, do které chcete mergovat, a vyřešíte během
rebasekonflikty, máte potom jistotu, žegit mergeproběhne bez problému.
ℹ️ Dodatečná poznámka: aby konflikty nenastávaly, je rozumné, aby každý vývojář pracoval pouze na svých souborech a "nelezl ostatním do zelí". To bohužel u větších projektů zajistit nelze, kdy si logicky nezávislé změny začnou mít souborové závislosti (úprava business logiky, definice rozhraní, konfigurační soubory, ...). Proto je důležité umět konflikty řešit.
Vytváření PR (pull request)
Pokud chcete kontribuovat do cizího projektu, je běžné vytvořit tzv. pull request (PR) – žádost o začlenění vašich změn do hlavní větve projektu. Nyní si vyzkoušíte vytvořit svojí kopii ("fork") repozitáře na GitLabu, v něm udělat změny a ty následně přidat do původního repozitáře otevřením pull requestu. Budeme pracovat s repozitářem https://gitlab.fel.cvut.cz/psy/pr-test. Do tohoto repozitáře nemáte právo zapisovat, proto je třeba si nejdříve vytvořit jeho kopii.
-
Vytvořte si kopii ("fork") repozitáře https://gitlab.fel.cvut.cz/psy/pr-test pomocí tlačítka "Fork" vpravo nahoře.
-
Naklonujte si svoji kopii repozitáře na váš lokální počítač:
git clone -
Do souboru
students.mddoplňte ke svému jménu libovolný text, změny commitněte a nahrajte do vašeho GitLab repozitáře:git add,git commit,git push -
Nyní z vašich změn vytvořte nový pull request (v terminologii GitLabu "merge request") do původního repozitáře:
- Otevřete stránku vašeho repozitáře na GitLabu.
- Klikněte na tlačítko "Create merge request" (pokud se nezobrazuje, načtěte stránku znovu).
- Přidejte popisek změn a merge request odešlete.
Bonus: Body za opravy chyb
Stránky předmětu jsou generované z repozitáře https://gitlab.fel.cvut.cz/psy/psy.pages.fel.cvut.cz. Pokud najdete na stránkách předmětu libovolnou chybu (překlep, nejasnost,...) můžete získat až 3 bonusové body za aktivitu (1 bod za každé PR), pokud chybu opravíte a vytvoříte pull request do výše uvedeného repozitáře, který bude schválen vyučujícím. Oprava musí být provedena lokálně na vašem počítači, nikoliv přes webové rozhraní GitLabu.
Než chybu opravíte a vytvoříte PR, zkontrolujte prosím, že už danou chybu neopravil v svém PR nějaký z vašich spolužáků. Pokud najdete více chyb, otevřete prosím pro každou opravu nové PR (smyslem je si procvičit práci s větvemi a forky, nejenom opravit chyby) – v takovém případě chcete každou chybu opravit v jiné větvi, z jedné větve lze vytvořit jen jedno PR.