Git Advanced Workshop

Tibor Stanko

1 Úvod

O mne

  • Tibor Stanko, 33 rokov
  • od 2020 dátový inžinier v Zurich Insurance, Bratislava 🇸🇰
  • predtým 6 rokov v akademickej sfére vo 🇫🇷 (PhD, postdoc)
  • rád automatizujem nudné úlohy s pomocou Pythonu 🐍
  • nie som Git guru, no Git používam denne už viac ako 9 rokov
  • moje voľnočasové aktivity: 👨‍👩‍👧‍👦🚲⛰️🎸🎹🍺

Obsah tohto workshopu

2 Vnútro Gitu

Čo sa skrýva vo vnútri Gitu?

Čo je to Git?

  • systém riadenia verzií
  • angl. version control system (VCS) alebo source control management (SCM)
  • zaznamenáva históriu vývoja projektu
  • užitočný pre tímy aj pre jednotlivcov
  • nie je len o kóde, dovoľuje ukladať ľubovoľné súbory (aj netextové)

Ale… Čo je skutočne Git?

  • Git je obsahovo adresovateľný systém súborov
  • To znamená, že adresa súboru (kľúč) je definovaná pomocou jeho obsahu
  • V jadre systému Git sa nachádza jednoduché úložisko údajov, ku ktorým sa dá pristupovať pomocou kľúčov
  • Kľúč = SHA-1 hash , napr. 655a20f99af32926cbf6d8fab092506ddd70e49c

Čo Git ukladá?

Ide najmä o:

  • objekty (objects)
  • referencie (references alebo refs)

Objekty

  1. blob
    • len obsah, žiadne metadáta (cesta, meno)
  2. tree = strom
    • strom obsahuje bloby alebo ďalšie stromy
  3. commit = záznam
    • obsahuje ukazovatele na strom a iný commit (rodič)
  4. tag
    • definuje alternatívne meno pre iný objekt, ktoré môže byť použité na interakciu s objektom namiesto hashu

Každý objekt je identifikovateľný s pomocou svojho SHA-1 hashu.

Referencie = ukazovatele na objekty

  • vetva nie je sled commitov, ale len ukazovateľ (pointer) na určitý commit
cat .git/refs/heads/main
# 7c66409021358486e63d2d40c9b07e2c35e8124d

cat .git/refs/remotes/origin/dev
# c29dc332ac3eebebffc5726e16d0e91df170103f

cat .git/refs/tags/v2.6.3
# d49de0ec577052db3e47e2baf5aff0be738637ac

Tip: v powershelli môžeš namiesto príkazu cat použiť gc (alias pre Get-Content)

Typy príkazov

Porcelain:

  • high-level príkazy, ktoré používa bežný smrteľník
  • commit, log, merge, pull, push, status, …

Plumbing:

  • “core git”
  • low-level príkazy, používané interne Gitom (príp. powerusermi)
  • cat-file, commit-tree, hash-object, ls-files, merge-base, rev-parse, …

Demo

  • powershell
  • .git tree

cd ~
git init test
# Initialized empty Git repository in 
# C:/Users/tibor.stanko/test/.git/
cd test
.git
├── HEAD    ref: refs/heads/main
│
├── objects
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└── refs
    ├── heads
    |
    └── tags

echo "version 1" > test.txt
git status
# On branch main
# No commits yet
#
# Untracked files:
#         test.txt
.git
├── HEAD    ref: refs/heads/main
│
├── objects
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└── refs
    ├── heads
    |
    └── tags

git add test.txt
git status
# On branch main
# No commits yet
#
# Changes to be committed:
#         test.txt
git ls-files --stage
# 100644 594dc0e39bc4468ee19c
#        67e65d37b97eb963b68b 0 test.txt
.git
├── HEAD    ref: refs/heads/main
├── index
├── objects
│   └── 59 blob [test.txt] 'version 1'
│       └── 4dc0e39bc4468ee19c67e65d37b97eb963b68b
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
│
└── refs
    ├── heads
    |
    └── tags

