Dangit, Git!?!

Git je težak: lako je pogrešiti, a skontati kako da popraviš greške je nemoguće. Git dokumentacija ima problem šta je starije koka ili jaje gdje ne možeš da nađeš kako da se izvučeš iz problema, osim ako već znaš za stvar koja ti treba kako bi rešio svoj problem.

Dakle evo nekih loših situacija u koje sam zapao i kako sam se na kraju izvukao iz njih u običnom srpskom jeziku.

Bokte, napravio sam nešto veoma pogrešno, molim te reci mi da git ima čarobnu vremeplov mašinu!?!

git reflog
# vidjećeš listu svih stvari koje si
# radio u gitu, na svim brančevima!
# svaki od njih ima index HEAD@{index}
# nađi onaj koji tražiš prije nego što pokvariš sve
git reset HEAD@{index}
# magična vremeplov mašina

Možeš da koristiš ovu komandu da vratiš stvari koje si slučajno izbrisao, ili da izbrišeš neke stvari koji si probao a koje su skrišile tvoj repo, ili da vratiš staro stanje poslije lošeg merga, ili da se vratiš u vrijeme kada su stvari zapravo radile. Ja koristim reflog STALNO. Kapa dole svim svim svim svim ljudima koji su predložili da se doda ova komanda!

Bokte, komitovao sam i odmah sam zaključio da treba da napravim malu izmjenu!

# napravi izmjene
git add . # ili dodaj fajlove indvidualno
git commit --amend --no-edit
# sada tvoj zadnji komit sadrži tu izmjenu!
# PAŽNJA: nikad nemoj da koristiš ammend na public komitima

Ovo mi se obično desi kada napravim komit, onda pokrenem tests/linters... ugh, nisam dodao razmak poslije znaka jednakosti. Takođe mogao bi da napraviš izmjenu kao novi komit i onda odradiš rebase -i kako bi ih spojio zajedno, ali ovo je milion puta brže.

Pažnja: Nikada ne bih trebao da amendaš komite koji su već objavljeni na public/shared branč! Samo amenduj komite koji postoje u tvojoj lokalnoj kopiji repositorija, ili ceš u suprotnom zažaliti.

Bokte, treba da promjenim poruku na zadnjem komitu!

git commit --amend
# prati upute da bi promjenio komit poruku

Glupi zahtjevi za formatiranje komit poruke.

Bokte, slučajno sam komitovao nešto na master a što bi trebalo da bude na potpuno novom branču!

# kreiraj novi branč od trenutnog stanja mastera
git branch some-new-branch-name
# izbriši zadnji komit sa master branča
git reset HEAD~ --hard
git checkout some-new-branch-name
# tvoj komit je sada na novom branču :)

Zabilježi: ovo neće raditi ako si već pušao komit na public/shared branč, i ako si pokušao druge stvari, možda ćeš trebati git reset HEAD@{number-of-commits-back} umjesto korištenja HEAD~. beskonačno. Takođe, mnogo, mnogo, mnogo ljudi je predložilo ovaj odlični kratki način za koji nisam znao. Hvala vam svima!

Bokte, slučajno sam komitovao na pogrešan branč!

# poništi zadnji komit, ali ostavi izmjene
git reset HEAD~ --soft
git stash
# prebaci se na pravi branč
git checkout name-of-the-correct-branch
git stash pop
git add . # ili dodaj fajlove indvidualno
git commit -m "your message here";
# sada su tvoje izmjene na pravom branču

Mnogo ljudi je predložilo da koristim cherry-pick za ovu situaciju, pa izaberite ono što vam ima najviše smisla!

git checkout name-of-the-correct-branch
# uzmi zadnji komit sa mastera
git cherry-pick master
# izbriši komit sa mastera
git checkout master
git reset HEAD~ --hard

Bokte, pokušao sam da pokrenem diff ali se ništa nije desilo?!

