Cvičení: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14.

Cílem tohoto cvičení je seznámit vás s Gitem na příkazové řádce a s tím, jak psát opakovaně použitelné skripty. Ukážeme si, jak je Linux vhodný pro interpretované jazyky. A také si výrazně zefektivníme práci s GitLabem a ukážeme si, jak z něj a zpět do něj přenášet soubory prostřednictvím Gitového klienta na příkazovém řádku.

Skriptování v Linuxu

Skript je v Linuxovém prostředí libovolný program, který je interpretován (tj. program je distribuován jako zdrojový kód). V tomto směru pak rozlišujeme shellové skripty (shell je jazyk příkazové řádky), skript v Pythonu, Ruby nebo třeba PHP.

Výhodou tzv. skriptovacích jazyků je že potřebujete pouze textový editor na vývoj a jsou lehce přenositelné. Nevýhodou pak je, že potřebujete nainstalovat i interpretr. Naštěstí, Linux je často dodáván se sadou interpretrů a začít tak s dalším jazykem je vlastně velmi jednoduché.

Jednoduché shellové skripty

Abychom vytvořili shellový skript, stačí psát příkazy do souboru (namísto jejich přímého psaní do terminálu).

Takže, jednoduchý skript, který vypíše informace o systému může vypadat takto.

cat /proc/cpuinfo
cat /proc/meminfo

Pokud tohle uložíte do souboru first.sh, můžete skript spustit následujícím příkazem.

bash first.sh

Všimněte si, že spouštíme bash, což je program s interpretrem, a jméno vstupního souboru (skriptu).

Udělá to, že spustí cat s těmito soubory (mohli bychom samozřejmě pustit cat jen jednou a dát mu dva argumenty).

Vzpomeňte si, že váš project_name.py může být spuštěn následujícím příkazem (opět musíme uvést ten správný interpretr).

python3 factor.py

Shebang a executable (spustitelný) bit

Spouštění skriptů uvedením interpretru (tj. příkazu, který vlastně skript provede) není úplně elegantní. Ale existuje snazší cesta: označíme soubor jako spustitelný a Linux se postará o zbytek.

Ve skutečnosti v okamžiku, kdy spustíme cat nebo mc, tak existuje soubor (typicky v adresáři /bin nebo /usr/bin), který se jmenuje cat či mc a který je označen jako spustitelný. (Můžeme si zatím představovat, že spustitelnost je speciálním atributem souboru). Všimněte si také, že tyto soubory nemají žádnou příponu.

Nicméně, označení souboru jako spustitelného je jen první půlka řešení. Představte si, že vytvoříme následující program a uložíme ho do spustitelného souboru hello.py.

print("Hello")

A teď ho chceme spustit.

Ale počkat! Jak systém pozná, který interpretr má použít? Pro binární aplikace (např. přeložené z Céčkových zdrojáků) je to snadné, protože binárka je (v podstatě) rovnou strojový kód. Ale tady potřebujeme ten správný interpretr.

V Linuxu je interpretr specifikován pomocí tzv. shebangu nebo hashbangu. Už jste se s ním dokonce několikrát potkali: pokud je první řádka skriptu označená pomocí #! (odtud také název: hash a vykřičník), Linux očekává, že tam najde cestu k interpretru, který se má spustit.

Pokud není uveden žádný shebang, chování není dobře definováno.
Linuxový kernel dokonce odmítne spustit skripty bez shebangu. Pokud je ale spustíte z shellu, shell je zkusí interpretovat jako shellové skripty. V praxi na to ale příliš nespoléhejte.

Pro shellové skripty budeme používat #!/bin/bash, pro Python musíme použít #!/usr/bin/env python3. Část s env vysvětlíme později; zatím si jen, prosím, zapamatujte, že ji máte používat.

Všimněte si, že většina interpretrů bere # jako znak kometáře, takže není nijak potřeba řešit, co s první řádkou, která je vlastně přeskočena (protože interpretr jako takový ji vlastně nepotřebuje).

Často se setkáte s #!/bin/sh v shellových skriptech. Pro většinu skriptů je to vlastně jedno: jednoduché konstrukce fungují stejně, ale /bin/bash nabízí některá příjemná rozšíření. V tomto předmětu budeme používat /bin/bash, protože tato rozšíření jsou poměrně užitečná.

Pokud pracujete na starších systémech nebo potřebujete, aby byl váš skript přenositelný na různé verze unixových systémů, může být nutné použít /bin/sh.

Abychom to ještě trochu zkomplikovali, na některých systémech je /bin/sh totéž co /bin/bash, protože se ve skutečnosti jedná o nadmnožinu.

