Jak používat GIT

Při vývoji aplikací, na kterém se podílí více vývojářů, lze efektivně řídit správu zdrojového kódu prostřednictvím verzovacího systému, v našem případě GITu. Pomocí něj lze také pohodlně zajistit distribuci zdrojového kódu mezi např. domácím počítačem, pracovní stanicí v učebně a vývojovým kitem MZAPO z git repozitáře. Pro potřeby výuky a projektů je na FEL k dispozici správa GIT repozitářů v aplikaci GitLab. Po přihlášení pomocí ČVUTid mohou studenti FEL využívat GitLab pro svoje projekty.

Tato stránka si neklade za cíl naučit práci s gitem, není to ani náplní tohoto předmětu. Nicméně její autoři věří, že je git vhodný nástroj pro sdílení a verzování práce na týmové semestrální práci a de-facto standard v moderním IT. Tato stránka tedy obsahuje alespoň pár tipů k základní práci s gitem a zároveň důraznou radu využít k naučení se gitu některý z obsáhlých návodů na internetu, například v odkazech na konci této stránky.

Základní git příkazy

Nejprve je třeba mít GIT repozitář se kterým chcete pracovat. Můžete si buď vytvořit nový nebo naklonovat stávající. Začneme s naklonováním stávajícího:

git clone url_repozitáře

Příkaz clone vám repozitář naklonuje a uloží do nově vytvořeného adresáře. Nyní se do adresáře přesuňme. Po přesunutí do adresáře můžeme vypsat status příklazem git status. Protože jsme ale neprovedli žádné modifikace, výstup nebude zajímavý. Zkusme tedy modifikovat nepříklad soubor jménem file1. Příkaz git status bude mít následující výstup:

  On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file1

Konkrétní provedené změny pak zobrazíte příkazem git diff. Pokud jste se změnami spokojeni, můžete soubor označit pro zařazení do přístí revize, commitu, neboli verze vašeho kódu příkazem git add file1. Pokud chcete označit jen část změn v daném souboru, zkuste použít git add -p file1 (p jako patch).

Pokud jste označili příkazem git add soubor file1, výstup git status se změní na

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   file1

A označený soubor či soubory budou svítit zeleně. Pokud jste spokojeni se všemi ozačenými soubory a se změnami, které obsahují, můžete vytvořit novou revizi repozitáře příkazem git commit. Tento příkaz vezme označené soubory a přidá je do nové revize kódu označené nově vygenerovaným hashem. Zároveň budete vyzvání k zadání tzv. commit message, neboli krátkého či obsáhleho popisu změn, které jste právě “komitnuli”. Krátký popis můžete příkazu přidat i pomocí přepínače -m následovně:

git commit -m "Pridal jsem dulezite zmeny v souboru file1"

nebo

git commit -m "Blink LED on button press"

A podobně. Dobrý commit je (pokud je to možné) krátký, ucelený a má výstižnou commit message. Dobrý commit přidává jednu ucelenou fukcionalitu nebo její logickou část. Commit by ideálně neměl rozbít například překlad programu. Po vykonání git commit ve výstupu příkazu git status zmizí dříve označené soubory a pokračujete tzv. s čistým štítem:

On branch master
nothing to commit, working tree clean

Pokud jste spokojeni s několika vytvořenými commity, je dobrým zvykem stav lokálního repozitáře odeslat zpět na server z jakého jste repozitář naklonovali. To provede zjednodušeným příkazem git push. Na server se odešlou pouze změny, které jste commitnuli.

Pokud chcete na práci pokračovat druhý den, je možné že Váš týmový kolega mezitím provedl nějaké změny. Tyto změmy si tedy nejprve raději stáhněte abyste nemodifikovali něco, co modifikoval i on. Zjednodušené stáhnutí změn provedete příkazem git pull. Nyní máte aktuální verzi repozitáře a můžete dále pracovat.

Pokud se chcete podívat jaké commity a změny Vás kolega mezitím provedl, můžete použít příkaz git log. Pro zobrazení změn v jednotlivých commitech pak jeho variantu git log -p.

