Rahat, Git!?!

Gitul nu e pentru toți: să dai cu bâta în baltă e ușor, dar să îți dai seama cum să repari e imposibil, rahat! Documentația gitului are problema oului și a găinii și nu poți să cauți cum să te scoți din rahat, decât dacă știi deja numele a ceea ce trebuie să știi pentru a-ți rezolva problema.

Deci uite câteva situații de rahat în care m-am băgat și cum m-am scos singur în cele din urmă din ele pe românește.

Rahat, am făcut ceva foarte prost, te rog spune-mi că gitul are o mașină magică a timpului!?!

git reflog
# vei vedea o listă cu tot ce 
# ai facut in git, pe toate branchurile!
# fiecare are un index HEAD@{index}
# găsește-l pe cel de dinainte să se dezlănțuie iadul
git reset HEAD@{index}
# mașina magică a timpului

Poți să folosești asta să recuperezi chestiile pe care le-ai sters din greșeală, sau pur și simplu să scoți chestii pe care le-ai încercat și care au distrus repoul sau să refaci repoul după un merge prost sau doar să te intorci în timp când lucrurile mergeau. Eu folosesc reflog MULT. Jos pălăria celor mulți, mulți, mulți, mulți, mulți care mi-au sugerat să îl adaug

Rahat, am comis și imediat mi-am dat seama că trebuie să mai fac o modificare mică!

# fă-ți modificarea
git add . # sau adaugă fișiere individuale
git commit --amend --no-edit
# acum ultimul tău commit conține acea schimbare!
# AI GRIJĂ: nu face niciodată asta în commituri publice

Asta mi se intamplă de obicei dacă comit și apoi rulez teste/linters... și PLM, nu am pus un spațiu după un egal. Ai putea și să faci modificarea ca un nou commit și apoi să faci rebase -i ca să le pui unu-ntr-altu', dar asta e cam de un milion de ori mai rapid.

*Ai grijă: Nu ar trebui niciodată să faci amend la commituri care au fost împinse într-un branch public/comun! Doar amend la commituri care există doar in copia ta locală sau te trezești cu mortu-n casă.

Rahat, trebuie să schimb mesajul ultimului meu commit!

git commit --amend
# Urmărește indicațiile pentru a schimba mesajul commitului

Cerințe stupide de formatare a mesajului de commit.

Rahat, am comis din greșeală ceva în master care ar fi trebuit sa fie pe un branch nou-nouț!

# creează un branch de pe starea curentă a masterului
git branch un-nume-de-branch-nou
# scoate ultimul commit din master branch
git reset HEAD~ --hard
git checkout un-nume-de-branch-nou
# commitul tău este acum in branchul ăsta :)

Notă: chestia asta nu merge dacă deja ai impins commitul într-un branch public/comun și, dacă ai încercat alte lucruri înainte, s-ar putea să ai nevoie de git reset HEAD@{number-of-commits-back} în loc de HEAD~. Valea plângerii. Mai mult, mulți, mulți, mulți oameni au sugerat un fel foarte tare de a face chestia asta mai scurtă, pe care eu personal nu îl știam. Vă mulțumesc tuturor!

Rahat, am comis într-un branch greșit!

# anulează ultimul commit, dar lasă modificările disponibile
git reset HEAD~ --soft
git stash
# mută-te pe branchul corect
git checkout nume-corect-de-branch
git stash pop
git add . # sau adaugă fișiere individuale
git commit -m "mesajul tău aici";
# acum modificările tale sunt pe branchul corect

Mulți oameni au sugerat de asemenea folosirea cherry-pickului în această situație, deci alege ce vrei in funcție de ce are mai mult sens pentru tine!

git checkout nume-corect-de-branch
# ia ultimul commit de pe master
git cherry-pick master
# șterge-l de pe master
git checkout master
git reset HEAD~ --hard

Rahat, am încercat să rulez un diff, dar nu s-a întamplat nimic?!

Dacă știi că ai facut modificări în fișiere, dar difful este gol, probabil ți-ai addaugat fișierele tale în staging și trebuie să folosești o opțiune specială.

git diff --staged

Fișier în ¯\_(ツ)_/¯ (da, știu este un feature, nu un bug, dar este absolut neplăcut și nu este evident prima oară când ți se întamplă!)