Sečteno a podtrženo: pokud nevíte, co děláte, zůstaňte prozatím u shebangu #!/bin/bash.

Zpátky k původní otázce: jak je skript tedy spuštěn. Systém vezme příkaz z shebangu, přidá k němu název souboru se skriptem jako další parametr a to spustí. Pokud uživatel přidá více argumentů (např. --version), jsou přidány také (na konec).

Například, pokud by hexdump byl shellový skript, začínal by následujícím:

#!/bin/bash

...
kod-co-jde-po-bajtech-a-tiskne-je-bude-tady
...

Spuštění hexdump -C file.gif by tedy doopravdy spustilo následující příkaz:

/bin/bash hexdump -C file.gif

Všimněte si, že vlastně jediná magie za shebangem a spustitelnými soubory je, že systém zkonstruuje delší řádek s příkazem ke spuštění.

A uživatel se nemusí starat o to, který jazyk je vlastně používán.

Vyzkoušejme si to prakticky.

Už ale víme o shebangu, takže soubor upravíme a označíme ho jako spustitelný.

Uložme následující do souboru first.sh.

#!/bin/bash

cat /proc/cpuinfo
cat /proc/meminfo

Abychom jej označili jako spustitelný, spustíme následující příkaz. Prozatím si jej prosím zapamatujte jako kouzlo, které je třeba provést, podrobnější informace o tom, proč to tak vypadá, přijdou později.

chmod +x first.sh
chmod nebude fungovat na souborových systémech, které nejsou určeny pro Unixové/Linuxové systémy. Což bohužel zahrnuje i NTFS.
Webové UI GitLabu nenabízí žádné prostředky pro nastavení executable bitu. Je nutné použít klienta Gitu na příkazové řádce (vizte druhou část tohoto cvičení).

Teď můžeme skript spustit takto:

./first.sh

Nabízí se otázka: proč to přebytečné ./? Vždyť se tím odkazujeme na aktuální adresář (viz předchozí přednáška)? Takže to odkazuje na stejný soubor!

Když použijeme příkaz (např. cat) bez určení cesty (tj. jen holé jméno souboru s programem), shell se podívá do tzv. cesty, která je uložená v proměnné $PATH, aby našel soubor s tímto programem (cesty obvykle bude obsahovat adresář /usr/bin kde najdeme většinu spustitelných souborů). Na rozdíl od jiných operačních systémů se shell nedívá do pracovního adresáře, když program nenajde v $PATH.

Pro spuštění programu v aktuálním adresáři proto musíme specifikovat i jeho cestu (když je soubor uveden s cestou, $PATH se ignoruje a shell se prostě pokusí soubor najít). Naštěstí nemusí být absolutní, ale stačí relativní. Proto ten magický zápis ./.

Přesuneme-li se do jiného adresáře, můžeme program také spustit pomocí relativní cesty, např. ../first.sh.

Spusťte teď ls v aktuálním adresáři. Měli byste vidět soubor first.sh vypsaný zeleně. Pokud ne, zkuste ls --color nebo ověřte, že jste správně spustili chmod.

Nemáte-li barevný terminál (neobvyklé, ale pořád možné), můžete použít ls -F na odlišení typů souborů: adresáře pak budou končit lomítkem, spustitelné soubory hvězdičkou.

Cvičení

Vytvořte skriptu, který vypíše všechny obrazové soubory v aktuálním adresáři (zatím můžete s jistotou předpokládat, že tam vždy nějaké budou). Zkuste jej spustit z různých adresářů pomocí relativní a absolutní cesty. Answer.

Vytvořte skript, který vypíše informace o aktuálně viditelných diskových oddílech v systému. Prozatím zobrazí pouze obsah souboru /proc/partitions. Answer.

Změna pracovního adresáře

Trochu teď skript upravíme.

cd /proc
cat cpuinfo
cat meminfo

Spusťte skript znova.

Všimněte si, že navzdory tomu, že skript změnil adresář na /proc, jsme po jeho ukončení stále v původním adresáři.

Zkuste vložit pwd na ověření, že skript je opravdu uvnitř /proc.

Je důležité si odnést, že každý proces (běžící program; vč. skriptů) má svůj vlastní pracovní adresář. Po spuštění zdědí adresář od toho, kdo jej zavolal (např. shellu, v němž byl spuštěn). Následné změny adresáře ale nijak neovlivní ostatní procesy, takže je po ukončení volající stále ve stejném adresáři.

To také znamená, že samotné cd nemůže být normální program. Protože kdyby to byl normální program (např. v Pythonu), jakákoli změna uvnitř něj by byla po jeho ukončení k ničemu (ztracena).

Proto je cd takzvaný builtin, který je implementován uvnitř samotného shellu.

