Verzování a nasazování změn
„Nasadit změnu“ je řetězec kroků od commitu k deploy.
Někdo opraví text, upraví šablonu, změní redirect nebo přidá měřicí skript. „Jen to nasadíme." U malého webu to zní neškodně. Jenže u malých změn číhá nejvíc rizika: co přesně se nasazuje, kdo to viděl předem, co se stane, když build spadne, a jak rychle se dá vrátit zpět?
Knight Capital na to v srpnu 2012 doplatil brutálně. Firma nasadila nový kód na obchodní servery, ale ne na všechny. Sedm z osmi běželo novou verzí, na osmém zůstala stará. V ní spal osm let mrtvý kód jménem Power Peg, který nový deploy probudil přes recyklovaný feature flag. Po otevření burzy systém během 45 minut poslal 4 026 087 obchodů, které poslat neměl, a firma prodělala 440 milionů dolarů.
Klíčové slovo je částečně. Nasazení neproběhlo celé. Systém byl napůl nový a napůl starý. Z toho plyne první pravidlo, ať stavíš burzovní systém, nebo obsahový web: deploy má být atomický. Buď se přepne celý hotový výsledek, nebo se nepřepne nic.
Atomický deploy je ale až poslední krok. Před ním vede cesta přes: commit, větev, pull request, build, preview, deploy, rollback. Když ta jména znáš, přestane být „nasadit změnu" magie. A hlavně pochopíš, proč „vrátit změnu" není jedno tlačítko, ale může to být komplexní operace.
Cíl, ne popis současného stavu
Zkouším tu popsat bezpečný postup, ne nutně to, jak to děláme na všech projektech dnes. Hodně lidí pushuje rovnou do main a nasazuje naslepo. My to tak občas taky děláme. Není to ideál a docela bych byl nerad, kdyby si někdo nemyslel, že to je úplně v pohodě.
Nutné minimum naštěstí máme nastavené dobře: atomický deploy a jasná cesta jak vzít změny zpátky. Když nasazení rozbije web, přepneš produkci na předchozí build v rámci sekund. Tak i proto si občas push do main můžeme dovolit.
Ideál samozřejmě plná pipeline: změna jde přes pull request, pustí se testy nebo preview, a mergovat smíš až je vše zelené. Nasetupovat to je kus práce. Dlouhodobě se to vyplatí u větších projektů a poměr cena/výkon je výborný, protože tu práci odvedeš jednou a chrání tě při každé další změně. U malých projektů se to naopak nikdy vrátit nemusí.
Push do main naslepo je každopádně riziko i pro experta. Expert má aspoň šanci tušit, že nic nerozbije, ale pořád jen tuší. Otestovat lokálně je určitě základ, ale může to být málo: tvůj počítač není produkce a nějaké provázání na jinou funkcionalitu ti nedojde. Pipeline s testy je proto ideál - pustí testy za tebe a deploy může projít, až když všechny projdou.
Editace v produkci je špatně
Občas ještě dneska se u webu někdo přihlásí přes FTP, přepíše soubor na živém webu a doufá. V tu chvíli nemáš historii, náhled ani rozumnou cestu zpět. Když oprava rozbije layout nebo formulář, původní verze už není vedle připravená. Kdysi to byl standard, u nás to naštěstí už dneska nejde, nikde žádné FTP nemáme.
Proto web žije ve verzovaném repozitáři. Každá změna nechá stopu. Neřešíš, kdo naposledy přepsal soubor na serveru; podíváš se do historie a víš, co se stalo. Neházíš změnu rovnou do produkce; ukážeš ji v preview. A když je průšvih, víš, jestli máš hasit rollbackem, opravit historii přes git revert, nebo řešit migraci dat. A víš to nejen ty, ale kdokoli z kolegů.
Co je commit, větev a pull request
Commit je snímek změn webu a zpráva proč se dělají. Git si nevede jen anonymní hromadu změn. Každý commit říká: takhle web vypadal v tomhle okamžiku a tady je důvod, proč jsme ho změnili.
Proto zpráva typu „fix" skoro nic neřeší. Za měsíc se někdo zeptá, proč zmizelo pole z formuláře nebo proč se změnil nadpis v navigaci. Dobrá commit message mu dá odpověď dřív, než otevře diff. Naštěstí Claude Code píše príma commit messages.
Větev je odbočka mimo hlavní linku. Hlavní větev se u webů často jmenuje main a měla by vždy držet stav, co se může nasadit. Když chceš něco změnit, nedáváš to přímo do ní. Založíš si pracovní větev, pracuješ v ní a až jsi spokojený, mergneš to.
Technicky je větev jen posuvný ukazatel na konkrétní commit. Prakticky je to bezpečný prostor pro změny. Jde v ní zkoušet různé nápady, přepisovat a případně zahodit slepou uličku. Nebo si tam nechat složitější změnu a vrátit se k aktuálně nasazené verzi a něco rychle opravit.
Až je změna hotová, merge ji dostane zpátky do main.
Mezi hotovou větví a mergem sedí pull request. Je to návrh ke sloučení a zároveň místo pro kontrolu. Otevřeš PR, někdo se podívá na změnu, okomentuje nejasnosti, ty doplníš úpravy a teprve potom se merguje.
PR není příkaz Gitu. Je to funkce hostingu repozitáře, třeba GitHubu. Pod ním pořád běží obyčejná větev a merge. PR k nim přidává review, diskuzi a často i automatické kontroly.
Secrets nepatří do repa
API klíče, tokeny a hesla k databázi nepatří do Gitu. Ani do Clauda, ehm.
Jakmile se secret jednou dostane do historie repozitáře, obyčejné smazání v dalším commitu ho neopraví. Starý snímek s hodnotou v historii zůstane. Každý, kdo si repo stáhl, ho může mít pořád u sebe.
GitGuardian ve zprávě State of Secrets Sprawl 2026 uvádí, že detekoval 28 649 024 secrets ve veřejných commitech na GitHubu jen za rok 2025. Zároveň píše, že víc než 64 % secrets uniklých v roce 2022 bylo na začátku roku 2026 pořád platných. Pointa není to šíleně velké číslo, ale to, že uniklý klíč může fungovat roky.
Secrets proto patří do prostředí, ne do kódu. CI je čte z chráněného úložiště, ideálně z GitHub secrets. V repu zůstane jen název proměnné, nikdy ne hodnota.
Když secret unikne, nestačí ho smazat. Musíš ho zneplatnit a zrotovat. Smazaný commit klíč nezruší, pořád funguje. Takže je potřeba vlézt do dané služby, klíč smazat/deaktivovat a nastavit nový do Github secrets.
Když se to pokazí - jak se rychle vrátit zpět
„Vrátit změnu" zní jako jedna věc, ve skutečnosti to můžou být tři různé operace:
- přepnout hosting na starší deploy,
- zapsat do Gitu nový commit, který ruší starou změnu,
- vrátit schéma nebo data opačnou migrací.
Každá operace řeší jiný problém a má jiné následky.
Hostingový rollback: přepnutí na starý artefakt
Hosting většinou pracuje s neměnnými deployi, Zerops, Cloudflare i Vercel to umí. Nový build vznikne vedle starého. Až když je hotový, hosting atomicky přepne produkční doménu na nový artefakt.
Starý deploy se tedy nepřepíše. Pořád existuje. Rollback je tedy rychlé přepnutí domény zpátky na artefakt, který tam pořád leží připravený. Nespouští nový build a nečeká na pipeline. Takže je to rychlé a typicky bezbolestné.
Kde se klikne, záleží na providerovi:
- Vercel. Funkce se jmenuje Instant Rollback. Najdeš ji na dlaždici Production Deployment, nebo přes tři tečky (⋮) u řádku v záložce Deployments.
- Cloudflare Pages. Sekce Deployments → seznam All deployments → tříbodové menu (⋮) u cílového deploye → Rollback to this deployment.
Je to rychlá záchrana. Sekundy, žádný build, žádná změna v repu.
git revert: oprava zapsaná do historie
git revert dělá něco jiného. Vyrobí nový commit, který ruší efekt předchozí změny.
Původní commit v historii zůstane. Nad ním přibude další commit, který ho vrací. Protože je to normální commit, projde review, buildem i deployem stejně jako každá jiná změna.
Na sdílené větvi je to hlavní výhoda. git revert nepřepisuje historii, kterou už si ostatní stáhli. Jen přidává další zápis.
Plete se s git reset. Ten posune ukazatel větve a může commity z historie odstranit. To je v pořádku pro lokální nepushnuté změny. Na sdílené větvi tím ale ostatním rozbiješ historii.
Krátce: rollbackem hasíš. git revertem opravuješ natrvalo.
Co rollback nevrátí
Rollback vrátí jen to, co bylo v deploynutém artefaktu: kód a obsah, který žije v Gitu. U čistě statického webu s obsahem v repu to typicky je celý web a je to tedy snadné.
Jakmile ale stav žije mimo artefakt, rollback končí. Databáze, objednávky, uživatelské účty nebo ručně editovaný obsah v administraci se nepřepnou zpátky jen proto, že hosting ukáže starší build. Nejvíc bolí migrace v databázi, starý artefakt s nimi nemusí fungovat.
Schéma nebo data vracíš opačnou (down) migrací. V Contemberu (a na většině databází) je migrace dopředná operace. Cestu zpět musíš napsat, pokud vůbec existuje. Když „vrátíš deploy", databázi tím nevracíš.
Tři typické záměny
- Commit a deploy jsou totéž. Nejsou. Commit je zápis změny do historie. Deploy je nasazení artefaktu naživo. Můžeš commitovat desetkrát a nenasadit vůbec.
- Vrátit změnu je jedna operace. Ne. Hostingový rollback přepne starý artefakt.
git revertzapíše nový opravný commit. Opačná migrace řeší schéma a data mimo artefakt. - Smazaný secret je v bezpečí. Není. Co se jednou dostalo do Git historie, ber jako uniklé. Klíč se musí zneplatnit a zrotovat, ne jen smazat v dalším commitu.
Praktický checklist
- Zdroj webu i obsah jsou ve verzovaném repu.
- Změny jdou přes větev a PR, ne přímo do
mainani na produkci. - Každá změna je commit se srozumitelnou zprávou proč.
- Větve drž krátké: jedna změna, jeden PR, rychle do
main. - Preview deploy otevři na reálném zařízení a pošli ho lidem, kteří mají změnu vidět před publikací.
- Žádný secret v repu. Hodnoty patří do chráněného úložiště nebo environment variables.
- Při úniku secret zneplatni a zrotuj. Samotné smazání commitu nestačí.
- U citlivých deployů zvaž approval gate a předem ověř omezení plánu.
- Měj jasno, co rollback vrátí: artefakt ano, externí DB nebo CMS ne.
- Rozlišuj, kdy sáhnout po hostingovém rollbacku, kdy po
git reverta kdy potřebuješ opačnou migraci.
16 / 26