Git pro mě/Psaní zdrojového kódu skriptu

Čas od času si potřebuji napsat malý prográmek či skript. Dost často vytvořím základní funkci, kterou vylepším, pak překopám a upravím a zjistím, že mi to nefunguje. V takové chvíli se chci vrátit zpátky na tu základní vylepšenou funkci.

K tomu přesně slouží Git, protože Git ukládá historii změn řádků jednotlivých souborů.

Zaznamenávání změn zdrojového kódu

editovat

Z kapitol Psaní textových poznámek k přednáškám a Psaní semestrální práce v LaTeX vím, jak pomocí Git přidat soubory do historie změn. Jenže psaní kódu je jiné psaní. Důležité jsou totiž řádky, nikoli věty či odstavce.

Při přidávání celých souborů používám

git diff JMENO-SOUBORU

abych viděl změny, které jsem v souboru udělal a

git add JMENO-SOUBORU

pro připravení souboru k zanesení do historie.

Když ale přidávám funkci do skriptu nebo opravuji chybu zdrojového kódu, jde o řádky. Špatné řádky kódu mažu a ty správné přidávám. Abych viděl, které řádky kterých souborů jsem změnil, používám

git diff

a změny jednotlivých řádků připravím k přidání do historie příkazem

git add -p

Příkaz git add -p rozdělí všechny změny, které vidím příkazem git diff, na menší části, ze kterých vyberu, zda změnu chci připravit k přidání do historie ("y") nebo nechci ("n").

Když jsem přidal všechny změny, které spolu souvisí -- což rozhodně nemusí být změny pouze v jednom souboru a naopak, jeden soubor může obsahovat více spolu nesouvisejících změn -- můžu si zkontrolovat, co je připravené k zápisu do historie, příkazem

git diff --cached

a tyto změny do historie zapsat příkazem

git commit -m'52 znaků dokončujících větu'

Jakých 52 znaků dokončujících jakou větu? To je ten nadpis krátkého komentáře ke změně. Ta věta, kterou má nadpis dokončit je "When applied, this patch will ...".

Jaký patch? To je commit. Jaký commit? To jsou ty uložené změny, které mají vlastní IDENTIFIKATOR-ULOZENE-ZMENY.

Vývoj nové funkce

editovat

Často vím, jakou funkci chci přidat. A byl bych rád, kdyby z historie změn bylo na první pohled jasné, které změny jsem pro ni musel udělat.

Dříve už jsem zmínil master (který bude nejspíš brzy main). Je to jako se stromem. Kmen je master a z něj pak jdou různé větve. A jednou z těch větví je jméno funkce, kterou chci přidat.

Novou větev vytvořím příkazem

git branch JMENO-VETVE

přepnu se na ni příkazem

git checkout JMENO-VETVE

a potom vytvářím historii, jak jsem zvyklý, tedy že do historie přidávám změny (commity). A přes git logg sleduji, jak historie vypadá.

No a potom tu novou historii v té nové větvi začlením zpátky do té hlavní, master. Do kmenu. Nejdřív se přepnu na master:

git checkout master

a potom novou větev začlením:

git merge --no-ff JMENO-VETVE

Úplně nejlepší je nakonec větev smazat, aby se mi tam nepletla:

git branch -d JMENO-VETVE

Když se teď podívám na historii, je na první pohled vidět, které změny v historii byly pro funkci potřeba.

Vývoj více funkcí najednou

editovat

Díky větvím je možné vyvíjet více funkcí najednou. Problém ale nastane, když nové funkce, které jsou v různých větvích, potřebují upravit stejný soubor. Dokud takové funkce vyvíjím postupně, problém to není.

Když dvě nové funkce upravují jeden soubor a trefí se do různých řádků, pořád není co řešit. Když jsou ale upravené řádky příliš blízko sebe a já se snažím obě nové funkce začlenit do hlavní (master) větve, Git neví, kterou ze změn kterých nových funkcí má použít. V takovém případě dojde ke konfliktu (merge conflict), který je potřeba vyřešit.

Pravidlo pro řešení konfliktů je "dej tam to, co tam chceš mít". Příkaz git status ukáže, ve kterých souborech konflikty jsou. V souborech se objeví sekce oddělené >>>>>> a ====== a <<<<<<, ze kterých je potřeba dát dohromady kód, který je chtěný. Příkaz git add přidá soubory, ve kterých jsou konflikty již vyřešené a příkaz git merge --continue pokračuje v operaci začlenění nových funkcí.

Musím si poznamenat, že "kód, který je chtěný", znamená "kód chtěný po začlenění konfliktních změn", nikoli "kód chtěný po ukončení operace začlenění" (merge). V sadě změn, kterou se snažím začlenit, může totiž následovat změna, kterou aplikuji na "kód chtěný po začlenění konfliktních změn", čímž dostanu "kód chtěný po ukončení operace začlenění".

No a nakonec

editovat

Takže Git ukládá historii změn řádků jednotlivých souborů.

git diff JMENO-SOUBORU
git diff --cached
git add -p JMENO-SOUBORU
git branch JMENO-VETVE
git checkout JMENO-VETVE
git merge --no-ff JMENO-VETVE
◄ Git pro mě/Psaní semestrální práce v LaTeX Psaní zdrojového kódu skriptu Git pro mě/Psaní zdrojového kódu nové funkce ►