git commit -m "First"
# [main (root-commit) c771cdc] First
#  1 file changed, 0 insertions(+),
#   ... 0 deletions(-)
#  create mode 100644 test.txt
git status
# On branch main
# nothing to commit, working tree clean
.git
├── HEAD    ref: refs/heads/main
├── index
├── objects
│   ├── 59 blob [test.txt] 'version 1'
│   │   └── 4dc0e39bc4468ee19c67e65d37b97eb963b68b
│   ├── 67 tree [blob 594d]
│   │   └── 4d4d31b97233152f3be1825cc9e765fa2b2859
│   └── f8 commit [tree 674d] "First"
│       └── 0a04ee3dfbeb5eb666ade615abc617c1ea20e3
│
│
│
│
│
│
│
│
│
│
│
│
└── refs
    ├── heads
    |   └── main f80a...
    └── tags

mkdir bak
mi test.txt bak
echo "version 2" > test.txt
git add .
git commit -m "Second"
# [main 4ba094f] Second
#  2 files changed, 0 insertions(+), 
#   ... 0 deletions(-)
#  create mode 100644 bak/test.txt
.git
├── HEAD    ref: refs/heads/main
├── index
├── objects
│   ├── 59 blob [test.txt] 'version 1'
│   │   └── 4dc0e39bc4468ee19c67e65d37b97eb963b68b
│   ├── 67 tree [blob 594d]
│   │   └── 4d4d31b97233152f3be1825cc9e765fa2b2859
│   ├── f8 commit [tree 674d] "First"
│   │   └── 0a04ee3dfbeb5eb666ade615abc617c1ea20e3
│   ├── f0 blob [test.txt] 'version 2'
│   │   └── d983103c610431663d84b3012d1b172f2f52ea
│   ├── 37 tree [tree 674d, blob f0d9]
│   │   └── 87931e43c8baf51f3ffafc44f6394651a505ca
│   └── 53 commit [tree 3787, par. f80a] "Second"
│       └── 9f7e662b0fa2ceb0df1dc9332179b06e5cdaec
│
│
│
│
│
│
└── refs
    ├── heads
    |   └── main 539f...
    └── tags

echo "new" > new.txt
git add new.txt
git commit -m "Third"
# [main 62e37a9] Third
#  1 file changed, 0 insertions(+), 
#   ... 0 deletions(-)
#  create mode 100644 new.txt
.git
├── HEAD    ref: refs/heads/main
├── index
├── objects
│   ├── 59 blob [test.txt] 'version 1'
│   │   └── 4dc0e39bc4468ee19c67e65d37b97eb963b68b
│   ├── 67 tree [blob 594d]
│   │   └── 4d4d31b97233152f3be1825cc9e765fa2b2859
│   ├── f8 commit [tree 674d] "First"
│   │   └── 0a04ee3dfbeb5eb666ade615abc617c1ea20e3
│   ├── f0 blob [test.txt] 'version 2'
│   │   └── d983103c610431663d84b3012d1b172f2f52ea
│   ├── 37 tree [tree 674d, blob f0d9]
│   │   └── 87931e43c8baf51f3ffafc44f6394651a505ca
│   ├── 53 commit [tree 3787, par. f80a] "Second"
│   │   └── 9f7e662b0fa2ceb0df1dc9332179b06e5cdaec
│   ├── dc blob [new.txt] 'new'
│   │   └── 334bff12fb7d7404c79935fa3ba535c3bb28d0
│   ├── b0 tree [tree 674d, blob f0d9, blob dc33]
│   │   └── ea95a512bad604278bcc96e8b8e726b462e010
│   └── 62 commit [tree b0ea, par. 539f] "Third"
│       └── e37a96f8f09d0421644817dea320108ceac481
└── refs
    ├── heads
    |   └── main 62e3...
    └── tags

 

.git pre reálny projekt