Ladění skriptů

Chcete-li vidět, co se děje, spusťte skript pomocí bash -x first.sh. Zkuste si to. Pro delší skripty je ale lepší vypisovat vlastní hlášky, protože -x bývá až příliš podrobné.

Pro vypsání hlášky na terminál lze použít příkaz echo. Až na pár výjimek (více o nich později), jsou všechny jeho argumenty jen vypsány.

Vytvořte skript echos.sh s následujícím obsahem a vysvětlete rozdíly:

#!/bin/bash

echo alpha bravo charlie
echo alpha  bravo   charlie
echo "alpha   bravo"   charlie
Answer.

Argumenty na příkazové řádce

Argumenty příkazové řádky (jako například -l pro ls nebo -C pro hexdump) jsou obvyklým způsobem, jak ovládat chování CLI nástrojů v Linuxu. Pro nás, jako vývojáře, je důležité naučit se, jak s nimi uvnitř našich programů pracovat.

O práci s argumenty v shellových skriptech budeme mluvit později, dnes si ukážeme jejich použití v Pythonu.

Přístup k těmto argumentům v Pythonu je jednoduchý. Potřebujeme do programu přidat import sys a poté k nim můžeme přistupovat přes seznam sys.argv.

Následující program tedy vypíše své argumenty.

#!/usr/bin/env python3

import sys

def main():
    for arg in sys.argv:
        print("'{}'".format(arg))

if __name__ == '__main__':
    main()

Při jeho spuštění (samozřejmě poté, co na něj zavoláme chmod +x) uvidíme následující (řádky prefixované $ značí příkaz, zbytek je jeho výstup).

$ ./args.py
'./args.py'
$ ./args.py one two
'./args.py'
'one'
'two'
$ ./args.py "one  two"
'./args.py'
'one  two'

Všimněme si, že nultá položka představuje vlastní název příkazu (ten teď nevyužijeme, ale může být užitečný pro některé chytré triky) a také jak se volání druhého a třetího příkazu liší uvnitř Pythonu.

To by nás ale nemělo překvapit, vzpomeňme si na předchozí cvičení a práci se jmény souborů s mezerami.

Jiné interpretry

Teď si vyzkoušíme, které další interpretry můžeme dát do shebangu.

Vytvořte absolutní (!) cestu (nápověda: man 1 realpath) k args.py, který jsme používali výše. Použijte ji jako shebang v jinak prázdném souboru (např. use-args) a označte jej jako spustitelný. Hint.

Poté jej spusťte takto:

./use-args
./use-args first second

Zjistíte, že argument nula teď obsahuje cestu k vašemu skriptu, argument na pozici jedna obsahuje vnější skript – use-args a až za nimi jsou vlastní argumenty z příkazové řádky (first a second).

Tohle je zásadní – když přidáme shebang, interpretr obdrží vstupní název souboru jako první argument. Jinými slovy – každý Linuxový interpretr musí začít vykonávat program, který dostane jako jméno souboru v prvním argumentu.

Přestože to může vypadat jako cvičení ve zbytečnostech, jde o demonstraci důležitého principu: Linux je extrémně nakloněn vytváření minijazyků. Potřebujete-li vytvořit interpretr pro svůj vlastní minijazyk, stačí jen zařídit, aby přijímal vstupní jméno souboru jako první argument a voilà, uživatelé v něm můžou psát své vlastní spustitelné soubory.

Jako další příklad si připravte následující soubor, uložte jej jako experiment (bez přípony) a označte jej jako spustitelný:

#!/bin/bash

echo Hello

Poznamenejme, že jsme se rozhodli znova úplně zahodit příponu, protože uživatele ve skutečnosti nezajímá jaký jazyk jsme použili. A ono je to stejně zachyceno pomocí shebangu.

Nyní změňte shebang na #!/bin/cat a spusťte program znova. Co se stalo? Spusťte jej s nějakým argumentem (např. jako ./experiment experiment). Co se stalo? Answer.

Změňte shebang na /bin/echo. Co se stalo?

Shebang: zkontrolujte si, zda této části rozumíte

Budeme předpokládat, že my-cat i my-echo jsou spustitelné skripty v aktuálním adresáři.

my-cat obsahuje jako svůj jediný obsah následující shebang #!/bin/cat a my-echo obsahuje pouze #!/bin/echo.

Vyberte všechna pravdivá tvrzení.

You need to have enabled JavaScript for the quiz to work.

Základy Gitu

Dosud byla naše práce s GitLabem výhradně skrze GUI. Teď se přesuneme do příkazové řádky, abychom pracovali trochu efektivněji.

