git(gud)

Co to je?
Jak se to používá?
Jak to funguje?

Jan Černohorský

Vojtěch Káně

Co to je?

VCS - Version Control System

CLI vs. GUI

Instalace

Linux

sudo apt install git
sudo zypper install git
sudo yum install git
sudo pacman -Sy git

Advanced masox

brew install git

Widličky a MASOX

https://git-scm.com/downloads

Git Bash - chová se jako na UNIXu

Jak se to používá

Vytvoříme repozitář


					mkdir muj_uzasny_projekt
					cd muj_uzasny_projekt
					git init
				

nebo stáhneme existující


					git clone https://github.com/nekdo/neco.git
					cd neco
				

Provedeme změny

Zacommitujeme


					git add -A
					git commit -m "Přidán seznam pečiva."
				

Pushujeme


					git push
				

nebo


					git push origin master
				

Zjištění stavu repozitáře kdykoliv během práce


					git status
				
90% činností s gitem ↑
git init

Vytvoří prázdný repozitář v aktuální složce

Můžeme

použít v prázdné složce a začít nový projekt

nebo

přidat git do existujícího projektu

git clone
Stáhne repozitář z gitového úložiště (v internetu)
syntax:

					git clone <adresa> [složka]
				

adresa - např. https://gitlab.com/nekdo/neco.git

složka - výchozí je název repozitáře

Autentifikace

SSH vs. HTTPS

HTTPS

obvyklé použití:

bez autentifikace - veřejné repozitáře, read only


pro autentifikaci se musí zadat jméno a heslo při každém připojení

SSH

obvyklé použití:

soukromé repozitáře, přispívání


nutná konfigurace: Connecting to GitHub with SSH

liší se adresami:

HTTPS: https://github.com/nekdo/neco.git

SSH: git@github.com:nekdo/neco.git

git remote
umožňuje přidělit lokálnímu repozitáři vzdálený - tzn. remote

					git remote add origin <adresa>
				

v 99% případů pouze jeden remote - origin

Více remotů:

					git remote add <jméno> <adresa>
				

commit

to commit, one commit, more commits

česky spáchat - nepoužívá se

je jednotka v historii

obsahuje:

  • provedené změny
  • commit message - krátký popis provedených změn
  • metadata (autor, datum, čas ...)
  • svůj otisk - sha1 hash => univerzální identifikátor
  • otisk rodiče(ů)
git status
zobrazí aktuální stav změn

když nenastaly žádné změny od posledního commitu:


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

					nothing to commit, working tree clean
				

nevybrané změny:

vybrané změny:

git add
vybírá, které změny budou zahrnuty v příštím commitu

Vybrání všech změn:


					git add -A
				

Vybrání dle názvu souboru:


					git add cesta/soubor [...cesta/soubor]
				
git commit

vytvoří nový commit

syntax:


					git commit -m "Přidáno pečivo."
				

--amend upravuje předchozí commit


					git commit --amend -m "Přidáno pečivo a taky rohlíky."
				
git push

odesílá změny na remote

syntax:


					git push origin master
				

					git push --set-upstream origin master
				

si zapamatuje, kam změny posíláme, poté stačí


					git push
				
git pull jsem nestihl ☹

Advanced git

Precautions

Branching

Merging

Tato část bude stále poněkud technicky nepřesná, budu se snažit představit koncepty, nikoli internálie gitu.

⚠Precautions⚠

git velmi dobrý v tom neztratit vaše data, ale:

  • stará se pouze o data, která mu náleží (simply: jsou zacommitovaná)
  • git gc

Pak můžete volat všechny rádoby nebezpečné příkazy, jako git reset, nebo git rebase

Branching ⸙

Pojďme experimentovat!

Cyklus pull, commit, push, často funguje velmi dobře, ale jsou situace, kdy nám přivodí vrásky, jako např. paralelní vývoj fíčur.

Větvení nám umožní vytvořit si několik paralelních směrů vývoje, které se nijak neovlivňují, ale můžeme je zase sloučit, až to uznáme za vhodné. Trochu jako zkoušet nové koncepty na pískovišti, a teprve až budou fungovat, se starat o jejich začlenění.

Existují i další důvody, proč s větvemi pracovat (tzv. git workflows), ale o nich někdy jindy.

Prakticky

Přepni na větev mojebranch


					git switch mojebranch #klasičtěji git checkout mojebranch
				