Společná práce

Při společné práci na jednom repozitáři se může snadno stát, že budete s kolegou pracovat současně. Může se tak stát, že on odešle své změny na server zatímco Vy ještě pracujete. Když i Vy později s prací skončíte a budete též chtít odeslat Vaše změny na server, může na Vás vypadnout následující chybová hláška:

To gitlab.fel.cvut.cz:prudemar/apo-seminary.git
 ! [rejected]        dev -> dev (non-fast-forward)
error: failed to push some refs to 'git@gitlab.fel.cvut.cz:prudemar/apo-seminary.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

V takovém případě si musíte nejdřív stáhnout změny, které provedl on a zaintegrovat je do své kopie vývojové větve ještě před změny, které jste provedli sami - příkazem git pull -r. Následně klasickým git push odešlete svoji várku změn a verze na serveru i u Vás bude opět stejná. Pokud na Vás tedy zmíněná hláška vypadne, použijete pro nahrání změn na server tyto příkazy:

  git pull -r
  git push

Uvedený postup funguje pouze pokud jste oba modifikovali jiné soubory nebo alespoň vzdálené řádky ve stejných souborech. Pokud jste modifikovali oba blízké řádky ve stejném souboru, povede tento postup na tzv. merge konflikt, v rámci kterého budete muset vybrat jaké změny chcete zachovat. Práce s tímto stavem není složítá, nicméně je momentálně nad rámec tohoto návodu. V začátcích práce s gitem je tedy lépe se s kolegou domluvit tak, abyste změny na blízkých řádkách daného souboru neprováděli současně.

Z preventivních důvodů je také dobré použít git pull vždy než s prací začnete. Vždy, když s prací skončíte, je vhodné ji odeslat dojicí příkazů git pull -r a git push. Vyhnete se tak většině komplikací.

Tvorba nového repozitáře

Pokud začínáte pracovat na úplně novém projektu a nepoužíváte například šablonu, kterou chcete jen modifikovat, můžete si vytvořit repozitář úplně nový. Repozitář tvoříte pro adresář, ve kterém se momentálně nacházíte příkazem git init. Následně je vhodné jako první soubor přidat příkazem git add například prázný soubor README a vytvořit první “initial” commit příkazem: git commit -m “Initial commit”. Následně pracujete stejně jako s repozitářem naklonovaným. Prostředí jako gitlab Vám při tvorbě nového repozitáře obvykle dají dobrou nápovědu.

Větve

Při práci na větších projektech je běžné, že ruzné týmy pracují na stejném repozítáři na různých fukcionalitách. Aby se navzájem “nerušili”, má git tzv. větve - tedy verze stejného repozitáře, ve kterým můžete commitovat nezávisle na sobě. Pokud je nějterá nová fukcionalita hotova je pak větev ve které je vyvíjena obvykle včleněna do větve hlavní. Hlavní a defaultní větev se v gitu jmenuje master nebo main. S touto větví pracujete ve výchozím stavu aniž byste o ni věděli. Novou větev můžete vytvořit příkazem git branch nova_vetev. Smažete ji prikazem git branch -d nova_vetev. Mezi větvemi se přepínate příkazem git checkout vetev. Pokud chcete nově vytvořenou větev nahrát na server, použijete příkaz:

git push --set-upstream origin nova_vetev

Je to rozšířená verze známého příkazu git push. V tomhle případě navic sdělujete, že chcete pushovat na server označený jako origin (defaultní) a že chcete provést push do jeho větve nova_vetev, kterou tím na serveru založíte. Pokud váš kolega pak použije příkaz git pull, nová větev se mu automaticky stáhne a on se na ni může přepnout.

Mergování větví

Ve chvíli, kdy je práce na dané funkcionalitě u konce, je čas větev, ve které byla vyvíjena, začlenit zpět do větve master. Pro začlenění je nutné se přepnout nejdříve do větve master a pak provést příkaz git merge následovně:

git checkout master
git merge nova_vetev

