git push –force és hogyan kezeljük
Voltál már olyan helyzetben, amikor egy rossz git parancs pusztítást végzett a projekted repóján? Az emberek hibáznak, és néha ezek a hibák órákba kerülhetnek a csapatod idejéből. Ebben a bemutatóban megmutatjuk, hogyan lehet gyorsan helyreállni egy szerencsétlen git push --force
ből.
Ne legyünk túlságosan magabiztosak. Előbb vagy utóbb ez is meg fog történni. Miközben több távoli ággal dolgozol ugyanabban a git-repositoryban, előbb-utóbb git push --force
a master
-be (vagy egy másik fontos ágba, amellyel soha nem szabad szórakozni).
Ez megtörténhet például a Deis vagy a Heroku segítségével történő telepítéskor, amelyek külön git távoli ágakat használnak az alkalmazás építéséhez és telepítéséhez. Egy hosszú munkanap után hihetetlenül könnyű a szokásos git push --force deis master
helyett git push --force
-t végrehajtani.
Oops! Egy szempillantás alatt a csapattársaid elvesztették az összes legutóbbi munkájukat. Ideje szembenézni a dühükkel.
Mindamellett, ahogy egy kiváló útmutató mondja: NE PÁNIKOLJ! A jó dolog az, hogy git-et használsz, és ez azt jelenti, hogy mindent ki lehet javítani.
A legjobb esetben: valaki más, aki ugyanazon a kódon dolgozik, épp azelőtt húzta ki a
master
egy friss verzióját, mielőtt te elrontottad volna. Ekkor csak annyit kell tenned, hogy belépsz a csapatod csevegésébe, és megkéred ezt a személyt, hogy erőltesse a friss változtatásait.
Ha szerencséd van, az ő helyi tárolójában meglesz a commitok teljes története, a hibádat friss kóddal írják felül, és semmi sem vész el. De mi van, ha nem vagy ilyen szerencsés? Akkor olvass tovább!
1. eset: Te voltál az utolsó, aki a hiba előtt a masterbe pusholt
Jó hír! A szemed előtt van minden, amire szükséged van ahhoz, hogy visszacsináld a hibádat. Csak ne zárd be vagy töröld a terminálodat. Először is menj be a csapatod chatjébe, és gyónd meg a bűneidet. Kérd meg az embereket, hogy a következő egy-két percben ne szórakozzanak a repóval, amíg te javítod a dolgokat.
A shell programodban a git push --force
parancs kimenetén keress egy ehhez hasonló sort:
+ deadbeef...f00f00ba master -> master (forced update)
A szimbólumok első csoportja (amely úgy néz ki, mint egy commit SHA előtagja) a megmentés kulcsa. A deadbeef
az utolsó jó commitod a master
ágba, közvetlenül azelőtt, hogy kárt okoztál volna.
Ezért már csak annyit kell tenned, hogy… erőlteted (tűzzel a tűz ellen!) ezt a commitot vissza a master
ágba, egy rossz commit tetejére.
$ git push --force origin deadbeef:master
Gratulálok! Megmentetted a napot. Most itt az ideje, hogy tanulj a hibáidból.
2. eset: a master-t valaki más módosította, mielőtt te elszúrtad
Szóval, pont mielőtt megcsináltad a git push --force
-t, valaki bezárt egy csomó pull requestet, és a master
most egyáltalán nem úgy néz ki, mint a helyi példányod. Már nem tudod megcsinálni a git push --force sha1:master
-et, mivel lokálisan nincsenek friss commitjaid (és a git fetch
-el sem tudod megszerezni őket, mert már nem tartoznak egyik ághoz sem). Mégis, maradj nyugodt, és kérd meg a csapattársaidat, hogy egy ideig maradjanak távol a remote-tól.
Nekünk az lesz a hasznunkra, hogy a GitHub nem távolítja el azonnal az elérhetetlen commitokat. Természetesen ezeket sem tudod lehívni, de van egy megoldás.
Megjegyezzük, hogy ez csak akkor fog működni, ha “figyeled” a repository-t, tehát minden, ami benne történik, megjelenik a GitHub címlapján megjelenő feedben. Nyisd meg ezt a feedet, és keress valami ilyesmit:
an hour agoUsername pushed to master at org/repo - deadbeef Implement foo - deadf00d Fix bar
Most már tudod:
- összeállíthatsz egy
https://github.com/org/repo/tree/deadbeef
URL-t, aholdeadbeef
a sérült ág utolsó jó commitjának hash-ja; - megnyithatod a GitHub webes felhasználói felületén az ág/tagváltót;
- Hozzon létre egy nevet egy új ideiglenes ágnak (pl.g.,
master-before-force-push
); - Kattints a “Create branch” (ág létrehozása) gombra.
Most már lekérheti az összes hiányzó commitot:
$ git fetchFrom github.com:org/repo * master-before-force-push -> origin/master-before-force-push
A problémája mostantól a korábbi példában leírtakra csökken:
$ git push --force origin origin/master-before-force-push:master
Ha továbbra is szükséged van arra, hogy a munkád a master
-ben legyen, egyszerűen csak rebase-elj rá:
$ git rebase origin/master
Hogyan kerüld el az ilyen katasztrófát a jövőben
-
A GitHub és a GitLab rendelkezik egy “protected branches” nevű funkcióval.” Jelöld meg a
master
,develop
,stable
, vagy bármely más fontos ágat védettnek, és senki sem kényszeríthet push-t ezekbe. Mindig van lehetőség egy ág ideiglenes “feloldására”, ha valóban felül kell írni az előzményeket.A részletekért olvassa el a GitHub dokumentációját.
-
A
--force
opció helyett használja a--force-with-lease
opciót. Ez megállítja a push műveletet, ha valaki pusholt ugyanarra az ágra, miközben te dolgoztál rajta (és nem húztál ki semmilyen változtatást).Lásd ezt a cikket az Atlassian-tól.
-
Hozzon létre aliasokat a
git push --force
-t használó parancsokhoz, hogy elkerülje a véletlen romboló műveleteket:# ~/.gitconfig deploy = "!git push --force deis \"$(git rev-parse --abbrev-ref HEAD):master\""
Olvassa el a ProGit aliasokról szóló fejezetét.
-
Soha ne végezzen kísérleteket a repository fő ágában! A
git checkout -b experiments
a legjobb barátod.
Pro tipp: git push
számos lehetőséggel rendelkezik. A --force
és a --all
különösen jól működik együtt. Ezt a kombót akkor használhatod, ha több hónapos inaktivitás után visszatérsz a projekthez. Próbálja ki, ha extra kalandvágyónak érzi magát!
Leave a Reply