Nezapomeňte, že GitLab, je postaven nad Gitem, což je vlastní verzovací systém.

Git má také klienta na příkazové řádce, který umožní stáhnout celý projekt na váš stroj, sledovat v něm změny a ty pak nahrát zpátky na server (v našem případě GitLab, ale není to jediný takový produkt).

Přestože je možné upravovat soubory on-line v GitLabu, bývá mnohem jednodušší mít je lokálně a používat nějaký lepší editor (příp. IDE). Navíc, ne všechny nástroje mají své on-line protějšky a tak je budete muset spouštět lokálně.

Než se pustíme do samotného Gitu, musíme si na něj trochu připravit prostředí.

Výběr editoru

Git bude často potřebovat spouštět váš editor, základem proto je zajistit, že použije ten, který jste si vybrali.

Následující kroky vysvětlíme podrobněji později, prozatím jen zajistěte, že přidáte následující řádek na konec souboru ~/.bashrc (mcedit v něm nahraďte za vámi vybraný editor):

export EDITOR=mcedit

Otevřete nový terminál a spusťte (včetně znaku dolaru):

$EDITOR ~/.bashrc

Pokud jste soubor upravili správně, měli byste jej opět vidět otevřený ve vašem oblíbeném textovém editoru.

Pokud ne, ujistěte se, že jste skutečně upravili svůj soubor .bashrc (ve svém domovském adresáři) tak, aby obsahoval to, co je uvedeno výše (bez mezer kolem = atd.).

Aby se změny projevily, je potřeba předem zavřít všechny terminály (tedy před použitím Gitových příkazů zmíněných níže).
Nikdy nepoužívejte grafický editor pro $EDITOR, pokud opravdu nevíte, co děláte. Git očekává od editoru určité chování, které grafické editory splňují jen zřídka, zatímco TUI editory tak fungují vždy.
Pokud chcete vědět, proč jsou grafické editory špatnou volbou, vysvětlení je poměrně jednoduché: Git spustí nový editor pro úpravu zprávy o commitu (viz níže) a bude předpokládat, že zpráva je hotová, jakmile editor skončí. Mnoho editorů s grafickým uživatelským rozhraním však pracuje v režimu, kdy je spuštěna jediná instance a vy pouze otevíráte nové karty. V takovém případě se editor spuštěný Gitem ve skutečnosti okamžitě ukončí - pouze řekne stávajícímu editoru, aby otevřel nový soubor - a Git tak vidí pouze prázdnou commit zprávu.

Příkaz git

V podstatě všechno okolo Gitu je řízeno příkazem git. Prvním argumentem je vždy akce – občas se jí říká také podpříkaz –, kterou chceme provést. Například, git config nastavuje Git a git commit vytváří nový commit (verzi).

Vždy je k dispozici nápověda pomocí následujícího příkazu:

git PODPRIKAZ --help

Manuálové stránky jsou dostupné pomocí man git-PODPRIKAZ.

Git má přes 100 podpříkazů. Nepropadejte panice. Začneme s méně než 10 a i poměrně pokročilé funkce nevyžadují znát více než 20 z nich.

Nastavení Gitu

Jedním z klíčových konceptů v Gitu je, že každý commit (změna) má autora – tedy je známo, kdo jej vytvořil. (Git zvládá i kryptografické podepisováni commitů, takže autorství je nezpochybnitelné, ale tím si teď nebudeme látku komplikovat.)

Potřebujeme tedy Gitu říct, kdo jsme. Následující dva příkazy jsou absolutní minimum, co potřebujete spustit na počítači (nebo účtu), kde chcete pracovat s Gitem.

git config --global user.name "Moje skutečné jméno"
git config --global user.email "můj-email"

Přepínač --global říká, že nastavení má být platné pro všechny Gitové projekty. Pro lokální změnu můžete spustit stejný příkaz bez tohoto přepínače uvnitř konkrétního projektu. To může být například užitečné pro odlišení vaší soukromé a firemní identity.

Poznamenejme, že Git neověřuje správnost e-mailové adresy ani vašeho jména (stejně ani není, jak by mohl). Může zde být tedy cokoliv. Pokud ale použijete svou skutečnou e-mailovou adresu, GitLab dokáže spárovat commity s vaším účtem, atp., což může být užitečné. Rozhodnutí je ale na vás.

Pracovní kopie čili working copy (práce s Gitem lokálně)

Úplně první operací, kterou je třeba provést, je tzv. klon (clone). Během klonování se vytvoří kopie zdrojáků ze serveru (GitLab) na místní stroj. Server může pro tuto operaci vyžadovat nějaký druh autentikace (ověření uživatele).