v tuto chvíli je třeba řící, že pokud změny v obou vetvích modifikovaly stejné (nebo velmi blízké) řádky kódu ve stejných souborech, dojde k tzv. “merge konfliktu” v rámci kterého je třeba vyřešit, které změny se mají použít. Práce s tímto stavem není složítá, nicméně je nad rámec tohoto návodu.

Přejmenování souborů

GIT verzuje soubory podle jejich názvu. Pokud tedy chcete verzovaný soubor přejmenovat, musíte to GITu sdělit. Přejmenování a zároveň oznámení změny GITu můžete provést v jednom kroku příkazem:

git mv stary_nazev novy_nazev

Soubor tím zároveň označíte pro zařazení do příštího commitu pododbě jako příkazem git add. Je dobrý nápad takto například přejmenovat soubor change_me.c použitý v šabloně pro semestrální práci co nejdříve.

Shrnutí uvedených příkazů

git init inicializace nového repozitáře v existujícím adresáři

git clone repo_url nakonování existujícího repozitáře z uvedeného URL

git branch nova_vetev vytvoření nové větve

git checkout nova_vetev přepnutí se na jinou větev

git status výpis aktuálního stavu repozitáře - označené jsou modifikované soubory a soubory označené pro zařazení do následující revize (commitu)

git add file1 file2 označení nových nebo modifikovaných souborů pro zařazení do dalšího commitu

git add -p file1 file2 označení pouze části změn provedených v uvedených souborech pro zařazení do dalšího commitu

git mv stary_nazev novy_nazev přejmenování verzovaného souboru a zároveň jeho označení pro zařazení do dalšího commitu

git commit vytvoření nové revize kódu s označenými soubory

git commit -m “commit message” vytvoření nové revize kódu s označenými soubory, commit message předána parametrem

git log vypsání historie repozitáře commit po commitu

git log -p vypsání historie repozitáře commit po commitu, navíc jsou zobrazeny i změny provedené v každém z commitů

git push odeslání nově vytvořených commitů na server

git push –set-upstream origin nova_vetev odeslání nově vytvořených commitů na server pokud pracujeme v nově vytvořené větvi, která na serveru ještě není

git pull stažení změn ze serveru a sloučení s lokální vývojovou větví

git pull -r stažení změn ze serveru a jejich zařazení do lokální vývojovou větvě ještě před Vámi nezveřejněné commity

git merge nova_vetev včlenění větve nova_vetev do aktivní větve

Merge request v gitlabu

Při práci na reálných projektech je běžné že při ukončení vývoje fukcionality je ještě před zamergováním vývojové větve vytvořen tzv. “merge request”, jinde nazýván “pull request”. Jedná se o prosbu o včlenění dané větve která zároveň souvisí s kontrolou provedených změn.

Merge request je možné vytvořit a zpracovat například pomocí webových rozhraní jako jsou gitlab nebo github. Následující screenshot znázorňuje, odkud je možné merge request vytvořit z přostředí gitlab. Můžete například otevřít seznam větví ve svém repozitáři a přímo si vybrat, pro kterou z větví chcete merge request vytvořit.

Následně zvolte vhodný název merge requestu a ve zkratce popište, jaké změny jste v rámci něj provedli. Zkontrolujte také, že máte vybranou správnou cílovou větev. Při odevzdání semestrálky volte jako cílovou větev větev master svého repozitáře. Jako reviewera volte svého cvičícího a merge request mu zároveň hend přiřaďte. Pokud není řečeno jinak, svou semestrální práci nahrajte do brute až ve chvíli, kdy je merge request v gitlabu vaším cvičícím označen jako Approved. Během procesu kontroly je možné, že Váš cvičící bude mít k práci poznámky a napíše je přímo do merge requestu. Pokud od Vás pak bude chtít reakci, může Vám merge request přiřadit zpět. Vy následně reakci poskytnete a MR přiřadíte opět jemu. Ve chvíli, kdy bude cvičící spokojen, označí MR jako Approved a finálně Vám jej přiřadí. Vy následně můžete vývojovou větev skutečně zamergovat a uploadovat řešení do brute. Pokud bude v zápalu řešení porušena deadline pro odevzdání, nemusí na ní být brán zřetel.

