Git za hranicemi základů: Workflow, které šetří hodiny každý týden
Interaktivní rebase, cherry-pick, bisect, worktrees, reflog záchrana a strategie větvení, které skutečně fungují. Git příkazy, které používám denně a většina vývojářů o nich neví.
Většina vývojářů se naučí pět Git příkazů a přestane. add, commit, push, pull, merge. Možná checkout a branch, pokud se cítí odvážně. Tím se dostanete přes první rok. Pak má vaše větev 47 commitů se zprávami jako "fix" a "wip" a "prosím funguj", omylem resetujete něco, co jste neměli, a strávíte 40 minut na Stack Overflow snahou odvolat merge, který se pokazil.
Používám Git už léta. Ne příležitostně — intenzivně. Více větví, více repozitářů, více spolupracovníků, celý den, každý den. To, co následuje, jsou příkazy a workflow, které skutečně používám. Ne ty, které vypadají dobře v tutoriálu. Ty, které mi šetří reálný čas, každý týden.
Interaktivní Rebase: Ukliďte si nepořádek, než ho kdokoliv uvidí#
Vaše větev má dvanáct commitů. Polovina z nich je "oprava překlepu". Jeden říká "zrušit předchozí commit". Další říká "tentokrát to opravdu opravit". Chystáte se otevřít PR. Nikdo tuto historii nepotřebuje vidět.
Interaktivní rebase je způsob, jak přepsat historii ve vaší větvi před sdílením. Umožňuje vám slučovat commity dohromady, přepisovat zprávy, přeuspořádávat je nebo je úplně zahodit.
Základní příkaz#
git rebase -i HEAD~5Toto otevře editor zobrazující vašich posledních 5 commitů, nejstarší první:
pick a1b2c3d Add user authentication endpoint
pick d4e5f6g Fix typo in auth middleware
pick h7i8j9k Add rate limiting
pick l0m1n2o Fix rate limit bug
pick p3q4r5s Update auth testsKaždý řádek začíná příkazem. Změňte pick na jeden z těchto:
squash(nebos) — Sloučit tento commit s tím nad ním, zkombinovat zprávyfixup(nebof) — Stejné jako squash, ale zahodit zprávu tohoto commitureword(nebor) — Ponechat commit, ale změnit jeho zprávudrop(nebod) — Smazat tento commit úplněedit(neboe) — Pozastavit rebase u tohoto commitu, abyste ho mohli upravit
Reálná úklidová session#
Zde je, co skutečně dělám. Ta nepořádná historie výše se stane:
pick a1b2c3d Add user authentication endpoint
fixup d4e5f6g Fix typo in auth middleware
pick h7i8j9k Add rate limiting
fixup l0m1n2o Fix rate limit bug
pick p3q4r5s Update auth testsUložte a zavřete. Nyní máte tři čisté commity místo pěti. Oprava překlepu se vloží do auth commitu. Oprava bugu rate limitu se vloží do commitu rate limitu. Váš PR reviewer vidí čistou, logickou progresi.
Přeuspořádání commitů#
Můžete doslova přeuspořádat řádky. Pokud by testovací commit měl být před commitem rate limitingu, prostě přesuňte řádek:
pick a1b2c3d Add user authentication endpoint
pick p3q4r5s Update auth tests
pick h7i8j9k Add rate limitingGit přehraje vaše commity v tomto novém pořadí. Pokud nastanou konflikty, pozastaví se a nechá vás je vyřešit.
Zkratka Autosquash#
Pokud víte, že commit je oprava předchozího, označte ho v době commitu:
git commit --fixup=a1b2c3dToto vytvoří commit se zprávou fixup! Add user authentication endpoint. Pak při rebase:
git rebase -i --autosquash HEAD~5Git automaticky přeuspořádá fixup commity přímo pod jejich cíle a označí je jako fixup. Stačí uložit a zavřít. Žádné ruční upravování.
Toto používám neustále. Je to nejrychlejší způsob, jak iterovat na větvi a přitom udržet konečnou historii čistou.
Zlaté pravidlo#
Nikdy neaplikujte rebase na commity, které byly pushnuty na sdílenou větev. Pokud jiní lidé založili práci na těchto commitech, přepisování historie způsobí skutečné problémy. Aplikujte rebase na své vlastní feature větve před mergem. Nikdy na main.
Pokud jste již pushli svou feature větev a potřebujete rebase:
git push --force-with-leasePříznak --force-with-lease je bezpečnější než --force. Odmítne push, pokud někdo jiný pushl na stejnou větev od vašeho posledního fetch. Nezabrání všem problémům, ale zachytí ten nejčastější.
Cherry-Pick: Chirurgické přenosy commitů#
Cherry-pick vezme konkrétní commit z jedné větve a aplikuje ho na druhou. Není to merge. Není to rebase. Jen jeden commit, čistě aplikovaný.
Kdy to skutečně používám#
Nejčastější scénář: opravil jsem bug na své feature větvi, ale oprava musí jít také na main nebo release větev hned teď. Nechci mergovat celou svou feature větev. Chci jen tu jednu opravu.
# Najděte commit hash opravy
git log --oneline feature/user-auth
# a1b2c3d Fix null pointer in session validation
# Přepněte na main a cherry-pickněte ho
git checkout main
git cherry-pick a1b2c3dHotovo. Oprava je na main jako nový commit se stejnými změnami.
Cherry-Pick bez commitování#
Někdy chcete aplikovat změny, ale ještě je necommitovat. Možná chcete zkombinovat několik cherry-picků do jednoho commitu, nebo změny mírně upravit:
git cherry-pick --no-commit a1b2c3dZměny jsou stagované, ale necommitované. Můžete je upravit, přidat další změny a pak commitovat, až budete připraveni.
Cherry-Pick rozsahu#
Potřebujete více po sobě jdoucích commitů? Použijte syntaxi rozsahu:
git cherry-pick a1b2c3d..f6g7h8iToto cherry-pickne všechno po a1b2c3d až do a včetně f6g7h8i. Poznámka: a1b2c3d samotný je vyloučen. Pokud ho chcete zahrnout:
git cherry-pick a1b2c3d^..f6g7h8iŘešení konfliktů#
Konflikty při cherry-pick fungují jako merge konflikty. Když k jednomu dojde:
# Git vám řekne, že je konflikt
# Opravte konfliktní soubory, pak:
git add .
git cherry-pick --continueNebo pokud si to rozmyslíte:
git cherry-pick --abortJedna věc na pozor: cherry-picknuté commity vytvoří nové commit hashe. Pokud později mergujete původní větev, Git je obvykle dostatečně chytrý, aby duplikaci zvládl. Ale pokud cherry-pickujete agresivně mezi větvemi, které se nakonec budou mergovat, můžete vidět neočekávané konflikty. Používejte to chirurgicky, ne jako strategii mergování.
Git Bisect: Binární vyhledávání bugů#
Něco se rozbilo. Víte, že to fungovalo před dvěma týdny. Od té doby bylo 200 commitů. Který z nich to rozbil?
Mohli byste kontrolovat každý commit ručně. Nebo můžete použít git bisect, který používá binární vyhledávání k nalezení přesného commitingu, který způsobil poruchu, v log2(n) krocích. Pro 200 commitů to je asi 7-8 kontrol místo 200.
Ruční způsob#
# Začněte bisectování
git bisect start
# Označte aktuální commit jako špatný (bug zde existuje)
git bisect bad
# Označte známý dobrý commit (bug zde neexistoval)
git bisect good v2.1.0Git vyčeká commit uprostřed mezi dobrým a špatným. Otestujte ho. Pak:
# Pokud bug na tomto commitu existuje:
git bisect bad
# Pokud bug na tomto commitu neexistuje:
git bisect goodGit zúží rozsah o polovinu pokaždé. Po 7-8 krocích vám řekne:
a1b2c3d4e5f6g7h is the first bad commit
commit a1b2c3d4e5f6g7h
Author: Some Developer <dev@example.com>
Date: Tue Feb 18 14:23:01 2026 +0300
Refactor session handling to use async middlewareNyní víte přesně, který commit zavedl bug. Když jste hotovi:
git bisect resetToto vás vrátí tam, kde jste začali.
Automatizovaný způsob (zde je skutečná síla)#
Pokud máte test, který dokáže detekovat bug, můžete celou věc automatizovat:
git bisect start
git bisect bad HEAD
git bisect good v2.1.0
git bisect run npm test -- --grep "session validation"Git automaticky vyčeká commity, spustí test a označí je jako dobré nebo špatné na základě exit kódu. Nula znamená dobrý, nenulová znamená špatný. Odejděte, vraťte se a řekne vám přesný commit.
Můžete použít jakýkoliv skript:
git bisect run ./test-regression.shKde test-regression.sh je:
#!/bin/bash
npm run build 2>/dev/null || exit 125 # 125 znamená "přeskoč tento commit"
npm test -- --grep "session" || exit 1 # 1 znamená "špatný"
exit 0 # 0 znamená "dobrý"Exit kód 125 je speciální — říká bisectu, aby přeskočil tento commit (užitečné, pokud se commit nezkompiluje). Toto je jedna z těch funkcí, která se zdá být okrajová, dokud ji nepotřebujete, a pak vám ušetří celé odpoledne.
Reálná bisect session#
Zde je, jak to vypadá v praxi:
$ git bisect start
$ git bisect bad HEAD
$ git bisect good abc1234
Bisecting: 97 revisions left to test after this (roughly 7 steps)
[def5678...] Commit message here
$ npm test -- --grep "login flow"
# Testy selžou
$ git bisect bad
Bisecting: 48 revisions left to test after this (roughly 6 steps)
[ghi9012...] Another commit message
$ npm test -- --grep "login flow"
# Testy projdou
$ git bisect good
Bisecting: 24 revisions left to test after this (roughly 5 steps)
...
# Po ~7 iteracích:
abc1234def5678ghi is the first bad commitSedm kroků k nalezení jehly v kupce sena 200 commitů.
Git Worktrees: Více větví, nulové stashování#
Toto je nejméně využívaná funkce Gitu. Jsem přesvědčen, že většina vývojářů neví, že existuje.
Problém: jste hluboko ve feature větvi. Soubory jsou změněné všude. Pak někdo řekne "můžeš se na chvíli podívat na tento produkční bug?" Máte tři možnosti:
- Stashnout všechno, přepnout větve, opravit, přepnout zpět, popnout stash. Doufat, že se nic nepokazí.
- Commitnout vaši nedodělanou práci se zprávou "wip". Ošklivé, ale funkční.
- Naklonovat repo znovu do jiného adresáře.
Nebo možnost 4: worktrees.
Co je Worktree#
Worktree je druhý (nebo třetí, nebo čtvrtý) pracovní adresář propojený se stejným repozitářem. Každý worktree má svou vlastní vyčekanou větev, své vlastní pracovní soubory, svůj vlastní index. Ale sdílejí stejná .git data, takže neduplikujete celé repo.
Přidání Worktree#
# Jste na feature/user-auth, hluboko v práci
# Potřebujete opravit bug na main:
git worktree add ../hotfix-session mainToto vytvoří nový adresář ../hotfix-session s vyčekaným main. Váš aktuální adresář zůstane přesně tak, jak byl. Nic stashnutého, nic commitnutého, nic narušeného.
cd ../hotfix-session
# Opravte bug
git add .
git commit -m "Fix null pointer in session validation"
git push origin main
cd ../my-project
# Pokračujte v práci na vaší funkci, jako by se nic nestaloVytvoření nové větve ve Worktree#
git worktree add ../hotfix-nav -b hotfix/nav-crash mainToto vytvoří worktree A vytvoří novou větev hotfix/nav-crash založenou na main.
Správa Worktrees#
# Výpis všech worktrees
git worktree list
# /home/dev/my-project abc1234 [feature/user-auth]
# /home/dev/hotfix-session def5678 [main]
# Odebrání worktree po dokončení
git worktree remove ../hotfix-session
# Pokud byl adresář již smazán:
git worktree pruneProč je to lepší než Stashování#
Stashování je v pořádku pro rychlé přepnutí kontextu. Ale worktrees jsou lepší pro cokoliv, co trvá déle než pět minut:
- Vaše IDE zůstane otevřené na vaší feature větvi. Žádné přeindexování, žádná ztráta pozice scrollu.
- Můžete spouštět testy v obou adresářích současně.
- Žádné riziko konfliktů stashe nebo zapomenutí, co jste stashnuli.
- Můžete mít dlouho běžící dev server v jednom worktree a čistý build v druhém.
Typicky udržuji dva nebo tři worktrees aktivní: mou hlavní feature větev, main worktree pro rychlé kontroly a někdy review worktree, kde si vyčekám cizí PR.
Jediný háček#
Nemůžete mít stejnou větev vyčekanou ve dvou worktrees. To je záměrné — brání vám to v provádění konfliktních změn na stejné větvi na dvou místech. Pokud to zkusíte, Git odmítne.
Reflog: Tlačítko Zpět pro úplně všechno#
Udělali jste hard reset a přišli o commity. Smazali jste větev. Rebasovali jste a všechno se strašně pokazilo. Myslíte si, že vaše práce je pryč.
Není. Git téměř nikdy skutečně nic nemaže. Reflog je vaše záchranná síť.
Co je Reflog#
Pokaždé, když se HEAD přesune — každý commit, checkout, rebase, reset, merge — Git to zaznamená do reflogu. Je to log všude, kde váš HEAD byl, v pořadí.
git reflogVýstup:
a1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~3
f4e5d6c HEAD@{1}: commit: Add payment processing
b7a8c9d HEAD@{2}: commit: Update user dashboard
e0f1g2h HEAD@{3}: commit: Fix auth token refresh
i3j4k5l HEAD@{4}: checkout: moving from feature/payments to mainKaždý záznam má index (HEAD@{0}, HEAD@{1}, atd.) a popis toho, co se stalo.
Obnova po Hard Reset#
Omylem jste spustili git reset --hard HEAD~3 a přišli o tři commity. Jsou přímo tam v reflogu:
# Podívejte se, co jste ztratili
git reflog
# Commit před resetem je HEAD@{1}
git reset --hard f4e5d6cVšechny tři commity jsou zpět. Krize zažehnána.
Obnova smazané větve#
Smazali jste větev, která měla nezmergovanou práci:
git branch -D feature/experimental
# Ach ne, tam byly dva týdny práceCommity stále existují. Najděte je:
git reflog | grep "feature/experimental"
# Nebo prostě projděte reflog a hledejte poslední commit na té větvi
# Nalezeno. Znovu vytvořte větev na tom commitu:
git branch feature/experimental a1b2c3dVětev je zpět se všemi svými commity.
Obnova po špatném Rebase#
Rebasovali jste a všechno se pokazilo. Konflikty všude, špatné commity, chaos:
# Reflog ukazuje, kde jste byli před rebase
git reflog
# a1b2c3d HEAD@{0}: rebase (finish): ...
# ...
# f4e5d6c HEAD@{5}: rebase (start): checkout main
# b7a8c9d HEAD@{6}: commit: Your last good commit
# Vraťte se před rebase
git reset --hard b7a8c9dJste zpět přesně tam, kde jste byli před začátkem rebase. Jako by se to nikdy nestalo.
30denní záchranná síť#
Ve výchozím nastavení Git uchovává záznamy reflogu 30 dní (90 dní pro dosažitelné commity). Poté mohou být garbage collectovány. Takže máte měsíc na to, abyste si uvědomili, že jste udělali chybu. V praxi je to více než dostatečné.
Můžete zkontrolovat expiraci:
git config gc.reflogExpire
# default: 90.days.ago (pro dosažitelné)
git config gc.reflogExpireUnreachable
# default: 30.days.ago (pro nedosažitelné)Pokud jste paranoidní, zvyšte to:
git config --global gc.reflogExpireUnreachable "180.days.ago"Osobní pravidlo#
Před jakoukoliv destruktivní operací — hard reset, force push, smazání větve — spustím nejprve git log --oneline -10. Mentálně si poznamenám aktuální HEAD. Trvá to dvě sekundy a ušetřilo mě to víc než jednou od paniky, kterou jsem nepotřeboval mít.
Správně Stashujte: Není to jen git stash#
Většina lidí používá stash takto:
git stash
# udělejte něco
git stash popFunguje to, ale je to ekvivalent házení všeho do krabice označené "věci". Když máte tři stashe, nemáte ponětí, co je co.
Pojmenujte své Stashe#
git stash push -m "WIP: validace formuláře autentizace uživatele"Nyní když vypíšete stashe:
git stash list
# stash@{0}: On feature/auth: WIP: validace formuláře autentizace uživatele
# stash@{1}: On main: Pokus o rychlou opravu bugu navigace
# stash@{2}: On feature/payments: Experiment se Stripe webhookyVidíte přesně, co každý stash obsahuje.
Zahrnutí nesledovaných souborů#
Ve výchozím nastavení git stash stashuje pouze sledované soubory. Nové soubory, které jste ještě nepřidali, zůstanou:
# Stashněte všechno, včetně nových souborů
git stash push --include-untracked -m "WIP: nové auth komponenty"
# Nebo dokonce zahrňte ignorované soubory (zřídka potřeba)
git stash push --all -m "Plný snapshot pracovního prostoru"Používám --include-untracked téměř pokaždé. Ponechání nových souborů při přepínání větví způsobuje zmatek.
Částečné stashování#
Tohle je to, o čem většina lidí neví. Můžete stashnout konkrétní soubory:
# Stashněte pouze konkrétní soubory
git stash push -m "Jen změny auth" src/auth/ src/middleware.tsNebo použijte patch režim ke stashnutí konkrétních hunků v souborech:
git stash push --patch -m "Částečné: pouze logika validace"Git projde každou změnu interaktivně a zeptá se, zda ji chcete stashnout. y pro ano, n pro ne, s pro rozdělit hunk na menší kusy.
Apply vs Pop#
# Pop: aplikovat a odebrat ze seznamu stashů
git stash pop stash@{2}
# Apply: aplikovat, ale ponechat v seznamu stashů
git stash apply stash@{2}Používám apply, když si nejsem jistý, zda se stash aplikuje čistě. Pokud je konflikt, stash je zachován. S pop, pokud je konflikt, stash stejně zůstane v seznamu (mnoho lidí to neví), ale preferuji explicitní záměr apply.
Zobrazení obsahu Stashe#
# Podívejte se, jaké soubory se ve stashi změnily
git stash show stash@{0}
# Podívejte se na plný diff
git stash show -p stash@{0}Vytvoření větve ze Stashe#
Pokud se váš stash rozrostl v něco podstatnějšího:
git stash branch feature/auth-validation stash@{0}Toto vytvoří novou větev z commitu, kde jste původně stashovali, aplikuje stash a zahodí ho. Čisté.
Strategie větvení: Která skutečně funguje#
Existují tři mainstreamové strategie větvení. Každá má kontext, kde zářila, a kontexty, kde způsobuje bolest.
Gitflow#
Klasika. main, develop, feature/*, release/*, hotfix/*. Vytvořil Vincent Driessen v roce 2010.
# Feature větev
git checkout -b feature/user-auth develop
# ... práce ...
git checkout develop
git merge --no-ff feature/user-auth
# Release větev
git checkout -b release/2.1.0 develop
# ... finální opravy ...
git checkout main
git merge --no-ff release/2.1.0
git tag -a v2.1.0 -m "Release 2.1.0"
git checkout develop
git merge --no-ff release/2.1.0
# Hotfix
git checkout -b hotfix/session-fix main
# ... oprava ...
git checkout main
git merge --no-ff hotfix/session-fix
git checkout develop
git merge --no-ff hotfix/session-fixKdy to funguje: Mobilní aplikace, desktopový software, cokoliv s pojmenovanými verzovanými releasy a více současně podporovanými verzemi. Pokud dodáváte v2.1 a v3.0 a potřebujete záplatovat obojí, Gitflow to zvládne.
Kdy to nefunguje: Webové aplikace s continuous deployment. Pokud nasazujete do produkce 5krát denně, ceremoniál release větví a develop větví je čistá režie. Většina webových týmů, které adoptují Gitflow, skončí s develop větví, která je permanentně rozbitá, a release větvemi, kterým nikdo nerozumí.
GitHub Flow#
Jednoduché. Máte main. Vytváříte feature větve. Otevíráte PR. Mergujete do main. Nasazujete main.
git checkout -b feature/user-auth main
# ... práce ...
git push origin feature/user-auth
# Otevřete PR, review, merge
# main je vždy nasaditelnýKdy to funguje: Malé až střední týmy dodávající webové aplikace. Continuous deployment. Pokud je main vždy nasazený, tohle je vše, co potřebujete. Používá to i tento web.
Kdy to nefunguje: Když potřebujete udržovat více release verzí, nebo když máte dlouhý QA cyklus před nasazením. GitHub Flow předpokládá, že main jde do produkce rychle.
Trunk-Based Development#
Všichni commitují do main ("trunk") přímo nebo přes velmi krátkodobé větve (méně než den). Žádné dlouhodobé feature větve.
# Krátkodobá větev (zmergovaná ten samý den)
git checkout -b fix/auth-token main
# ... malá, zaměřená změna ...
git push origin fix/auth-token
# PR schválen a zmergován během hodin, ne dnůKdy to funguje: Vysoce výkonné týmy s dobrou CI/CD, komplexními testovacími sadami a feature flagy. Google, Meta a většina velkých technologických firem používají trunk-based development. Vynucuje malé, inkrementální změny a eliminuje merge peklo.
Kdy to nefunguje: Týmy bez dobrého pokrytí testy nebo CI. Pokud mergování do trunku znamená nasazení netestovaného kódu, budete neustále rozbíjet produkci. Také potřebujete feature flagy pro cokoliv, co trvá déle než den na vytvoření:
# Feature flag v kódu
if (featureFlags.isEnabled('new-checkout-flow')) {
renderNewCheckout();
} else {
renderLegacyCheckout();
}Mé doporučení#
Pro většinu webových vývojářských týmů: začněte s GitHub Flow. Je to jednoduché, funguje to a nevyžaduje to nástroje nad rámec toho, co GitHub/GitLab již poskytuje.
Pokud váš tým přeroste 15-20 inženýrů a nasazujete vícekrát denně, podívejte se na trunk-based development s feature flagy. Investice do infrastruktury feature flagů se vrátí v redukovaných merge konfliktech a rychlejší iteraci.
Pokud dodáváte verzovaný software (mobilní aplikace, CLI nástroje, knihovny): Gitflow nebo jeho zjednodušená verze. Ty release větve skutečně potřebujete.
Nevybírejte strategii, protože blogový příspěvek řekl, že je nejlepší. Vyberte tu, která odpovídá tomu, jak skutečně dodáváte.
Git Hooky: Automatizujte věci, na které stále zapomínáte#
Git hooky jsou skripty, které se automaticky spouštějí v konkrétních bodech Git workflow. Jsou lokální na vašem stroji (nepushují se na remote), což znamená, že potřebujete způsob, jak je sdílet s týmem.
Hooky, na kterých skutečně záleží#
pre-commit — Spouští se před každým commitem. Použijte ho pro linting a formátování:
#!/bin/bash
# .git/hooks/pre-commit
# Spusťte ESLint pouze na stagovaných souborech
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(js|ts|tsx)$')
if [ -n "$STAGED_FILES" ]; then
echo "Spouštím ESLint na stagovaných souborech..."
npx eslint $STAGED_FILES --quiet
if [ $? -ne 0 ]; then
echo "ESLint selhal. Opravte chyby před commitem."
exit 1
fi
fi
# Spusťte Prettier na stagovaných souborech
if [ -n "$STAGED_FILES" ]; then
echo "Spouštím Prettier..."
npx prettier --check $STAGED_FILES
if [ $? -ne 0 ]; then
echo "Prettier kontrola selhala. Nejdříve spusťte 'npx prettier --write'."
exit 1
fi
ficommit-msg — Validuje formát commit zprávy. Perfektní pro vynucení conventional commits:
#!/bin/bash
# .git/hooks/commit-msg
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}"
if ! echo "$COMMIT_MSG" | grep -qE "$PATTERN"; then
echo "Neplatný formát commit zprávy."
echo "Očekávaný: type(scope): popis"
echo "Příklad: feat(auth): add session refresh endpoint"
echo ""
echo "Platné typy: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert"
exit 1
fipre-push — Spouští se před pushem. Použijte ho pro testy:
#!/bin/bash
# .git/hooks/pre-push
echo "Spouštím testy před pushem..."
npm test
if [ $? -ne 0 ]; then
echo "Testy selhaly. Push přerušen."
exit 1
fiHusky vs nativní hooky#
Nativní hooky žijí v .git/hooks/. Problém: adresář .git není sledován Gitem, takže nemůžete sdílet hooky přes repo. Každý si je musí nastavit ručně.
Husky to řeší. Ukládá konfigurace hooků v repu a nastaví .git/hooks automaticky při npm install:
npx husky initToto vytvoří adresář .husky/. Přidejte hooky jako soubory:
# .husky/pre-commit
npx lint-stagedV kombinaci s lint-staged získáte rychlé, cílené pre-commit kontroly:
{
"lint-staged": {
"*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.css": ["prettier --write"],
"*.json": ["prettier --write"]
}
}Toto spouští ESLint a Prettier pouze na souborech, které skutečně commitujete. Ne na celém kódu. Rychlé.
Kdy přeskočit hooky#
Někdy potřebujete commitovat bez spuštění hooků. Nouzové hotfixy, work-in-progress commity na vaší vlastní větvi:
git commit --no-verify -m "WIP: debugging produkčního problému"Používejte toto střídmě. Pokud zjistíte, že pravidelně přeskakujete hooky, vaše hooky jsou pravděpodobně příliš pomalé nebo příliš přísné.
Aliasy, které šetří čas#
Můj .gitconfig se vyvíjel léta. Toto jsou aliasy, které přežily — ty, které skutečně používám denně, ne ty, které jsem přidal, protože vypadaly chytře.
Přehledný log#
Výchozí git log je ukecaný. Toto vám dá čistý, barevný zobrazení s grafem:
git config --global alias.lg "log --oneline --graph --all --decorate"Použití:
git lg
# * a1b2c3d (HEAD -> main) Fix session validation
# | * d4e5f6g (feature/payments) Add Stripe integration
# | * h7i8j9k Update payment models
# |/
# * l0m1n2o Merge PR #42
# * p3q4r5s Add user dashboardToto spouštím 20krát denně. Je to nejrychlejší způsob, jak porozumět stavu vašeho repozitáře.
Odvolání posledního commitu#
Ponechat změny, jen odvolat commit:
git config --global alias.undo "reset HEAD~1 --mixed"Použití:
git undo
# Commit je pryč, ale všechny změny jsou stále ve vašem pracovním adresářiPoužívám toto, když commitnu příliš brzy, zapomenu soubor nebo chci restrukturalizovat změny.
Unstagování všeho#
git config --global alias.unstage "reset HEAD --"Použití:
git unstage src/auth/session.ts
# Soubor je unstagován, ale změny jsou zachoványVýpis všech aliasů#
Protože zapomenete, co jste nastavili:
git config --global alias.aliases "config --get-regexp ^alias\\."Další aliasy, které používám#
# Zobrazit, co se chystáte commitnout
git config --global alias.staged "diff --staged"
# Krátký status
git config --global alias.st "status -sb"
# Amend bez změny zprávy
git config --global alias.amend "commit --amend --no-edit"
# Zobrazit poslední commit
git config --global alias.last "log -1 HEAD --stat"
# Pull s rebase místo merge
git config --global alias.up "pull --rebase --autostash"
# Smazat větve, které byly zmergované do main
git config --global alias.cleanup "!git branch --merged main | grep -v '^[ *]*main$' | xargs git branch -d"Alias up je obzvláště dobrý. pull --rebase udržuje vaši historii lineární místo vytváření merge commitů pro každý pull. --autostash automaticky stashne a obnoví vaše změny, pokud máte neuložené soubory. Je to to, čím by pull měl být ve výchozím nastavení.
Alias cleanup smaže lokální větve, které byly zmergované do main. Časem se nahromadí desítky zastaralých větví. Spouštějte toto týdně.
Příkazy, které používám denně#
Toto nejsou aliasy ani pokročilé funkce. Jsou to prostě příkazy, které neustále spouštím a o kterých mnoho vývojářů zřejmě neví.
Ultimátní příkaz Log#
git log --oneline --graph --allToto zobrazí každou větev, každý merge, celou topologii vašeho repa v kompaktním zobrazení. Je to první věc, kterou spustím, když stáhnu změny. Odpovídá na "co se děje v tomto repu právě teď?"
Diff stagovaných změn#
git diff --stagedToto zobrazí, co se chystá být commitnuto. Ne co se změnilo ve vašem pracovním adresáři — co je skutečně stagované. Toto spouštím vždy před commitem. Vždy. Zachytí to náhodná zahrnutí, debug příkazy, console.logy, které tam nemají být.
# Zobrazit nestagované změny
git diff
# Zobrazit stagované změny
git diff --staged
# Zobrazit obojí
git diff HEADZobrazení konkrétního commitu#
git show a1b2c3dZobrazí plný diff jednoho commitu. Užitečné při procházení historie, pochopení, co commit skutečně změnil.
# Zobrazit pouze změněné soubory
git show --stat a1b2c3d
# Zobrazit konkrétní soubor v konkrétním commitu
git show a1b2c3d:src/auth/session.tsTen poslední je neuvěřitelně užitečný. Můžete zobrazit jakýkoliv soubor v jakémkoliv bodě historie bez vyčekání toho commitu.
Blame s rozsahem řádků#
git blame -L 42,60 src/auth/session.tsZobrazí, kdo naposledy upravil řádky 42-60. Užitečnější než blame celého souboru, což je obvykle ohromující.
# Zobrazit také commit zprávu, ne jen hash
git blame -L 42,60 --show-name src/auth/session.ts
# Ignorovat změny mezer (velmi užitečné)
git blame -w -L 42,60 src/auth/session.ts
# Zobrazit commit před viněným (kopat hlouběji)
git log --follow -p -- src/auth/session.tsPříznak -w je důležitý. Bez něj blame připíše řádky tomu, kdo naposledy přeformátoval soubor, což je zřídka osoba, kterou hledáte.
Najít řetězec napříč celou historií#
# Najít, kdy byla funkce přidána nebo odebrána
git log -S "validateSession" --oneline
# Najít, kdy se objevil regex pattern
git log -G "session.*timeout" --oneline-S ("pickaxe") najde commity, kde se změnil počet výskytů řetězce. -G najde commity, kde diff odpovídá regexu. Oba jsou mocné pro archeologii — zjišťování, kdy bylo něco zavedeno nebo odebráno.
Zobrazit co se změnilo mezi dvěma body#
# Co se změnilo mezi dvěma větvemi
git diff main..feature/auth
# Co se změnilo na této větvi od odchýlení od main
git diff main...feature/auth
# Vypsat pouze změněné soubory
git diff main...feature/auth --name-only
# Statistický pohled (soubory + vložení/smazání)
git diff main...feature/auth --statDvě tečky vs tři tečky záleží. Dvě tečky zobrazí rozdíl mezi špičkami obou větví. Tři tečky zobrazí, co se změnilo na pravé straně od odchýlení od levé strany. Tři tečky je obvykle to, co chcete při review feature větve.
Vyčištění nesledovaných souborů#
# Podívejte se, co by bylo smazáno (dry run)
git clean -n
# Smazat nesledované soubory
git clean -f
# Smazat nesledované soubory a adresáře
git clean -fd
# Smazat nesledované a ignorované soubory (jaderná možnost)
git clean -fdxVždy spusťte s -n nejdříve. git clean -fdx smaže vaše node_modules, .env, build artefakty — všechno, co není sledováno Gitem. Užitečné pro skutečně čistý začátek, ale destruktivní.
Obnovit jediný soubor z jiné větve#
# Získejte verzi souboru z main větve bez přepínání větví
git restore --source main -- src/config/database.tsNebo z konkrétního commitu:
git restore --source a1b2c3d -- src/config/database.tsToto je čistší než stará syntaxe git checkout main -- path/to/file a neovlivňuje HEAD.
Sestavení celku: Reálný Workflow#
Zde je, jak vypadá typický den s těmito nástroji:
# Ráno: zkontrolujte, co se děje
git lg
git fetch --all
# Začněte feature
git checkout -b feature/session-refresh main
# Pracujte, commitujte inkrementálně
git add -p # Stagujte konkrétní hunky, ne celé soubory
git commit -m "Add token refresh endpoint"
git commit -m "Add refresh token rotation"
git commit -m "Fix: handle expired refresh tokens"
git commit -m "Add integration tests"
# Přerušení: potřeba opravit produkční bug
git worktree add ../hotfix main
cd ../hotfix
# ... oprava, commit, push, PR zmergován ...
cd ../my-project
git worktree remove ../hotfix
# Zpět k feature práci
git commit -m "Fix edge case in token validation"
# Připraveno na PR: vyčistit historii
git rebase -i main
# Squashnout fix commity, přeformulovat pro jasnost
# Push a otevření PR
git push -u origin feature/session-refresh
# Něco se rozbilo ve stagingu? Zjistěte, který commit:
git bisect start
git bisect bad HEAD
git bisect good main
git bisect run npm test
# Oops, hard-resetoval jsem špatnou věc
git reflog
git reset --hard HEAD@{2}Každý z těchto příkazů trvá sekundy. Dohromady šetří hodiny. Ne hypotetické hodiny — reálné hodiny, každý týden, které bych jinak strávil rozplétáním Git nepořádků, ručním hledáním bugů nebo ztrátou práce kvůli přepínání kontextu.
Git je nástroj, který odměňuje hloubku. Základy vás dostanou přes den. Ale příkazy v tomto článku jsou to, co odděluje "používám Git" od "Git mě skutečně dělá rychlejším". Učte se je inkrementálně. Vyberte si jednu novou techniku tento týden a používejte ji, dokud nebude svalová paměť. Pak vyberte další.
Vaše budoucí já, zírající na produkční bug v 11 večer, vám poděkuje za znalost git bisect.