Shit pommes frites, Git!?!

Git är svårt: Det är lätt att röra till det, och att ta reda på hur du tar fixar dina misstag är helt jävla omöjligt. Git-dokumentationen har ett problem likt det med hönan och ägget, du kan inte söka efter hur du kommer ur en knipa om du inte redan vet namnet på det du behöver lära dig mer om för att kunna fixa ditt problem.

Så här är några knipor som jag har hamnat i, och hur jag tids nog tog mig ur dem på ren svenska.

Shit pommes frites, jag gjorde något riktigt dåligt, snälla säg att git har en magisk tidsmaskin!?!

git reflog
# du får se en lista över allt du har
# gjort i git, tvärs över alla brancher!
# var och en har ett index HEAD@{index}
# leta upp den som är innan du pajade allting
git reset HEAD@{index}
# magisk tidsmaskin

Du kan använda detta för att få tillbaka nåt som du råkade ta bort, eller bara ta bort något som du provade som pajade repot, eller för att återställa efter en dålig merge, eller bara för att gå tillbaka i tiden till en tidpunkt där saker faktiskt funkade. Jag använder reflog EN HEL DEL. Tack och bock till alla ni många många många många många människor som föreslagit det!

Shit pommes frites, jag committade och insåg omedelbart att jag måste göra en liten ändring!

# gör din ändring
git add . # eller lägg till individuella filer
git commit --amend --no-edit
# nu innehåller din senaste commit den ändringen!
# VARNING: använd aldrig amend på publika commits

Detta händer oftast mig när jag committar, och sen kör tester/linters... och blä, jag hade glömt ett mellanslag efter ett likhetstecken. Du kan också göra ändringen som en ny commit och efteråt göra rebase -i för att squasha ihop dem, men detta är typ en miljon gånger snabbare.

Varning: Du bör aldrig amend:a commits som har pushats till en publik/gemensam branch! Gör bara amend på commits som bara existerar på din lokala kopia, annars kan du få det jobbigt.

Shit pommes frites, jag måste byta meddelandet på min senaste commit!

git commit --amend
# följ instruktionerna för att ändra meddelandet för committen

Dumma commitmeddelandeformateringsregler.

Shit pommes frites, jag råkade committa något till master som borde ha varit på en helt ny branch!

# skapa en ny branch från masters nuvarande tillstånd
git branch some-new-branch-name
# återställ senaste commit från branchen master
git reset HEAD~ --hard
git checkout some-new-branch-name
# din commit bor i denna branchen nu :)

Bemärk: Detta fungerar inte om du redan har pushat committen till en publik/gemensam branch, och om du försökt andra saker först, kan du behöva göra git reset HEAD@{number-of-commits-back} istället för HEAD~. Oändlig sorg. Slutligen, många många många människor föreslog en grym grej för att göra detta kortare som jag inte själv kände till. Tack alla!

Shit pommes frites, jag råkade committa till fel branch!

# ångra senaste commit, men lämna kvar ändringarna
git reset HEAD~ --soft
git stash
# flytta till rätt branch
git checkout namnet-av-rätt-branch
git stash pop
git add . # eller lägg till individuella filer
git commit -m "ditt meddelande här"
# nu finns dina ändringar på rätt branch

Massor av människor har föreslagit cherry-pick för denna situationen också, så välj den lösning som ger mest mening för dig!

git checkout namnet-av-rätt-branch
# hämta senaste commit från master
git cherry-pick master
# ta bort den från master
git checkout master
git reset HEAD~ --hard

Shit pommes frites, jag försökte köra en diff men inget hände?!

Om du vet att du har gjort ändringar i filer, men diff är tom, då har du förmodligen add:at dina filer till staging och behöver använda en speciell flagga.

git diff --staged

Spara detta tips under ¯\_(ツ)_/¯ (ja, jag vet att detta är en feature och inte en bugg, men den är jävligt förbluffande och icke-uppenbar första gången det händer dig!)

Shit pommes frites, jag måste ångra en commit från typ 5 commits sedan!

# hitta committen som du måste ångra
git log
# använd piltangenterna för att scrolla upp och ned i historiken
# när du har hittat din commit, spara hashen
git revert [saved hash]
# git kommer att skapa en ny commit som ställer tillbaka ändringarna från den committen
# följ instruktionerna för att ändra meddelandet för committen
# eller bara spara filen och committa

Det visar sig att du inte behöver leta upp och copy-paste:a den gamla filens innehåll i den nuvarande filen för att ångra ändringar! Om du har committat en bugg, kan du ångra hela committen med revert.

Du kan också ångra en enstaka fil istället för en hel commit! Men såklart, på äkta git-manér, är det en helt annan jävla uppsättning kommandon...

Shit pommes frites, jag måste ångra mina ändringar av en fil!

# hitta en hash från en commit innan filen ändrades
git log
# använd piltangenterna för att scrolla upp och ned i historiken
# när du har hittat din commit, spara hashen
git checkout [saved hash] -- path/to/file
# den gamla versionen av filen kommer att vara i ditt index
git commit -m "Wow, du behöver inte copy-paste:a för att ångra"

När jag äntligen upptäckte detta var det STORT. STORT. S-T-O-R-T. Men helt ärligt, på vilken jävla planet är det mest logiskt att checkout -- är bästa sättet att undo:a en fil? :skakar-näven-åt-linus-torvalds:

Åt helvete med detta, jag ger upp.

cd ..
sudo rm -r dumma-git-repo-katalog
git clone https://någon.github.url/dumma-git-repo-katalog.git
cd dumma-git-repo-katalog

Tack till Eric V. för denna. Alla klagomål om sudo i detta skämtet kan riktas mot honom.

Men allvarligt talat, om din branch är sååå trasig att du behöver nollställa ditt repos tillstånd till att bli smamma som repot som är remote på ett "git-godkänt" sätt, försök med detta, men bemärk att dessa är destruktiva och oåterkalleliga kommandon!

# hämta senaste tillstånd från origin
git fetch origin
git checkout master
git reset --hard origin/master
# radera ospårade filer och kataloger
git clean -d --force
# upprepa checkout/reset/clean till varje förstörd branch

*Varning: Denna site är inte avsedd att vara heltäckande. Och ja, det finns andra sätt att göra samma sak med mer teoretisk äkthet eller något, men jag har kommit fram till dessa steg genom praktisk felsökning och massor av svärande och vältande av bord, och jag fick den här galna idén att dela dem med en hälsosam dos av lättfärdighet. Ta det för vad det är!

Tack så mycket till alla som har bidragit med att översätta sajten till nya språk, ni rockar! Björn Söderqvist (sv) · 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) · Khaja Md Sher E Alam (bn) · Rahul Dahal (ne) · Taha Paksu (tr) · Kitt Tientanopajai (th) · Gyeongjae Choi (ko) . Med ytterligare hjälp från Iain Murray · Frank Taillandier · David Fyffe · Lucas Larson · Artem Vorotnikov

Om du vill hjälpa till och översätta till ditt språk, lägg in en PR på GitHub