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

Cílem tohoto cvičení je představit vám klienta Gitu na příkazové řádce a také jak psát znovupoužitelné skripty.

Nezapomeňte, že Čtení před cvičením je povinné a je z něj kvíz, který musíte vyplnit před cvičením.

Čtení před cvičením

Pro dnešní cvičení jsou dvě velká témata. V prvním z nich uvidíte jak se Linux krásně hodí pro interpretované jazyky. Ve druhém si zefektivníme práci s GitLabem a uvidíme, jak lze soubory přenášet z něj a zpátky pomocí klienta na příkazové řádce.

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áš factor.py může být spuštěn následujícím příkazem (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 tam shebang nebude, není chování úplně dobře definováno.

Linuxový kernel je dokonce odmítne spustit. 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).

You will often encounter #!/bin/sh for shell scripts. For most scripts is actually does not matter: simple constructs works the same, but /bin/bash offers some nice extensions. We will be using /bin/bash in this course as the extensions are rather nice.

You may need to use /bin/sh if you are working on older systems or you need to have your script portable to different flavours of Unix systems.

To complicate things a bit more, on some systems /bin/sh is the same as /bin/bash as it is really a superset.

Bottom line is: unless you know what you are doing, stick with #!/bin/bash shebang for now.

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

# Zbytek kodu

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.

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).

Vlastní příkazy probereme během cvičení, tady chceme popsat hlavní operace, které vývojář bude typicky provádět.

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.

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.

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.

Základní průběh práce

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).

Existují i příkazy, které vám umožní si změnu prohlédnout. Uvidíte seznam změněných souborů (ve smyslu, že jejich obsah je odlišný od poslední verze) a můžete také vidět tzv. diff (občas se mu také říká záplatapatch), který popisuje změnu.

Diff bude obvykle vypadat nějak takto:

--- 01/factor.py
+++ 01/factor.py
@@ -2,5 +2,7 @@

 def main():
-    print('-')
+    x = get_number()
+    for i in get_factors(x):
+        print(i)

 if __name__ == '__main__':

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ů (-2,5 +2,7)
    • řádky beze změny (začínají mezerou)
  • skutečné změny
    • přidané řádky (začínají +)
    • odebrané rádky (začínají -)

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ě odráží, co se vlastně dělo.

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.

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

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.

Kdykoliv vytvoříte commit, commit zůstane lokální. Není odeslán na server. Abyste změny odeslali, je potřeba provést tzv. push. Ten nahraje nové commity (tj. ty, co vznikly mezi naklonováním a současností) na server.

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).

Začátek je stejný: vytvoříte si klon na každém stroji. Ale pokud z jednoho počítače pushnete změny, chcete je také dostat na ostatní počítače.

Přímočaré řešení je prostě odstranit pracovní kopii a znovu vše naklonovat. Git je ale mnohem chytřejší a umožní provést inkrementální aktualizaci, která se nazývá pull. Pull zkontroluje poslední změny na serveru, porovná je s pracovní kopií a stáhne jen nové commity.

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).

Kvíz před cvičením

Soubor s kvízem je ve složce 03 v tomto GitLabím projektu.

Zkopírujte si správnou jazykovou mutaci do vašeho projektu jako 03/before.md (tj. budete muset soubor přejmenovat).

Otázky i prostor pro odpovědi jsou v souboru, odpovědi vyplňte mezi značky **[A1]** a **[/A1]**.

Pipeline before-03 na GitLabu zkontroluje, že jste odevzdali odpovědi ve správném formátu. Ze zřejmých důvodů nemůže zkontrolovat skutečnou správnost.

Odevzdejte kvízy před začátkem dalšího cvičení.

Úlohy po cvičení

Tyto budou zveřejněny příští pondělí (stejně jako pro druhé cvičení).

Skripty

Vraťme se zpět k prvnímu příkladu ze čtení před cvičením.

cat /proc/cpuinfo
cat /proc/meminfo

Uložíme-li text do souboru first.sh, můžeme jej spustit následujícím příkazem:

bash first.sh

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

#!/bin/bash

cat /proc/cpuinfo
cat /proc/meminfo

Pro označení za spustitelný použijeme následující příkaz:

chmod +x first.sh

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)?

Když použijeme příkaz (např. cat), shell se podívá do tzv. cesty, která je uložená v proměnné $PATH, aby našel soubor s tímto programem. 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. 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.

Změna pracovního adresáře

Trochu program 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.

Ladění skriptů

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

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:

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é 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?

Git na příkazové řádce

Tato sekce popíše, jak používat Git na příkazové řádce namísto jeho grafické nástavby poskytované GitLabem. Motivaci k použití obojího jsme již popsali na předchozích cvičeních, tady ukážeme, jak přistupovat k souborům z příkazové řádky.

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ě.

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.

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).

Important: never use a graphical editor for $EDITOR unless you really know what you are doing. Git expects a certain behaviour from the editor that is rarely satisfied by GUI editors but is always provided by a TUI-based one.