Klonování zkopíruje kompletní historii projektu. Všechny commity jsou vidět i na naklonovaném projektu. Bez potřeby internetového připojení.

Klon se často nazývá pracovní kopií (working copy). Klon je skutečně kopií 1:1 – pokud by někdo projekt vymazal, zdrojové kódy půjde obnovit z klonu (včetně kompletní historie). (To neplatí o Wiki nebo Issues protože ty nejsou Gitem verzované.)

Jak uvidíte, celý projekt z GitLabu se naklonuje jako adresář na vašem disku. Jako obvykle, existují i GUI alternativy k příkazům, které tu budeme ukazovat. My se ale zaměříme jen na CLI variantu.

První klonování (git clone)

Pro následující příklad použijeme váš repozitář s řešeními ve skupině teaching/nswi177/2023.

Otevřete svůj projekt (v prohlížeči) a klikněte na modré tlačítko Clone. Měli byste vidět adresy pro Klonování přes SSH a Klonování přes HTTPS.

Zkopírujte adresu HTTPS a použijte ji v příkazu clone:

git clone https://gitlab.mff.cuni.cz/teaching/nswi177/2023/student-LOGIN.git

Příkaz se vás zeptá na uživatelské jméno a heslo. Jako obvykle v našem GitLabu, použijte prosím přihlašovací údaje do SISu.

Některá prostředí můžou nabízet k použití tzv. klíčenky nebo podobné nástroje na ukládání přihlašovacích údajů. Klidně je používejte. Později se podíváme na to, jak používat SSH a asymetrickou kryptografii pro bezproblémovou práci s projekty Gitu bez potřeby starat se o uživatelská jména a hesla.

Zdá se, že některá prostředí jsou poměrně “vlezlá” co se týče propagace svých klíčenek (a pokud zadáte heslo špatně, neexistuje snadná cesta, jak uložené heslo vygumovat).

Pokud narazíte na chybu HTTP Basic: Access denied. a nezobrazí se žádný prompt, zkuste spustit nejdříve následující (vizte též tuto issue).

export GIT_ASKPASS=""
export SSH_ASKPASS=""
git clone ...

Nyní byste měli mít na svém počítači adresář student-LOGIN. Přesuňte se do něj a podívejte se, jaké soubory tam jsou. A co skryté soubory? Answer.

Neřekneme-li jinak, všechny příkazy budeme vykonávat uvnitř adresáře student-LOGIN.

Jakmile je projekt naklonován, můžete začít upravovat soubory. To je naprosto nezávislé na Gitu – dokud Gitu neřeknete, že má něco udělat, vašich souborů se nijak nedotkne.

Je také důležité zmínit, že Git nestáhne aktualizace ze serveru automaticky. Takže poté co si projekt naklonujete a změníte nějaké soubory přímo na GitLabu, tyto změny se neprojeví na vaší pracovní kopii (dokud si o ně explicitně neřeknete).

Jakmile jste dokončili práci na změnách (např. jste opravili chybu), je na čase Gitu říct o nové verzi (revizi).

Provedení změn (git status a git diff)

Než začnete lokálně měnit jakýkoli soubor, otevřete nový terminál a spusťte git status. Měli byste vidět něco takového.

$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Nyní provedeme triviální změnu. Otevřete soubor README.md ve svém projektu (lokálně, tj. ne v uživatelském rozhraní GitLabu v prohlížeči) a přidejte do něj odkaz na Fórum.

Všimněte si, jak jsou v Markdown vytvořeny odkazy, a přidejte jej jako poslední odstavec.

Po provedení změny spusťte git status. Pozorně si přečtěte celý výstup tohoto příkazu, abyste pochopili, co vlastně vypisuje.

Vytvořte nový soubor 03/editor.txt a vložte do něj název editoru, který jste se rozhodli používat (klidně vytvořte adresář 03 v nějakém grafickém nástroji nebo použijte mkdir 03).

Opět se podívejte, jak git status hlásí tuto změnu v adresáři projektu.

Co jste se naučili? Answer.

Spusťte git diff pro zobrazení toho, jak Git sleduje provedené změny.

Zobrazí se seznam změněných souborů (tj. jejich obsah se liší od poslední revize) a také tzv. diff (někdy také nazývaný záplata čili patch), který popisuje změnu.

Diff bude obvykle vypadat nějak takto:

diff --git a/README.md b/README.md
index 39abc23..61ad679 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,5 @@
 Submit your solutions for all graded tasks and quizzes here.

 See details at course homepage: <https://d3s.mff.cuni.cz/teaching/nswi177/>
+
+Forum is at ...