pybrickz/.git
│   COMMIT_EDITMSG  posledný popis záznamu upravený v lokálnom repozitári
│   config          lokálna konfigurácia, aplikuje sa iba na tento repozitár
│   description     don't worry about it
│   FETCH_HEAD      pamätá si, čo bolo naposledy stiahnuté zo vzdialeného repozitára
│   HEAD            ukazovateľ na aktuálnu vetvu/commit
│   index           binárny zoznam ciest a SHA-1 hashov, obsah zobraz cez `git ls-files --stage`
│   ORIG_HEAD       predchádzajúci stav HEAD, nastavený príkazmi s potenciálne nebezpečným správaním
│   packed-refs     zabalené referencie (heads, tags)
├───hooks […]
├───info […]
├───logs […]
├───objects […]
└───refs […]

.git/objects

pybrickz/.git
│   […]
├───hooks […]
├───info […]
├───logs […]
├───objects  objekty - bloby, stromy (trees), commity
│   ├───00
│   │       57f7cf16175d94fa850ad30918dffcd4cd850c
│   ├───01
│   │       4daec1e8a05a71852209c4caf9750bfe4717b1
...
│   ├───fe
│   │       1c754ef352dece245b5f7a0d7047b048d7b1d9
│   │       8a73f88812537678fde89e91c19c87623ff47c
│   ├───ff
│   │       7e837bf1dc59b8835767fdcf789e308528498a
│   ├───info […]
│   └───pack […]
└───refs […]

.git/refs

pybrickz/.git
│   […]
├───hooks […]
├───info […]
├───logs […]
├───objects […]
└───refs     referencie - vetvy, vzdialené vetvy, tagy
    ├───heads […]
    ├───remotes […]
    └───tags […]

.git/refs/heads

pybrickz/.git
│   […]
├───hooks […]
├───info […]
├───logs […]
├───objects […]
└───refs
    ├───heads
    │       dev
    │       main
    │       staging
    │       ├───bugfix
    │       │       bugfix-1    vetva vytvorená cez `git branch bugfix/bugfix-1`
    │       │       bugfix-2    vetva vytvorená cez `git branch bugfix/bugfix-2`
    │       └───feature
    │               feature-A   vetva vytvorená cez `git branch feature/feature-A`
    │               feature-B   vetva vytvorená cez `git branch feature/feature-B`
    ├───remotes […]
    └───tags […]

.git/refs/remotes

pybrickz/.git
│   […]
├───hooks […]
├───info […]
├───logs […]
├───objects […]
└───refs
    ├───heads […]
    ├───remotes
    │   ├───gh
    │   │       main
    │   └───origin
    │       │   dev
    │       │   HEAD
    │       │   main
    │       ├───bugfix
    │       │       bugfix-2
    │       └───feature
    │               my-awesome-feature-A
    └───tags […]

.git/refs/tags

pybrickz/.git
│   […]
├───hooks […]
├───info […]
├───logs […]
├───objects […]
└───refs
    ├───heads […]
    ├───remotes […]
    └───tags
            v1.0.0
            v1.0.1
            ...
            v2.6.4
            v2.7.0

.git/HEAD

  • HEAD je ukazovateľ na aktuálnu vetvu alebo commit
  • DETACHED HEAD je situácia keď HEAD ukazuje na commit ktorý nie je hlavou vetvy
cat .git/HEAD
# ref: refs/heads/main
git checkout 7c66409
git status
# HEAD detached at 7c66409
# nothing to commit, working tree clean
cat .git/HEAD
# 7c66409021358486e63d2d40c9b07e2c35e8124d

Úlohy (1)

  1. Naklonuj si testovací repozitár:
git clone https://github.com/bbrrck/hello.git 
  1. Z priečinku .git nájdi súbor s hashom na ktorý ukazuje vetva slovak.
  2. Porovnaj hash s výstupom z príkazu git rev-parse slovak.
  3. Viacnásobným použitím príkazu git cat-file -p zisti aký obsah sa nacháda v súbore hello.py na vetve slovak.
    • Hint: ako argument za -p použi hash z predošlého kroku.

Odbočka: Ako rozbaliť git objekty?

Po naklonovaní repozitára sa v priečinku .git/objects nachádzajú všetky objekty, ktoré Git používa, niektoré z nich však môžu byť zabalené v priečinku pack.

