Hopp til hovedinnhold

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!

Et bilde tatt i froskeperspektiv av et tre opp langs stammen. Grenene er dekket i snø.

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. 🚴‍♂️

Oversikt over forskjellige tilstander i brancher. Tegnet opp i Notater på iPad med Apple Pencil 🖊️
Illustrasjon av divirgent branches

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 🤓

  1. git reset --soft HEAD~1
  2. git stash
  3. git pull
  4. git stash pop
  5. git commit
  6. 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:

  1. Nåværende branch blir tilbakestilt. Det betyr at den vil bli satt til å matche tilstanden til origin/main-branchen.
  2. 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 i origin/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. ⛵️

Relevante lenker anbefalt av forfatteren

Liker du innlegget?

Del gjerne med kollegaer og venner