Jak používat GIT s SSH klíčem

Pro pohodlnou práci s GIT repozitářem je doporučeno se vůči Git serveru autentizovat tzv. SSH klíčem.

Pokud ještě nepoužíváte SSH klíč, tak si jej můžete vytvořit (v Linuxu) příkazem ssh-keygen podle návodu v sekci Vzdálený přístup. Ve výchozím nastavení se veřejná a privátní část klíče uloží do adresáře .ssh va vašem domovském adresáři:

ssh-keygen
cat ~/.ssh/id_rsa.pub

Veřejnou část klíče (id_rsa.pub) následně přidáte do svého profilu v GitLabu - v žádném případě nevkládejte privátní část (id_rsa) vašeho klíče:

Ikona vašeho profilu → Settings → SSH keys

Fork v GitLabu

Často se stává, že potřebujete nějak rozšířit či modifikovat projekt, ke kterému ale nemáte práva pro zápis. Můžete mít třeba jen právo pro čtení a být tak schopni si daný projekt naklonovat. Nicméně pokud byste se pokusili provedené změny pushnout, budou zamítnuty. To je příklad třeba linuxového jádra nebo šablony pro práci s deskou MZ_APO. V případě šablony pro práci s deskou MZ_APO byste například rádi do šablony doimplementovali část zabývající se Vaší semestrální prací a rádi byste k ní také sdíleli přístup s vaším týmovým kolegou. Pro tyto účely je tedy nutné si vytvořit vlastní kopii původního repozitáře, ke které budete mít plná přístupová práva. V prostředí GitLab k tomuto účelu slouží tlačítko Fork.

Po kliknutí na tlačítko budete vyzvání k zadání prostoru, kam chcete kopii vytvořit. Standardně ale máte jen jednu možnost - tedy vytořit kopii v rámci vašeho vlastního jmenného prostoru. Pokud byste ale měli větší uživatelská práva, mužete kopii vytvořit napřiklad v jiné GitLab skupině apd.

Nyní předpokládejme, že jste tímto způsobem forknuli repozitář se šablonou MZ_APO pro účely vaší semestrální práce. Je dobrý nápad změnit tedy název a popis repozitáře tak, aby odpovídal tomu, co budete v práci implementovat. Repozitář je také ve výchozím stavu přístupný ke čtení všem. Je tedy vhodné tato práva omezit a nastavit repozitář jako “private”. Toto omezení, stejně jako název repozitáře, je možné nastavit v sekci Settings → General.

Pokud je repozitář nastaven jako “private”, máte k němu přístup pouze Vy a ti, kterým přístup dáte. Musíte tedy přístup přidat například svému týmovému kolegovi nebo cvičícímu pro účely finálního hodnocení práce - pokud tedy budete chtít dostat bonusové body za práci s gitem - viz. rámcové hodnocení práce v článku o semestrální úloze. Pokud je repozitář nastaven jako “Private”, musíte přidělit svému cvičícímu přístup alespoň úrovně “Reporter”. Pokud byste nechali repozitář ve výchozím stavu jako “public” nebo jako “internal”, budou k němu mít přístup pro čtení i Vaši spolužácí a mohou se jím “inspirovat” ve vlastní práci. Taková inspirace pak může být systémem BRUTE vyhodnocena jako plagiátorství - postihnuty jsou pak automaticky obě strany.

GitLab protected branch

Větev master je po vytvoření repozitáře chráněná proti zpětné změně již zapsané historie. Pokud potřebujete z její historie něco odstranit a vydat se jinou cestou, tak je potřeba nastavené ochrany zrušit. Nastavení a rušení ochrany větví se v GitLabu zadává v sekci Settings → Repository → Protected Branches .

Související odkazy

courses/b35apo/documentation/githowto/start.txt · Last modified: 2024/02/02 18:41 (external edit)