git push –force și cum să te descurci cu el

Te-ai aflat vreodată într-o situație în care o comandă git greșită a făcut ravagii în repo-ul proiectului tău? Oamenii fac greșeli, iar uneori aceste greșeli pot costa ore din timpul echipei dvs. În acest tutorial, vă vom arăta cum să vă reveniți rapid după o git push --force nefericită.

Să nu devenim prea încrezători. Mai devreme sau mai târziu, acest lucru se va întâmpla. În timp ce lucrați cu mai multe telecomenzi în același depozit git, veți ajunge în cele din urmă git push --force în master (sau o altă ramură importantă cu care nu ar trebui să vă jucați niciodată).

Acest lucru se poate întâmpla, de exemplu, atunci când implementați cu Deis sau Heroku care folosesc telecomenzi git separate pentru a construi și implementa o aplicație. După o zi lungă de lucru, este incredibil de ușor să executați git push --force în loc de obișnuitul git push --force deis master.

Oops! Într-o clipită, coechipierii tăi au pierdut toată munca lor cea mai recentă. E timpul să le înfruntați furia.

Acum însă, așa cum ne spune un ghid excelent, NU vă panicați! Partea bună este că folosiți git, iar asta înseamnă că totul poate fi reparat.

Scenariul cel mai bun: altcineva care lucrează la același cod a scos o versiune recentă a master chiar înainte ca voi să o stricați. Atunci tot ce trebuie să faceți este să intrați în chat-ul echipei dvs. și să cereți acelei persoane să forțeze push-ul modificărilor sale recente.

Dacă sunteți norocos, depozitul lor local va avea istoricul complet al comenzilor, greșeala dvs. va fi suprascrisă cu cod proaspăt și nimic nu va fi pierdut. Dar ce se întâmplă dacă nu sunteți atât de norocos? Atunci, citiți mai departe!

Cazul 1: Ați fost ultima persoană care a făcut push la master înainte de greșeală

Veste bună! Aveți tot ce vă trebuie pentru a vă repara greșeala sub ochii dumneavoastră. Doar să nu închideți sau să ștergeți terminalul. Mai întâi, intră în chat-ul echipei tale și mărturisește-ți păcatele. Roagă-i pe oameni să nu se joace cu repo-ul pentru următorul minut sau cam așa ceva în timp ce tu repari lucrurile.

În ieșirea comenzii git push --force din shell-ul tău, caută o linie care seamănă cu aceasta:

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

Primul grup de simboluri (care arată ca un prefix SHA al unui commit) este cheia salvării. deadbeef este ultimul tău commit bun către master chiar înainte de a provoca pagube.

Așa că tot ce trebuie să faci este să… împingi forțat (luptând focul cu focul!) acest commit înapoi în ramura master, deasupra unuia rău.

$ git push --force origin deadbeef:master

Felicitări! Ați salvat ziua. Acum este timpul să înveți din greșelile tale.

Cazul 2: masterul a fost modificat de altcineva înainte ca tu să o dai în bară

Acum, chiar înainte ca tu să faci git push --force cineva a închis o grămadă de pull requests, iar master nu seamănă acum deloc cu copia ta locală. Nu mai puteți face git push --force sha1:master pentru că nu mai aveți comenzi recente la nivel local (și nici nu le puteți obține cu git fetch pentru că nu mai aparțin niciunei ramuri). Totuși, păstrați-vă calmul și rugați-vă colegii de echipă să stea departe de remote pentru o vreme.

Vom beneficia de faptul că GitHub nu elimină imediat comenzile inaccesibile. Desigur, nici nu le puteți prelua, dar există o soluție de rezolvare.

Rețineți că aceasta va funcționa numai dacă „urmăriți” depozitul, astfel încât tot ceea ce se întâmplă în el să apară într-un feed afișat pe prima pagină a GitHub-ului dumneavoastră. Deschideți acel flux și căutați ceva de genul acesta:

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

Acum puteți:

  • Compuneți un URL https://github.com/org/repo/tree/deadbeef, unde deadbeef este un hash al ultimei confirmări bune pentru ramura deteriorată;
  • Deschideți comutatorul de ramuri/taguri din interfața web a GitHub;

GitHub branch/tag switcher

GitHub branch/tag switcher

  • Creați un nume pentru o nouă ramură temporară (de ex.g., master-before-force-push);
  • Click pe „Create branch”.

Acum puteți prelua toate comenzile lipsă:

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

Problema dvs. este acum redusă la cea descrisă într-un exemplu anterior:

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

Dacă aveți în continuare nevoie ca lucrarea dvs. să fie în master, pur și simplu rebazați deasupra ei:

$ git rebase origin/master

Cum să evitați un astfel de dezastru în viitor

  1. GitHub și GitLab au o caracteristică numită „ramuri protejate”.” Marcați master, develop, stable sau orice alte ramuri cruciale ca fiind protejate și nimeni nu va avea voie să forțeze push-ul în ele. Este întotdeauna posibil să „deprotejați” temporar o ramură dacă aveți cu adevărat nevoie să suprascrieți istoricul.

    Citiți documentația GitHub pentru detalii.

  2. În loc de opțiunea --force, utilizați --force-with-lease. Aceasta va opri operațiunea de push în cazul în care cineva a făcut push pe aceeași ramură în timp ce lucrați la ea (și nu ați scos nicio modificare).

    Vezi acest articol de la Atlassian.

  3. Creați alias-uri pentru comenzile care folosesc git push --force pentru a preveni acțiunile distructive din greșeală:

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

    Citiți capitolul ProGit despre alias-uri.

  4. Nu faceți niciodată experimente în ramura principală a unui depozit! git checkout -b experiments este cel mai bun prieten al tău.

Pro Tip: git push are multe opțiuni. --force și --all funcționează împreună deosebit de bine. Puteți folosi această combinație atunci când vă întoarceți la proiect după mai multe luni de inactivitate. Încercați-o dacă vă simțiți foarte aventuros!

.

Leave a Reply