Du er så uheldig og fått en diverged branch i git. Hvordan var dette igjen? Skulle jeg pushe så pulle, eller var det pulle så pushe? Her får du svar på hvordan du løser divirged branch og hvordan du i det hele tatt støter på det og hva det faktisk er!
Git: divirgent branches
TL;DR 📖🐇
- Beholde både remote og local:
git pull --rebase
- Beholde local og forkaste remote:
git push --force
- Beholde remote og forkaste local:
git reset --hard origin/main
Divirged branch 🌳
Jeg spurte ChatGPT om den kunne forklare dette til meg som om jeg var 5 år og fikk følgende 👶🏼:
Tenk på Git som en stor sykkelsti der du og vennene dine sykler sammen. Hver sti er som en "gren" (branch). Noen ganger kan det skje at du og en venn begynner å sykle på samme sti, men dere tar forskjellige veier.
Når dere begge prøver å komme til mål samtidig, kan det bli forvirrende fordi dere har syklet forskjellige ruter. Dette kalles "divergerende grener" (divergent branches). Det betyr at rutene (endringene) på stien (grenen) er forskjellige, og dere må finne ut hvordan dere skal sykle sammen igjen. 🚴♂️
Oppdatert: Her er både local og remote på samme nivå. Alt er oppdatert, og du trenger ikke forholde deg til noe.
Lokal bak: Her ligger den koden som du sitter på, bak remote. Dette løser du ved å skrive inn klassikeren git pull
.
Remote bak: Du har skrevet ny kode og kjørt en git commit
. Du mangler bare å gjøre en git push
så er du good.
Divirgent branches. Ai ai, her har remote og local branch divergert, og du må rette opp i dette. Les videre - så forklarer jeg hvordan!
Hvordan vet jeg at jeg har fått en divirged branch? 🤷🏽♂️
Det finnes flere måter å oppdage at du har gått divirged branch på. Her er noen vanlige måter.
git push
Dersom det finnes en remote endring som du selv ikke har, og du prøver kommanden git push
på en lokal endring, vil du få noe sånt som dette:
To github.com:fredrikmork/git-experiments.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:fredrikmork/git-experiments.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git pull
Kanskje man blir litt forvirret av hintet over og gjør en git pull i den samme situasjonen. Da vil du i så fall få denne meldingen:
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.
git status
Hvis du har en endring remote som du ikke har lokalt, ligger din lokale bak. Da kan du kjøre git fetch
etterfulgt av git status
. Da vil du få denne meldingen:
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
Dette betyr som regel at du ikke har siste versjon av remote, og du kan hente den med git pull
.
Dette fikser biffen 🥩
Det er ikke bare én løsning på divergent branches. Det kommer følgelig an på din situasjon 🫵 Bli med meg i et dypdykk ned i ulike situasjoner og potensielle løsninger. 🤿
Beholde både remote og local
git pull --rebase
- Løs konflikten før du går videre
<<<<<<< HEAD
Remote endring.
=======
Legger på litt tekst.
>>>>>>> 6168a9d (Lokal endring)
git rebase --continue
. Verre var det ikke 😊
Her er en annen variant hvis du ikke vil rebase 🤓
git reset --soft HEAD~1
git stash
git pull
git stash pop
git commit
git push
Beholde kun lokal
Du må være forsiktig med bruk av --force
, men dette fungerer dersom du ikke vil ta vare på endringen i remote som du ikke har lokalt. Da vil din lokale endring være den siste gjeldende (the force is strong with this one).
git push --force
Beholde kun remote
Hvis det du har commitet lokalt ikke skal inn i branchen likevel, for eksempel på grunn av en divergerende remote branch. NB: Pass på når du kjører denne kommandoen ⚠️
git reset --hard origin/main
➡️ Dette vil så skje:
- Nåværende branch blir tilbakestilt. Det betyr at den vil bli satt til å matche tilstanden til
origin/main
-branchen. - Lokale endringer blir forkastet.
--hard
-alternativet betyr at alle lokale endringer i arbeidskatalogen og staging-området vil bli forkastet. Dette inkluderer ikke-committede endringer og commits som ikke er iorigin/main
-grenen.
Happy days 🌅
Du nå fått en oversikt over ulike scenarioer som fører til diverged branches, og et bilde over hvordan disse kan løses i de forskjellige situasjonene. Det finnes helt klart flere måter å både oppdage og løse disse utfordringene på, men forhåpentligvis kommer du langt med disse metodene. Og frykt ikke – divergent branches betyr bare at kodebasen din lever. ⛵️