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 --force
pří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
, kdedeadbeef
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;
- 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
-
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.
-
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.
-
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.
-
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