If you want to know why GUI editors are a bad choice, the explanation is relatively simple: Git will start a new editor a commit message (see below) and it will assume that the commit message is ready once the editor terminates. However, many GUI editors work in a mode where there is single instance running and you only open new tabs. In that case, the editor that is launched by Git actually terminates immediatelly – it only tells the existing editor to open a new file – and Git sees only an empty commit message.

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. Podepisováni commitů zde přeskočíme a nebudeme tak uvažovat padělání/krádež identity.

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 "My real name"
git config --global user.email "my-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 na vás.

První klonování (git clone)

Pro následující příklad použijeme repozitář teaching/nswi177/2022/common/csv-templater.

Nejprve proveďte fork tohoto repozitáře do vlastního jmenného prostoru (v GitLabu přes prohlížeč). Hint.

Vytvoření forku projektu znamená vytvoření vaší vlastní kopie na GitLabu. Vytvořte fork – nepotřebujete k tomu přístup k zápisu do našeho repozitáře a také nechceme, abyste bojovali o stejné soubory.

Otevřete svůj fork projektu 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/YOUR_LOGIN/csv-templater.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 bezešvou práci s projekty Gitu bez potřeby starat se o uživatelská jména a hesla.

Nyní byste měli mít na svém počítači adresář csv-templater. 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 csv-templater.

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

Opravte překlepy na řádku 11 ve skriptu Pythonu a v souboru README.md a spusťte git status před i po změnách. Pozorně si přečtěte celý výstup tohoto příkazu, abyste pochopili, co hlásí.

Vytvořte nový soubor demo/people.csv s aspoň třemi sloupci a 4 řádky. Opět ověřte, jak git status hlásí tuto změnu v adresáři vašeho projektu.

Co jste se naučili? Answer.

Spusťte git diff pro zobrazení toho, jak Git sleduje provedené změny. Proč je tento výstup vhodný pro změny zdrojových kódů?

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)

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 csv_templater.py. O soubor README.md se postaráme později.

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

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.

Odeslání změn na server

Nyní odešleme změny zpět do GitLabu použitím git push. Příkaz se opět zeptá na heslo a poté už byste měli vidět změny na GitLabu.

Které změny jsou na GitLabu? Answer.

Cvičení

Přidejte druhý překlep jako druhý commit z příkazové řádky.

Jako třetí commit přidejte políčko Date do demo/call.txt.

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.

Získání změn ze serveru

Změňte nadpis v README.md aby také obsahoval napsáno v Pythonu. Tentokrát ale proveďte změnu na GitLabu.

Nezapomeňte nejdříve pushnout lokální commity.

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

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.

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.

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 tasks/01/factor
./bin/run_tests.sh tasks/01
./bin/run_tests.sh quizzes/02/before

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

Hodnocené úlohy (deadline: 13. březen)

Počínaje těmito úlohami, nezapomeňte označovat vaše skripty jako spustitelné a vždy přidávat správný shebang. Budou na to speciální testy.

Použití Git CLI (20 bodů)

Použijte git config na dočasnou změnu svého e-mailu na VAS_GITLAB_LOGIN@nswi177.gitlab.mff.cuni.cz (samozřejmě VAS_GITLAB_LOGIN nahraďte tím správným) a udělejte s tímto e-mailem jeden commit do svého repozitáře s hodnocenými úlohami. Můžete třeba vytvořit nový soubor 03/git_cli.txt, nevíte-li, co změnit ;-).

Aktualizace: Tento úkol je kontrolován na GitLab CI. Nicméně, GitLabové testy mohou najednou začít selhávat (tj., nejdříve jsou testy v pořádku a najednou jsou špatně až po několika commitech). GitLab si totiž nenaklonuje celou historii projektu, když spouští pipeline (takže vidí jen posledních pár commitů). My to pak budeme kontrolovat na celé historii, takže to hodnocení neovlivní.

Jinými slovy: pokud tato úloha někdy na GitLabu prošla testy a začala z ničeho nic selhávat někdy později, je to v pořádku.

03/tree.py (30 bodů)

Upravte svůj skript 02/tree.py, aby přijímal jako argument jméno adresáře k vypsání. Není-li žádný argument zadán, měl by stále vypisovat aktuální adresář.

Také přidejte podporu pro přepínač -d, který způsobí vypisování pouze adresářů. Přepínač může být před adresářem k vypsání nebo za ním nebo se může vyskytovat samostatně při vypisování aktuálního adresáře.

03/factor.py (20 bodů)

Přepracujte svůj skript z prvního cvičení, aby načítal číslo jako argument příkazového řádku.

03/architecture.sh (10 bodů)

Aktualizujte skript z předchozího cvičení, aby měl správný shebang a nastavený executable bit.

03/git.txt (20 bodů)

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

https://d3s.mff.cuni.cz/f/teaching/nswi177/202122/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ý.

Učební výstupy

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 jsou argumenty příkazové řádky

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

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

  • vysvětlit, co je pracovní kopii Gitu (klon)

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

  • přistupovat k argumentům příkazové řádky z Pythoního skriptu

  • nastavit Git (jméno a e-mail)

  • naklonovat Gitový repozitář přes HTTPS

  • prohlédnout změny v Gitové pracovní kopii

  • vytvořit commit v Gitovém repozitáři

  • nahrát nové změny na Gitový server (např. GitLab) a stáhnout z něj aktualizace

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

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