Jak tohle přečíst? Je to obyčejný text, který obsahuje následující:

  • soubor, kde ke změně došlo
  • kontext změny
    • čísla řádků (-3,3 +3,5)
    • řádky beze změny (začínají mezerou)
  • skutečné změny
    • přidané řádky (začínají +)
    • odebrané rádky (začínají -)

Proč je tento výstup vhodný pro změny ve zdrojovém kódu?

Příkaz git diff je taky extrémně užitečný pro ověření, že provedené změny jsou správné, tím že se zaměřuje jen na kontext změn namísto celých souborů.

Uložení změny natrvalo (git add a git commit)

Jakmile jste se změnami spokojeni, můžete je připravit k zapsání (staging). Což v Gitovštině znamená, že tyto soubory (jejich současný stav) budou v další verzi. Obvykle budete připravovat všechny změněné soubory. Ale občas je lepší commit rozdělit, protože jste pracovali na dvou věcech a nejdřív commitnete první část a teprve pak tu druhou.

Například jste opravovali chybu, ale také jste našli někde nějaký překlep. Můžete samozřejmě obě opravy přidat najednou do jednoho commitu, ale je mnohem lepší udržet commity malé a cílené na jednu věc. Takže první commit bude Oprava chyby XY zatímco druhý bude Oprava preklepu.

Což krásně říká, co se vlastně stalo. Je to trochu podobné tomu, jak vytváříte funkce při programování. Jedna funkce má dělat jednu věc (a dělat ji dobře). Jediný commit má zachycovat jedinou změnu.

Teď se připravte na svůj první commit (pro připomenutí: commit je v podstatě verze, přip. pojmenovaný stav projektu) – spusťte git add 03/editor.txt. O soubor README.md se postaráme později.

Jak to změnilo výstup git stutus? Answer.

Poté co připravíte všechny relevantní změny (tj. git addnete všechny potřebné soubory), můžete vytvořit commit. Commit vyčistí změny připravené k zapsání a můžete začít opravovat další chybu :-).

Vytvořte svůj první commit pomocí git commit. Nezapomeňte pro něj použít výstižnou commit zprávu!

Poznamenejme, že bez přepínačů git commit otevře váš textový editor. Napište do něj commit zprávu, uložte a editor zavřete. Váš první commit je tímto dokončen.

Pro krátké commit zprávy můžete použít git commit -m "Typo fix", kde celá commit zpráva je dána argumentem přepínače -m (všimněte si uvozovek kvůli použití mezery).

Jak bude git status vypadat teď? Zamyslete se nad tím před spuštěním příkazu!

A tohle v podstatě opakujete tak dlouho, dokud máte co měnit. Nezapomeňte, že každý commit by měl zachytit nějaký rozumný stav projektu, ke kterému dává smysl se vracet.

Kdykoli vytvoříte novou verzi, zůstane commit lokální. Není nijak automaticky poslána zpět na server.

Odeslání změn na server

Chcete-li nahrát commity (revize) zpět na server, musíte iniciovat takzvaný push. Ten nahraje všechny nové verze (tj. ty, které byly provedeny mezi vaším naklonováním a nyní) zpět na server. Příkaz je poměrně jednoduchý.

git push

Znovu vás požádá o heslo a poté byste měli vidět své změny v GitLabu.

Které změny jsou na GitLabu? Answer.

Cvičení

Přidejte odkaz na Fórum jako druhý commit provedený z příkazového řádku.

Jako třetí commit vytvořte skript 03/architecture.sh, který obsahuje správný shebang, je spustitelný a vypíše aktuální architekturu (pokud jste tento úkol v předchozím cvičení přeskočili, jednoduše tam spusťte pouze uname nebo si správný přepínač najděte v manuálu teď).

Pošlete změny do GitLabu. Všimněte si, že všechny commity byly poslány najednou.

Prohlížení commitů (git log)

Prozkoumejte, co je v menu Repository -> Commits v GitLabu. Porovnejte to s výstupem git log a git log --oneline.

Ano, příkazy mohou být i takto jednoduché.

Získání změn ze serveru

Ujistěte se, že jste nejprve odevzdali a odeslali všechny změny v lokální (pracovní) kopii do GitLabu.

Změňte nadpis v README.md aby také obsahoval pro VAŠE JMÉNO. Tentokrát ale proveďte změnu na GitLabu.

Pro aktualizaci lokálního klonu projektu použijte git pull.

Jak nejsnadněji zjistíte, jestli máte i změnu v souboru README.md? na vašem počítači po provedení git pull? Answer.

Příkaz git pull je opravdu mocný, dokáže začlenit změny, které vznikly v podstatě ve stejnou dobu na GitLabu a ve vašem lokálním klonu. Porozumění tomuto procesu ale vyžaduje také znalosti větví, což je mimo rámec tohoto cvičení.