Z aktuální větve vytvoř novou větev novabranch (nezapomeňme se na ni pak přepnout)


					git branch novabranch #vytvoření a přepnutí dohromady se dá též udělat přes git switch -c novabranch, nebo git checkout -b novabranch
				

Zjištění aktuální větve


					git branch #nebo lze vyčíst z výpisu git status
				

Jakmile jsme na větvi, která nám vyhovuje, můžeme normálně používat pull, commit, push. Klidně můžeme chvíli dělat na jedné větvi, pak změny commitnou, přepnout se na jinou větev a tam dělat na něčem jiném. Pull, commit, push, checkout.

Pokud při pushování nové branche narazíme na


					fatal: The current branch vetev has no upstream branch.
					To push the current branch and set the remote as upstream, use

						git push --set-upstream origin vetev
				

řiďme se tím, co radí git a napoprvé použijme


					git push --set-upstream origin vetev
				

Merging

Je načase se znovu setkat.

Merging je opačný proces k větvení. Po té, co jsme benefitovali z izolace, kterou nám větve poskytují, bychom chtěli změny začlenit zpět.

Můžeme rozlišit 3 varianty, co a jak budeme mergovat

  • fast-forward
    • Do branche, ze které jsme se odštípli, nepřibyly žádné commity. Izolace byla, s nadsázkou, zbytečná.
  • non fast-forward, bez konfliktů
    • —||— přibyly nové commity, ale neměnili jsme stejné kusy kódu. Jupí 👍
  • non fast-forward, s konflikty
    • —||— přibyly nové commity, a měnili jsme stejné kusy kódu. Tady bude třeba ruční práce

Na následujících slidech se budu tvářit, že se jedná o úplně jiné případy, ale uvidíme, že postup je skoro stejný a odlišnostmi nás git provede.

fast-forward

Zde není co řešit. Dokonce za nás git naši branch zamlčí, protože není (a nikdy nebyla) potřeba.


					git checkout puvodnibranch #nejprve přepneme na větev **do** které chceme změny začlenit
					git merge odstepenavetev
				

Pokud nechceme naši branch zamlčet


					git checkout puvodnibranch #nejprve přepneme na větev **do** které chceme změny začlenit
					git merge --no-ff odstepenavetev #tím se vytvoří nový commit, který nese informace právě o naší branchi. Git nás vyzve, abychom mu napsali commmit message
				

bez konfliktů

Tady se branch zamlčet nedá a proto musíme i vytvořit nový commit. Naštěstí to vše udělá git za nás.


					git checkout puvodnibranch #nejprve přepneme na větev **do** které chceme změny začlenit
					git merge odstepenavetev #git nás vyzve, abychom napsali commmit message
				

s konflikty

Tady nás čeká ruční práce. Budeme totiž muset rozhodnout, jak změny smíchat dohromady.


					git checkout puvodnibranch #nejprve přepneme na větev **do** které chceme změny začlenit
					git merge odstepenavetev #git zabrečí, že je třeba ruční intervence
					#vyřešení konfliktů
					git add -A #označme konflikty za vyřešené
					git commit #git nás vyzve, abychom napsali commmit message
				

Ono vyřešení konfliktů znamená projít konfliktní soubory (pomůže git status) a upravit je do požadovaného tvaru. Git nám v nich zanechal komentáře, co kdo dělal. Z nich musíme vyjít, konflikt vyřešit a pak je smazat. Pro tyto případy vřele doporučuju použít nějaké GUI, nebo třeba podporu v IDE.

Příklad

V souboru byl nejprve jen Bob. Jedna z větví přidala Alici, druhá Cecila


					<<<<<<< HEAD
					Moji kamarádi jsou: Bob, Alice
					=======
					Moji kamarádi jsou: Bob, Cecil
					>>>>>>> vetev
				

Automaticky merge nelze provést, rozumné výsledky jsou jak Bob, Alice, Cecil, tak Bob, Cecil, Alice.

Ručné soubor upravíme třeba takto a commitneme.


					Moji kamarádi jsou: Bob, Alice. Cecil
				

Advanceder git

  • rebasing
  • stashing
  • resetting
  • advanced merging

Ptejte se, co vás zajímá, prezentace je WIP

Git internals aka advancedest git

Jak to k sakru celé funguje a jak toho využít v náš prospěch?

Q&A, prezentace není a nebude.