git clone https://github.com/bbrrck/hello.git
cd hello
ls .git/objects
# .git/objects/info
# .git/objects/pack
ls .git/objects/pack
# .git/objects/pack/pack-48cae0e3bd98461308f23caeb2cfcc3df0b34da8.idx
# .git/objects/pack/pack-48cae0e3bd98461308f23caeb2cfcc3df0b34da8.pack
# .git/objects/pack/pack-48cae0e3bd98461308f23caeb2cfcc3df0b34da8.rev

Odbočka: Ako rozbaliť git objekty? (2)

Manuálne rozbalenie objektov je možné pomocou príkazu git unpack-objects. Ak však tento príkaz použijeme na súbory z predošlého príkladu, nič sa nestane. Je to preto, lebo Git nerozbalí objekty ktoré sa už nachádzajú v repozitári. Pred rozbalením objektov je preto potrebné ich najprv presunúť do inej časti repozitára.

# Presuň súbory so zabalenými objektami do dočasného priečinku
mkdir temp; mv .git/objects/pack/* temp
# Rozbaľ objekty
cat temp/*.pack | git unpack-objects
# Vymaž dočasný priečinok
rm -rf temp

Mimo experimentovania manuálne rozbaľovanie objektov nie je potrebné.

3 Merge vs. Rebase

Zlučovanie zmien

V Gite existujú dva hlavné spôsoby, ako integrovať zmeny z jednej vetvy do druhej: merge a rebase.

Zlučovanie zmien

Zlúčenie cez merge

  • najjednoduchší spôsob zlučovania vetiev
  • trojcestné zlúčenie medzi dvoma vetvami (napr. main a feature) a ich najnovším spoločným predkom
  • vytvorí nový commit

Zlúčenie cez merge

Zlúčenie cez rebase

  • rebase vetvy feature na vetvu main znamená presunutie začiatku vetvy feature na koniec vetvy main
  • znamená to, že commity z feature budú znova vytvorené na vetve main
  • hlavná výhoda: čistejšia, lineárnejšia história projektu a menej “vidličiek”

Zlúčenie cez rebase

Kedy nepoužívať rebase?

  • nikdy nepoužívajte git rebase na verejných alebo kolaboratívnych vetvách (najmä main)
  • v opačnom prípade môže dôjsť ku zmene alebo dokonca zmazaniu časti histórie

Kedy nepoužívať rebase?

Demo: merge

git clone https://github.com/bbrrck/hello.git hello-merge; cd hello-merge
git merge origin/french
# Auto-merging hello.py
git merge origin/slovak
# CONFLICT (content): Merge conflict in hello.py
# ... vyrieš konflikt ...
git add .
git commit
# [main cef4a72] Merge remote-tracking branch 'origin/slovak'

Demo: rebase (french)

git clone https://github.com/bbrrck/hello.git hello-rebase; cd hello-rebase
git checkout french
git rebase main
# Successfully rebased and updated refs/heads/french.
git checkout main
git merge french
# Updating 0297280..5f6f019
# Fast-forward
#  hello.py | 11 ++++++++++-
#  1 file changed, 10 insertions(+), 1 deletion(-)

Demo: rebase (slovak) - konflikt

git checkout slovak
git rebase -i main
# ... označ prostredný commit ako `fixup` ...
# CONFLICT (content): Merge conflict in hello.py
# ... vyrieš konflikt ...
git add .
git rebase --continue
# Successfully rebased and updated refs/heads/slovak.
git checkout main
git merge slovak # Fast-forward

git log --oneline --graph --all

Merge:

*   cef4a72 (main) Merge branch 'slovak'
|\
| * 163a9c3 (slovak) Add docstring for slovak
| * bd67d8d Fix slovak
| * 75fcf88 Add slovak
* |   bc3f86b Merge branch 'french'
|\ \
| * | a31caf9 (french) Add docstring for french
| * | 6d348f3 Add french
| |/
* / 0297280 Add docstring for default
|/
* 4b4a8ad Add hello.py
* 60d4d94 Initial commit

Rebase:

* ab2fda1 (main, slovak) Add docstring for slovak
* 806b97a Add slovak
* 5f6f019 (french) Add docstring for french
* ea40a3b Add french
* 0297280 Add docstring for default
| * 163a9c3 Add docstring for slovak
| * bd67d8d Fix slovak
| * 75fcf88 Add slovak
|/
| * a31caf9 Add docstring for french
| * 6d348f3 Add french
|/
* 4b4a8ad Add hello.py
* 60d4d94 Initial commit

git log main --oneline

Merge (10):

cef4a72 (main) Merge branch 'slovak'
bc3f86b Merge branch 'french'
0297280 Add docstring for default
163a9c3 (slovak) Add docstring for slovak
bd67d8d Fix slovak
75fcf88 Add slovak
a31caf9 (french) Add docstring for french
6d348f3 Add french
4b4a8ad Add hello.py
60d4d94 Initial commit

Rebase (7):

ab2fda1 (main, slovak) Add docstring for slovak
806b97a Add slovak
5f6f019 (french) Add docstring for french
ea40a3b Add french
0297280 Add docstring for default
4b4a8ad Add hello.py
60d4d94 Initial commit

Úlohy (2)

  1. Naklonuj si k sebe dve kópie testovacieho repozitára:
git clone https://github.com/bbrrck/zoo.git zoo-merge
git clone https://github.com/bbrrck/zoo.git zoo-rebase
  1. V repozitári zoo-merge:
    1. Zlúč cez príkaz git merge vetvy origin/krokodil a origin/gorila do lokálnej vetvy main.
    2. V oboch prípadoch vyrieš vzniknuté konflikty.

(pokračovanie na ďalšom slajde)

Úlohy (2)

  1. V repozitári zoo-rebase:
    1. Prepni sa na vetvu gorila a zlúč na ňu cez príkaz git rebase vetvu main. Vyrieš vzniknuté konflikty.
    2. Prepni sa na vetvu main a zlúč na ňu cez príkaz git merge vetvu gorila.
    3. Prepni sa na vetvu krokodil a zlúč na ňu cez príkaz git rebase -i vetvu main. Prostredný commit označ ako fixup. Vyrieš vzniknuté konflikty.
    4. Prepni sa na vetvu main a zlúč na ňu cez príkaz git merge vetvu krokodil.
  2. S pomocou príkazu git log porovnaj stav oboch repozitárov.
  3. Čo by sa vo výsledku zmenilo, ak by si vynechal(a) krok 3b?

4 Časté otázky a problémy

git revert

git revert HEAD   # odstráň zmeny vykonané v poslednom commite
git revert HEAD~1 # odstráň zmeny vykonané v predposlednom commite
git revert d49de0 # odstráň zmeny vykonané v commite s hashom d49de0

Príkaz git revert vytvorí novú verziu, a nemení históriu repozitára.

git reset

# vráť repozitár do stavu *po* commite s hashom d49de0
git reset --hard d49de0

Príkaz git reset mení históriu repozitára a môže spôsobiť stratu súborov.

reset vs revert vs checkout

Príkaz Kontext Použitie
git reset Commit Zahoď commity v súkromnej vetve alebo zahoď necommitnuté zmeny
git reset Súbor Odstráň súbor z prípravnej zóny (z indexu)
git checkout Commit Presun medzi vetvami alebo prezeranie starých verzií
git checkout Súbor Zahoď zmeny v pracovnom adresári
git revert Commit Vráť commity vo verejnej vetve
git revert Súbor (N/A)

Ako vrátim späť lokálne zmeny?

git commit -m "Something terribly misguided"
git reset HEAD~1
# ... uprav súbory podľa potreby ...
git add .
git commit -c ORIG_HEAD # otvor predošlý popis v commit editore
git commit -C ORIG_HEAD # použi predošlý popis bez otvorenia commit editoru

Ako vrátim späť zmeny ktoré už boli pushnuté?

git commit -m "Something terribly misguided"
git push origin main
git reset HEAD~1
# ... uprav súbory podľa potreby ...
git add .
git commit -C ORIG_HEAD # použi predošlý popis bez otvorenia commit editoru
git push origin main --force-with-lease # nepouživaj '--force'!

Ako vrátim späť časť commitu?

git revert -n $bad_commit  # vráť commit späť, ale neukladaj zmeny
git reset HEAD .           # zruš pridanie zmien
git add --patch .          # pridaj požadované zmeny
git commit                 # vytvor commit z týchto zmien
git checkout -- .          # odstráň ostatné zmeny

Pozn.: Zmeny, ktoré pridávame pomocou príkazu git add --patch, sú zmeny, ktoré chceme vrátiť späť, nie zmeny, ktoré chceme ponechať.

Ako premenujem lokálnu vetvu?

# premenuj aktuálnu vetvu na 'newname'
git branch -m newname

# premenuj vetvu 'oldname' na 'newname'
git branch -m oldname newname

Ako vymažem lokálnu aj vzdialenú vetvu?

git push -d <remote_name> <branch_name>
git branch -d <branch_name>
git fetch --all --prune # vymaž referencie na vymazané vzdialené vetvy

Ako presuniem posledných n commitov na novú vetvu?

Presunutie posledných 3 commitov z main na novú vetvu feature:

git checkout main           # prepni sa na main
git branch feature          # vytvor novú vetvu feature ktorá ukazuje na rovnaký
                            # commit ako main, ale neprepinaj sa na ňu
git reset --hard HEAD~3     # vymaž posledné 3 commity
git checkout feature        # prepni sa na vetvu feature

Ako odstránim súbory z prípravnej zóny?

git rm --cached <file>

Ako zmením popis v už vytvorenom commite?

git commit --amend -m "New commit message"

Ak už bol starý commit pushnutý na remote, po použití git commit --amend je potrebné pushnúť cez git push --force alebo --force-with-lease.

Ako pridám súbory do už vytvoreného commitu?

git add zabudnuty_subor
git commit --amend --no-edit # znovu použi predošlý commit message

Ak už bol starý commit pushnutý na remote, po použití git commit --amend je potrebné pushnúť cez git push --force alebo --force-with-lease.

Ako môžem resetovať alebo vrátiť súbor na konkrétnu verziu?

git checkout c5f567 -- file1/to/restore file2/to/restore

5 Git workflowy = modely vetvenia

V Gite existuje mnoho rôznych workflowov, ktoré sa líšia v tom, ako používajú vetvenie (branching). V tejto kapitole si ukážeme niekoľko najpoužívanejších workflowov a ich výhody a nevýhody.

Aké workflowy existujú?

  • Centralized
  • Feature branch (FB)
  • Trunk-based development (TBD)
  • Gitflow
  • Forking workflow
  • etc.

Centralized workflow

  • všetci vývojári pracujú na jednej vetve (main), žiadne ďalšie vetvy sa nepoužívajú

Výhody:

  • jednoduché pochopenie, implementácia, aj použitie
  • perfektne lineárna história

Nevýhody:

  • riešenie konfliktov môže byť zložité
  • nevyužíva potenciál distribuovaného systému

Feature branching

  • vývoj prebieha na samostatných feature vetvách, ktoré sa následne zlučujú do main vetvy

Výhody:

  • nové funkcie sú vyvíjané izolovane, stabilný main
  • umožňuje používanie pull requestov, code reviews, kolaboratívny vývoj

Nevýhody:

  • potenciálne veľa vetiev
  • pri dlhotrvajúcich vetvách môže byť zložité riešiť konflikty

Trunk-based development

  • podobný feature branching workflowu, ale feature vetvy sú krátke a často mergované do main vetvy (aj niekoľkokrát denne)
  • vhodný v kombinácii s automatickým testovaním a nasadzovaním (CI/CD)

Výhody:

  • kód na hlavnej vetve je vždy release ready

Nevýhody:

  • nutné automatizované testovanie a nasadzovanie
  • vyžaduje zrelý vývojový tím

Trunk-based development

Feature-based deployment can be beneficial for teams that value the isolation of features and are willing to manage the complexities of merging these features back into the mainline. On the other hand, trunk-based deployment is suited for organizations that prioritize rapid integration and releases and have the infrastructure to manage continuous integrations and feature flags.

In recent years, with the rise of DevOps and agile methodologies, there’s been a clear trend towards more frequent integrations and releases. This trend has made trunk-based development, with its emphasis on rapid integration and release, increasingly popular among many tech giants and startups alike. However, as with all methodologies, it’s essential to evaluate the specific needs and capabilities of an organization before adopting a deployment strategy.

Zdieľané vetvy mimo hlavnej línie spôsobujú problémy (merge hell)

Menšie tímy

Väčšie tímy

Gitflow workflow

  • rozšírenie feature branching workflowu o develop a release, a hotfix vetvy
  • účel každej vetvy je jasne definovaný
    • main - produkčná vetva
    • develop - vývojová vetva
    • feature - vývoj nových funkcií
    • release - príprava na vydanie
    • hotfix - oprava chýb v produkčnej verzii

Gitflow workflow

Výhody:

  • všetky výhody feature branching workflowu
  • vhodný pre projekty s dlhším vývojom a pravidelnými releasmi

Nevýhody:

  • veľké množstvo vetiev
  • merge hell

Gitflow is a legacy Git workflow that was originally a disruptive and novel strategy for managing Git branches. Gitflow has fallen in popularity in favor of trunk-based workflows, which are now considered best practices for modern continuous software development and DevOps practices. Gitflow also can be challenging to use with CI/CD.

Gitflow workflow

The overall flow of Gitflow is:

  1. A develop branch is created from main
  2. A release branch is created from develop
  3. Feature branches are created from develop
  4. When a feature is complete it is merged into the develop branch
  5. When the release branch is done it is merged into develop and main
  6. If an issue in main is detected a hotfix branch is created from main
  7. Once the hotfix is complete it is merged to both develop and main

Forking workflow

  • vývojári nemajú priamy prístup k hlavnému repozitáru, ale vytvárajú si fork (kópiu) repozitára, na ktorom pracujú
  • bežne používaný v open-source projektoch

6 Pull Requesty

Čo je to pull request?

  • jeho vytvorením žiadame (request) správcu projektu (maintainer), aby si stiahol (pull) naše zmeny a začlenil ich do projektu
  • môže byť vytvorený vrámci workflowov ako napr. feature alebo forking, ale nie vrámci centralized workflowu
  • umožňuje vývojárom diskutovať o zmene a vykonávať code reviews

Príklady:

7 CI/CD s pomocou Gitu

Čo je to CI/CD?

  • CI = continuous integration
  • CD = continuous delivery

8 SSH autentifikácia

Vytvorenie SSH kľúča

ssh-keygen # use default settings
ssh-keygen -t rsa -C "[email protected]" # compatible with most git providers
ssh-keygen -t ed25519 -C "[email protected]" # compatible with GitHub

Skopírovanie SSH kľúča do schránky

Powershell

Get-Content ~\.ssh\id_ed25519.pub | Set-Clipboard

 

Command Prompt

clip < ~\.ssh\id_ed25519.pub

9 Čo sme sa nenaučili

  • hooks
  • submodules
  • pruning
  • cherry picking
  • LFS = Large File Storage
  • garbage collection (git gc)

Odkazy

sk

Odkazy

en

Git slovník

en sk
branch vetva
clone naklonovanie repozitára
commit záznam
commit message popis záznamu
conflict konflikt medzi verziami
conflict resolution riešenie konfliktov
diff rozdiel medzi verziami
merge zlúčenie vetiev
en sk
pull stiahnutie vzdialených zmien
push odoslanie lokálnych zmien
repository repozitár, úložisko
remote vzdialený repozitár
snapshot snímka
staging area prípravná oblasť (tiež index)
status stav repozitára
version verzia

Git Cheatsheet

# Setup
git config --global user.name "[first last]"
git config --global user.email "[valid-email]"
git init
git clone [url]
# Stage & Snapshot
git status
git add [file]
git reset [file]
git diff
git diff --staged
git commit -m "[descriptive message]"
# Branch & Merge
git branch
git branch [branch-name]
git checkout
git merge [branch]
git log
# Share & Update
git remote add [alias] [url]
git fetch [alias]
git merge [alias]/[branch]
git push [alias]/[branch]
git pull

Ďakujem za pozornosť! 👋