Prozatím si tak pamatujte nemíchat lokální změny s těmi v GitLabu (nebo na jiném stroji) aniž byste vždy ukončili práci pomocí git push a začali pomocí git pull.

Práce na více strojích

Věci se trochu zkomplikují pokud pracujete na více počítačích (např. ráno na školním počítači a večer na vašem notebooku).

Git je dost šikovný na to, aby dokázal sloučit vaše změny z různých míst.

Prozatím je však nejlepší zajistit následující postup, aby se minimalizovalo množství nekompatibilních úprav.

Uvědomte si, že pokud se něco hodně pokazí, můžete vždy provést nový klon do jiného adresáře, zkopírovat soubory ručně a odstranit poškozený klon.

Dokud budete pracovat následujícím způsobem, nic se nemůže rozbít:

  1. Naklonujete práci na stroji A.
  2. Pracujete na stroji A (a commitujete).
  3. Push ze stroje A (na server).
  4. Přesunete se na počítač B a tam projekt naklonujete.
  5. Pracujete na stroji B (a commitujete).
  6. Push ze stroje B (na server).
  7. Přesunete se zpět na A a pullnete (ze serveru).
  8. Pracujete na A (commitujete).
  9. Push z A.
  10. Pull na B.
  11. Práce na B.
  12. Atd. (zpátky na bod 5).

Pokud zapomenete na nějaký synchronizační push/pull při přesunu mezi stroji, tak se mohou objevit problémy. Jsou poměrně jednoduše řešitelné, ale my je budeme probírat až později.

Zatím můžete vždy udělat čistý klon a prostě překopírovat změněné soubory a znovu je commitnout (není to to pravé ořechové, tedy Gitové, ale bude to fungovat).

Něco navíc

Příkaz git log zobrazuje spoustu informací, obvykle nás ale zajímají jen ty nejnovější. Použijeme je pro připomenutí, na čem jsme pracovali, atp.

Následující příkaz tak bude dávat větší smysl:

git log --max-count=20 --oneline

Je to ale delší a obtížně zapamatovatelné. Zkuste toto:

git config --global alias.ls 'log --max-count=20 --oneline'

To je ještě horší! S touto magii ale Git náhle začne rozpoznávat následující podpříkaz:

git ls

A to může ušetřit čas.

Naše oblíbené aliasy jsou pro následující příkazy.

st = status
ci = commit
ll = log --format='tformat:%C(yellow)%h%Creset %an (%cr) %C(yellow)%s%Creset' --max-count=20 --first-parent

Zkuste si je nejprve spustit před přidáním do svého Gitu.

Git: zkontrolujte si, že si pamatujete základní příkazy

Vyberte všechna pravdivá tvrzení.

You need to have enabled JavaScript for the quiz to work.

Spouštění testů lokálně

Protože už víte, co jsou shebang, executable bit, a skripty obecně, máte dostatek znalostí, abyste spustili naše testy lokálně bez potřeby GitLabu.

Mělo by to učinit váš vývoj rychlejší a přirozenější, když nebudete muset čekat na GitLab.

Jednoduše spusťte ./bin/run_tests.sh v kořenovém adresáři vašeho projektu a prohlédněte si výsledky.

Můžete také spustit jen konkrétní podmnožinu testů.

./bin/run_tests.sh 03-before
./bin/run_tests.sh 03-post
./bin/run_tests.sh 03-before/architecture

Poznámka: Používate-li vlastní instalaci Linuxu, může být potřeba předem nainstalovat balíček bats (či bash-bats nebo bats-core).

Úlohy před cvičením (deadline: začátek vašeho cvičení, týden 27. února - 3. března)

Následující úlohy musí být vyřešeny a odevzdány před příchodem na vaše cvičení. Pokud máte cvičení ve středu v 10.40, soubory musí být nahrány do vašeho projektu (repozitáře) na GitLabu nejpozději ve středu v 10.39.

Pro virtuální cvičení je deadline úterý 9:00 (každý týden, vždy ráno, bez ohledu na možné státní svátky apod.).

Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).

03/git.txt (40 bodů, skupina git)

Budete potřebovat následující repozitář.

https://d3s.mff.cuni.cz/f/teaching/nswi177/202223/labs/task-03.git/

Repozitář obsahuje více souborů. Zkopírujte ten, který je zmíněný v commit message do 03/git.txt.

Jinými slovy, naklonujte si výše zmíněný repozitář, prohlédněte si existující commity a v jejich textech najdete jméno souboru, který máte zkopírovat do vašeho projektu (jako 03/git.txt).