Rahat, trebuie să anulez un commit din urmă cu vreo 5 commituri!

# găsește commitul pe care trebuie să îl anulezi
git log
# folosește săgețile să te duci în sus și în jos prin istoric
# odată ce ți-ai găsit commitul, salvează hashul
git revert [hash salvat]
# git va crea un commit care anulează commitul respectiv
# urmărește indicațiile pentru a edita mesajul commitului 
# sau doar salvează și comite

Pare că nu trebuie să urmarești și să faci copy-paste la vechiul conținut al fișierului în fișierul existent pentru a anula schimbările! Dacă ai comis un bug, poți să anulezi totul dintr-o mișcare cu revert.

Poți de asemenea să anulezi un singur fișier în loc de un commit întreg! Dar desigur, într-un mod foarte "git", e un set complet diferit de rahaturi de comenzi...

Rahat, trebuie să îmi anulez modificările dintr-un fișier!

# găsește un hash pentru un commit dinainte ca fișierul să fi fost schimbat
git log
# folosește săgețile ca să te plimbi în sus și în jos prin istoric
# odată ce ai găsit commitul, salveaza hashul
git checkout [hash salvat] -- cale/către/fișier
# versiunea veche a fișierului va fi în indexul tău
git commit -m "Oau, nu trebuie să faci copy-paste ca să anulezi"

Când mi-am dat seama într-un final de asta, a fost BABAN. BABAN. B-A-B-A-N. Dar serios acum, pe ce rahat de planetă checkout -- are sens ca cel mai bun mod de a anula modificările dintr-un fișier? :scuturând-pumnul-către-linus-torvalds:

La dracu' cu dezastrul ăsta, renunț.

cd ..
sudo rm -r git-repo-dir-de-rahat
git clone https://some.github.url/git-repo-dir-de-rahat.git
cd git-repo-dir-de-rahat

Mulțumesc lui Eric V. pentru asta. Toate plângerile despre folosirea lui sudo în această glumă îi pot fi adresate lui.

Pe bune acu', dacă branchul tău este atâââât de distrus că trebuie să resetezi starea repoului pentru a fi la fel cu repoul remote într-un mod "git-approved", încearcă asta, dar ai grijă că acestea sunt acțiuni distructive și irecuperabile!

# preia cea mai din urmă stare
git fetch origin
git checkout master
git reset --hard origin/master
# șterge fișierele și directoarele netratate
git clean -d --force
# repetă checkout/reset/clean pentru fiecare branch distrus

*Ca să știi: Siteul acesta nu e menit să fie o referință exhaustivă. Și da, există alte moduri de a face aceleași lucruri mai corect din punct de vedere teoretic sau în fine, dar eu am ajuns la acești pași după numeroase erori si reîncercari și multe înjuraturi și răsturnări de mese și am avut ideea aceasta nebunească să ți le impărtășesc cu o doză sănătoasă de simplu și profan. Ia-o sau las-o, cum vrei!

Multe mulțumiri tuturor celor care au contribuit voluntar la traducerea acestui site în alte limbi. Sunteți cei mai tari! Michael Botha (af) · Khaja Md Sher E Alam (bn) · Eduard Tomek (cs) · Moritz Stückler (de) · Franco Fantini (es) · Hamid Moheb (fa) · Senja Jarva (fi) · Michel (fr) · Alex Tzimas (gr) · Elad Leev (he) · Aryan Sarkar (hi) · Ricky Gultom (id) · fedemcmac (it) · Meiko Hori (ja) · Zhunisali Shanabek (kk) · Gyeongjae Choi (ko) · Rahul Dahal (ne) · Martijn ten Heuvel (nl) · Łukasz Wójcik (pl) · Davi Alexandre (pt_BR) · Catalina Focsa (ro) · Daniil Golubev (ru) · Nemanja Vasić (sr) · Björn Söderqvist (sv) · Kitt Tientanopajai (th) · Taha Paksu (tr) · Andriy Sultanov (ua) · Tao Jiayuan (zh) . Cu ceva ajutor de la Allie Jones · Artem Vorotnikov · David Fyffe · Frank Taillandier · Iain Murray · Lucas Larson · Myrzabek Azil

Dacă ai vrea să ajuți cu adăugarea unei traduceri în limba ta, bagă un PR aici GitHub