git push –force a jak se s ním vypořádat

Stali jste se někdy v situaci, kdy chybný příkaz git způsobil v repozitáři vašeho projektu spoušť? Lidé dělají chyby a někdy tyto chyby mohou stát hodiny času vašeho týmu. V tomto návodu vám ukážeme, jak se z nešťastného git push --forcepříkazu rychle vzpamatovat.

Nebudeme si příliš věřit. Dříve nebo později se to stane. Při práci s několika remoty v jednom repozitáři git se nakonec git push --force dostane do master (nebo do jiné důležité větve, se kterou by se nikdy nemělo manipulovat).

To se může stát například při nasazení v systémech Deis nebo Heroku, které k sestavení a nasazení aplikace používají samostatné remoty git. Po dlouhém pracovním dni je neuvěřitelně snadné provést git push --force místo obvyklého git push --force deis master.

Oops! V mžiku oka vaši kolegové z týmu přijdou o veškerou svou poslední práci. Je čas čelit jejich vzteku.

Jak nám však radí jeden vynikající průvodce: NEPANIKAŘTE! Dobré je, že používáte git, a to znamená, že vše lze opravit.

Nejlepší scénář: někdo jiný, kdo pracuje na stejném kódu, stáhl nejnovější verzi master těsně předtím, než jste ji rozbili. Pak stačí jít do chatu vašeho týmu a požádat tohoto člověka, aby vynuceně odeslal své nedávné změny.

Pokud budete mít štěstí, jeho lokální repozitář bude mít kompletní historii revizí, vaše chyba bude přepsána čerstvým kódem a nic se neztratí. Ale co když takové štěstí nemáte? Pak čtěte dál!

Případ 1: Byl jste poslední, kdo odeslal do masteru před chybou

Dobrá zpráva! Máte před očima vše, co potřebujete, abyste svou chybu napravili. Jen nezavírejte nebo nevymazávejte terminál. Nejprve jdi do chatu svého týmu a vyznej se ze svých hříchů. Požádejte lidi, aby se v příštích minutách, než vše opravíte, nepletli do repa.

Ve výstupu příkazu git push --force v shellu hledejte řádek, který se podobá tomuto:

 + deadbeef...f00f00ba master -> master (forced update)

První skupina symbolů (která vypadá jako prefix SHA revize) je klíčem k záchraně. deadbeef je vaše poslední dobrá revize do větve master těsně před tím, než jste napáchali škodu.

Takže jediné, co potřebujete, je… násilně odsunout (bojovat s ohněm ohněm!) tuto revizi zpět do větve master, a to na špatnou.

$ git push --force origin deadbeef:master

Gratulujeme! Zachránil jsi den. Teď je čas poučit se ze svých chyb.

Případ 2: master byl změněn někým jiným předtím, než jsi to pokazil

Takže těsně předtím, než jsi udělal git push --force, někdo uzavřel hromadu pull requestů a master teď nevypadá jako tvá lokální kopie. Nemůžete už udělat git push --force sha1:master, protože nemáte poslední revize lokálně (a nemůžete je získat ani pomocí git fetch, protože už nepatří do žádné větve). Přesto zachovejte klid a požádejte své spoluhráče, aby se na chvíli drželi dál od vzdálené větve.

Budeme těžit z toho, že GitHub neodstraňuje nedosažitelné revize okamžitě. Samozřejmě je také nemůžete načíst, ale existuje způsob, jak to obejít.

Všimněte si, že bude fungovat pouze v případě, že úložiště „sledujete“, takže se vše, co se v něm děje, zobrazuje ve feedu zobrazeném na titulní stránce vašeho GitHubu. Otevřete tento kanál a vyhledejte něco takového:

an hour agoUsername pushed to master at org/repo - deadbeef Implement foo - deadf00d Fix bar

Nyní můžete:

  • Sestavit adresu URL https://github.com/org/repo/tree/deadbeef, kde deadbeef je hash poslední dobré revize poškozené větve;
  • Otevřít přepínač větví/značek ve webovém uživatelském rozhraní GitHubu;

Přepínač větví/značek GitHub

Přepínač větví/značek GitHub

  • Vytvořte název nové dočasné větve (např.g., master-before-force-push);
  • Klikněte na „Vytvořit větev“.

Nyní můžete načíst všechny chybějící revize:

$ git fetchFrom github.com:org/repo * master-before-force-push -> origin/master-before-force-push

Váš problém je nyní redukován na problém popsaný v předchozím příkladu:

$ git push --force origin origin/master-before-force-push:master

Pokud stále potřebujete, aby vaše práce byla v master, stačí nad ní provést rebase:

$ git rebase origin/master

Jak se takové katastrofě v budoucnu vyhnout

  1. GitHub a GitLab mají funkci tzv. chráněných větví.“ Označte master, develop, stable nebo jiné klíčové větve jako chráněné a nikdo do nich nebude smět násilně tlačit. Vždy je možné větev dočasně „nechránit“, pokud opravdu potřebujete přepsat historii.

    Pro podrobnosti si přečtěte dokumentaci GitHubu.

  2. Místo možnosti --force použijte --force-with-lease. Ta zastaví operaci odesílání, pokud někdo odeslal do stejné větve, zatímco jste na ní pracovali (a nestáhl žádné změny).

    Podívejte se na tento článek od společnosti Atlassian.

  3. Vytvořte si aliasy pro příkazy, které používají git push --force, abyste zabránili náhodným destruktivním akcím:

    # ~/.gitconfig deploy = "!git push --force deis \"$(git rev-parse --abbrev-ref HEAD):master\""

    Přečtěte si kapitolu o aliasech v ProGitu.

  4. Nikdy neprovádějte experimenty v hlavní větvi úložiště! git checkout -b experiments Je to váš nejlepší přítel.

Pro Tip: git push má mnoho možností. --force a --all spolu fungují obzvlášť dobře. Tuto kombinaci můžete použít při návratu k projektu po několika měsících nečinnosti. Vyzkoušejte ji, pokud se cítíte mimořádně odvážní!

Leave a Reply