Automatické testy ověřují jen přítomnost souboru, ne jestli jste zkopírovali ten správný.

03/architecture.sh (30 bodů, skupina shell)

Rozšiřte implementaci z minulého cvičení a napište skript, který vypíše, jakou hardwarovou architekturu má váš počítač.

Ujistěte se, že váš skript má správný shebang a je označen jako spustitelný.

03/editor.txt (30 bodů, skupina git)

Do tohoto souboru uložte název textového editoru, který používáte z příkazového řádku. Uložte tam prostě příkaz, který spouštíte, například joe.

Pokud jste prošli výše uvedený text, máte již hotovo :-).

Úlohy po cvičení (deadline: 19. března)

Očekáváme, že následující úlohy vyřešíte po cvičení, tj. poté, co budete mít zpětnou vazbu k vašim řešením úloh před cvičením.

Všechny úlohy (pokud není explicitně uvedeno jinak) musí být odevzdány přes váš repozitář na úkoly. Pro většinu úloh existují automatické testy, které vám mohou pomoci zkontrolovat úplnost vašeho řešení (zde je popsáno jak číst jejich výsledky).

Používání Gitu přes příkazový řádek (70 bodů, skupina git)

Tato úloha není testovaná automatickými testy na GitLabu.

Potřebujeme vám rozdat hesla k tomuto repozitáři (nechceme jej spojovat s vaším účtem v SIS). Uděláme to během týdne 02. Pro tuto úlohu použijete uživatelské jméno ze SISu/GitLabu ale jiné heslo. Heslo jsme už nahráli do Wiki, která je u vašeho NSWI177 projektu. Informace jsou na stránce nazvané Secrets. Screenshot níže vám pomůže stránku najít.

Budete potřebovat následující repozitář (samozřejmě nahraďte LOGIN svým přihlašovacím jménem do SISu/GitLabu). Využijte heslo z Wiki stránky Secrets (nezapomeňte, že kopírování zafunguje pouhým vybráním textu a vložením ho do terminálu pomocí prostředního tlačítka myši). Tohle URL není určené pro obvyklé webové prohlížení - nedivte se, že ve webovém prohlížeči uvidíte 404.

https://lab.d3s.mff.cuni.cz/nswi177/git-03/LOGIN.git

Po jeho naklonování v něm vytvořte soubor 03.txt.

Vytvořte dva commity nad tímto souborem.

V prvním commitu vložte 2022 jako jeho jediný obsah (tj. do souboru 03.txt).

Jako druhý commit rok upravte na 2023.

Odešlete změny zpátky na server.

03/local.txt (30 bodů, skupina shell)

V této úloze uložíte do tohoto souboru pouze určitý řetězec.

Správnou odpověď vypíší automatické testy, když je spustíte lokálně (tj. pomocí 03-post/local).

Učební výstupy

Učební výstupy podávají 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, co znamená skript (v kontextu Linuxového prostředí)

  • vysvětlit, co je to shebang a jak ovlivní spuštění skriptu

  • chápat rozdíl mezi tím, zda skript má nebo nemá nastavený spustitelný bit

  • vysvětlit, co je pracovní adresář (working directory)

  • vysvětlit proč je pracovní adresář soukromou “vlastností” běžícího programu

  • vysvětlit, jak jsou argumenty (parametry) předané skriptu s shebangem

  • vysvětlit, co je pracovní kopie Gitu (klon, working copy)

  • volitelné: vysvětlit, proč cd nemůže být normální spustitelný soubor jako /usr/bin/ls

  • volitelné: rozumět hlavním rozdílům mezi /bin/sh a /bin/bash shebangy

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 Linuxový skript se správným shebangem

  • nastavit executable bit skriptu pomocí utility chmod

  • přistupovat k argumentům příkazové řádky v Pythonovém skriptu

  • nastavit informace o autorovi v Gitu

  • nastavení výchozího editoru v shellu (nastavení EDITOR v ~/.bashrc)

  • naklonovat Gitový repozitář v shellu přes HTTPS

  • prohlédnout změny v Gitové pracovní kopii (příkaz git status)

  • vytvoření commitu v Gitu z příkazové řádky (příkazy git add a git commit)

  • nahrát nové commity na Git server nebo stáhnout nové do pracovní kopie (za předpokladu projektu s jedním uživatelem, příkazy git push a git pull)

  • prohlédnout si souhrnné informace o předchozích commitech pomocí git log

  • volitelné: upravit si chování Gitu pomocí aliasů

Seznam změn na této stránce

  • 2023-02-27: Varování o správcích hesel a executable bitu v UI GitLabu.

  • 2023-02-24: Přidány detaily o připojení ke Gitovému repozitáři z úlohy po cvičení.