Ako znaš da si napravio izmjene u fajlovima, ali diff je prazan, vjerovatno si add-ed (dodao) svoje fajlove u staging zonu i moraćeš da koristiš poseban flag.

git diff --staged

Datoteka pod ¯\_(ツ)_/¯ (da, znam da je ovo feature, a ne bag, ali je zbunjujuće i neočigledno je kada vam se prvi put dogodi!)

Bokte, moram da poništim komit od prije 5 komita!

# nađi komit koji želiš da poništiš
git log
# koristi tipke za gore i dole kako bi skrolovao kroz istoriju
# kada nađeš komit, snimi heš
git revert [saved hash]
# git će kreirati novi komit koji će poništiti stari
# isprati upute kako bi promjenio komit poruku
# ili samo snimi i komituj

Izgleda da ne moraš da tražiš sadržaj starog fajla i da copy-paste-aš u postojeći fajl kako bi poništio izmjene! Ako si komitao bag, možeš da poništiš komit u jednom potezu sa revert.

Takođe možeš vratiti samo jedan fajl umjesto cijelog komita! Ali naravno, u istinskom git modu, to je potpuno drugačiji skup komandi...

Bokte, moram poništiti izmjene u fajlu!

# nađi heš komita prije nego što je fajl bio promjenjen 
git log
# koristi tipke za gore i dole kako bi skrolovao kroz istoriju
# kada nađeš odgovarajući komit, snimi heš
git checkout [saved hash] -- path/to/file
# stara verzija fajla će biti u u tvojoj index zoni
git commit -m "Wow, ne moraš da copy-paste-aš da bi poništio"

Kad sam konačno shvatio ovo bio je to OGROMNI. OGROMNI. O-G-R-O-M-N-I AHAAA momenat. Ali ozbiljno, na kojoj planeti checkout ima smisla kao najbolji način za poništavanje fajla? :shakes-fist-at-linus-torvalds:

Zaboravi sve ovo, odustajem.

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

Hvala Eric V. za ovo. Sve pritužbe na korištenje sudo-a u ovoj šali mogu se usmjeriti na njega.

Ali sada stvarno, ako vam je branč toliko uništen da trebate resetovati stanje vašeg repositorija kako bi bio isti kao i remote repositori na "git-approved" način, pokušajte s ovim, ali pazite ovi su destruktivne i nepovratne akcije!

# uzmi zadnje stanje origin-a
git fetch origin
git checkout master
git reset --hard origin/master
# izbriši sve fajlove i foldere koje git ne prati
git clean -d --force
# ponovi checkout/reset/clean za svaki pokvareni branč

*Izjava o odricanju odgovornosti: Ovaj sajt nije namjenjen da bude iscrpna referenca. I da, postoje i drugi načini da se iste ove stvari izvedu sa više teorije ili šta god, ali ja sam do ovih koraka došao kroz pokušaje i grešeći i sa puno psovki, i imao sam ovu ludu ideju da ih podjelim sa zdravom dozom nesmotrenosti i bezobzirnosti. Uzmi ili ostavi kako hoćeš!

Mnogo hvala svima koji su volontirali da pevedu ovaj sajt na nove jezike, sila ste! Moritz Stückler (de) · Daniil Golubev (ru) · Łukasz Wójcik (pl) · fedemcmac (it) · Michel (fr) · Andriy Sultanov (ua) · Meiko Hori (ja) · Alex Tzimas (gr) · Martijn ten Heuvel (nl) · Elad Leev (he) · Franco Fantini (es) · Catalina Focsa (ro) · Davi Alexandre (pt_BR) · Nemanja Vasić (sr) · Tao Jiayuan (zh) · Eduard Tomek (cs) · Ricky Gultom (id) . Sa dodatnom podrškom od Iain Murray · Frank Taillandier · David Fyffe · Lucas Larson

Ako želiš da pomognes i dodaš prevod za svoj jezik, kreiraj PR na GitHub