Znalosti manGowebu
Graf znalostí
technika / git-cicd
Kapitola

Verzování a nasazování změn

„Nasadit změnu“ je řetězec kroků od commitu k deploy.

technikacicdgitdeploypreviewrollbackcommitrevertmigracepipelineNaposledy aktualizováno 14. června 2026

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.

Větve: krátké, ne strom

Vývojáři roky řeší Git Flow proti trunk-based developmentu. Pokud jste se hodiny u piva o tom nehádali, jste šťastní lidé. Pro obsahový web naštěstí stačí jednoduché pravidlo: jedna změna, jedna krátká větev, jeden PR, rychle zpátky do main.

Git Flow pracuje s dlouho žijícími větvemi jako develop nebo release větve. To dává smysl tam, kde současně podporuješ víc verzí softwaru. U běžného webu je živá jedna verze a vydáváš průběžně. Dlouhé větve jen oddalují integraci a zvyšují šanci, že merge bude bolet.

Obsah do toho patří stejně jako kód. Git-based CMS, třeba Nua site nebo Decap, může netechnickému editorovi ukázat normální administrační rozhraní, ale pod ním uloží změnu jako commit nebo PR. Editor pak projde známým redakčním postupem draft → review → publish, jen technicky běží přes větev a pull request.

I oprava překlepu tím dostane náhled a stopu v historii. O to jde: nepřidat zbytečnou administrativu, ale nedělat změny naslepo.

Preview: jedna stanice na cestě

Když nasadíš větev na hosting, ten z ní může postavit preview deploy: živou kopii webu se změnou na vlastní URL.

Preview umí být super užitečná. Otevřeš odkaz na mobilu a vidíš, jestli se nerozsypal layout. Pošleš ho klientovi ke schválení. Redaktor se podívá, jak bude článek opravdu vypadat. Recenzent v PR nečte jen diff, ale klikne na hotovou stránku. V Nua site přesně takhle fungují změny, uživatel se vlastně divá na preview.

U jiných projektů to jde nastavit, ale kvůli datům v databázi to není tak snadné, Contember neumí udělat rozdělení dat dostatečně jednoduše (zatím). Takže v praxi používáme spíš beta a prod a změny testujeme na betě.

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:

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:

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

Praktický checklist

Zdroje