Tilbake
8.3
Versjonskontroll og samarbeid

8.3 Versjonskontroll og samarbeid

Git, GitHub, branching og pull requests.

55 min
6 oppgaver
GitGitHubBranchingPull requests
Du leser den tradisjonelle versjonen
Din fremgang i kapitlet
0 / 6 oppgaver

Git er det dominerande verktøyet for versjonskontroll i moderne programvareutvikling. I dette kapittelet går vi djupare inn i avanserte Git-konsept som branching, merging og pull requests – teknikkar som er essensielle for effektivt teamarbeid.

Vi skal også sjå på GitHub Flow, ein populær arbeidsflyt for kontinuerleg leveranse.

Branching (Forgreining)

Ein branch er ein parallell versjon av kodebasen der du kan jobbe isolert utan å påverke hovudversjonen (main/master).

Vanlege branching-strategiar:

Feature branches:
- Éin branch per ny feature
- Namnekonvensjon: feature/brukerprofil, feature/betaling
- Blir merga til main når ferdig

Bugfix branches:
- Namnekonvensjon: bugfix/login-crash, fix/null-pointer

Release branches:
- Førebur ein ny versjon til produksjon
- Namnekonvensjon: release/v2.1.0

Hotfix branches:
- Kritiske feil i produksjon som må fiksast straks
- Namnekonvensjon: hotfix/security-patch

Grunnleggjande Git branch-kommandoar:

# Opprett og bytt til ny branch
git checkout -b feature/ny-funksjon

# Vis alle branches
git branch -a

# Bytt til eksisterende branch
git checkout main

# Slett branch (etter merge)
git branch -d feature/gammel-funksjon

# Tvungen sletting (vær forsiktig!)
git branch -D feature/forkastet-ide

Merging

Merging kombinerer endringar frå éin branch inn i ein annan:

Fast-forward merge:
Når target branch ikkje har nye commits sidan branching:

git checkout main
git merge feature/enkel-endring

Three-way merge:
Når begge branches har nye commits:
- Git lagar ein merge commit som kombinerer endringane

Merge conflicts:
Oppstår når same linje er endra i begge branches:

git merge feature/konflikt
# CONFLICT (content): Merge conflict in app.py

# Åpne app.py og finn:
<<<<<<< HEAD
def greeting():
    return "Hei"
=======
def greeting():
    return "Hello"
>>>>>>> feature/konflikt

Løyse konflikten:
1. Rediger fila manuelt, vel rett versjon (eller kombiner)
2. Fjern conflict markers (<<<<<<<, =======, >>>>>>>)
3. git add app.py
4. git commit

Rebase (alternativ til merge)

Rebase flyttar dine commits til toppen av ein annan branch:

git checkout feature/min-branch
git rebase main

Fordel: Lineær commit-historikk (reinare enn merge commits)
Ulempe: Skriv om historikk (ikkje bruk på public branches!)

Pull Requests (PR) / Merge Requests (MR)

Ein pull request er ein førespurnad om å merge din branch til main:

Typisk PR-flyt:
1. Lag feature branch og commit endringar
2. Push branch til GitHub: git push origin feature/ny-funksjon
3. Åpne PR på GitHub
4. Be om code review frå teammedlemmer
5. Diskuter, gjer endringar basert på feedback
6. Når godkjent: Merge til main

God PR-praksis:
- Hald PRs små (< 400 linjer kode)
- Skriv skildrande tittel og oppsummering
- Link til issue/ticket
- Inkluder screenshots for UI-endringar
- Sørg for at CI/CD-testar passerer

GitHub Flow

Ein enkel, branch-basert arbeidsflyt:

1. Main er alltid deploybar – All kode i main er produksjonsklar
2. Lag descriptive branchesfeature/user-authentication
3. Commit ofte – Små, fokuserte commits
4. Åpne PR tidleg – Få tilbakemelding undervegs
5. Diskuter og gjennomgå – Code review før merge
6. Merge og deploy – Automatisk deploy til produksjon etter merge

Git best practices:

- Commit ofte, push dagleg
- Skriv gode commit messages: "Legg til validering av e-post", ikkje "fix"
- Pull før du push (unngå konfliktar)
- Bruk .gitignore for å ekskludere autogenererte filer
- ALDRI commit hemmelegheiter (API-nøklar, passord)
- Bruk meaningful branch names

✏️Eksempel: Feature branch workflow
Scenario: Du skal leggje til ein "Glemt passord"-funksjon i ein Flask-app.

Steg 1: Opprett branch

# Sørg for at main er oppdatert
git checkout main
git pull origin main

# Lag ny feature branch
git checkout -b feature/forgot-password

Steg 2: Gjer endringar

# Rediger nødvendige filer
# app.py, templates/forgot_password.html, etc.

# Commit endringer
git add app.py templates/forgot_password.html
git commit -m "Legg til forgot password-funksjonalitet

- Nytt endepunkt /forgot-password
- E-postvalidering
- Send reset-lenke på e-post
- Testdekning: test_forgot_password.py"

Steg 3: Push og åpne PR

# Push branch til GitHub
git push origin feature/forgot-password

# Gå til GitHub og åpne Pull Request
# Tittel: "Legg til glemt passord-funksjonalitet"
# Beskrivelse:
# "Implementerer forgot password-flow:
# - Bruker oppgir e-post
# - Mottar reset-lenke
# - Kan sette nytt passord
#
# Closes #45"

Steg 4: Code review og feedback
Kollega kommenterer:
"Bør vi ha rate limiting på /forgot-password for å forhindre spam?"

Du gjer endringar:

# Legg til rate limiting
git add app.py
git commit -m "Legg til rate limiting på forgot password (max 3/time)"
git push origin feature/forgot-password
# PR oppdateres automatisk

Steg 5: Merge
Etter godkjenning:

# På GitHub: Klikk "Merge pull request"
# Eller via kommandolinje:
git checkout main
git merge feature/forgot-password
git push origin main

# Slett branch (opprydding)
git branch -d feature/forgot-password
git push origin --delete feature/forgot-password

✏️Eksempel: Løyse merge conflict
Scenario: To utviklarar har endra same fil.

Developer A (på main):

# config.py
DATABASE_URL = "postgresql://localhost/myapp"
DEBUG = False

Developer B (på feature/ny-database):

# config.py
DATABASE_URL = "postgresql://localhost/testdb"
DEBUG = True

Developer B prøver å merge:

git checkout main
git pull  # Får Developer A's endringer
git checkout feature/ny-database
git merge main

# Output:
Auto-merging config.py
CONFLICT (content): Merge conflict in config.py
Automatic merge failed; fix conflicts and then commit the result.

config.py ser no slik ut:

<<<<<<< HEAD
DATABASE_URL = "postgresql://localhost/testdb"
DEBUG = True
=======
DATABASE_URL = "postgresql://localhost/myapp"
DEBUG = False
>>>>>>> main

Løysing:
Developer B diskuterer med Developer A og blir samde om rett løysing:

# config.py (konflikt løst)
DATABASE_URL = "postgresql://localhost/myapp"
DEBUG = True  # Beholder DEBUG=True for testing

Fullfør merge:

git add config.py
git commit -m "Merge main og løs konflikt i config.py"
git push origin feature/ny-database

Oppgåve 1 (Flerval)
Kva er formålet med ein feature branch?

A) Å publisere nye versjonar til produksjon
B) Å jobbe på ny funksjonalitet isolert frå main
C) Å fikse kritiske bugs i produksjon
D) Å slette gammal kode

Oppgåve 2 (Flerval)
Kva skjer når du køyrer git merge feature/ny-funksjon frå main-branchen?

A) Main blir sletta og erstatta av feature/ny-funksjon
B) Endringar frå feature/ny-funksjon blir kombinerte med main
C) Feature/ny-funksjon blir sletta
D) Alle commits i main forsvinn

Oppgåve 3
Forklar kort kva ein merge conflict er, og korleis du løyser han.

Oppgåve 4
Skriv Git-kommandoane for å:
a) Opprette ein ny branch kalla feature/login
b) Bytte til denne branchen
c) Merge han inn i main
d) Slette branchen etter merge

Oppgåve 5
Kva er skilnaden mellom git merge og git rebase?

Oppgåve 6
Nemn tre ting som kjenneteiknar ein god pull request.

Oppgåve 7
Forklar kort kva GitHub Flow er.

Oppgåve 8
Kvifor er det viktig å halde pull requests små (under 400 linjer)?

// --- Samleoppgåver ---

Samleoppgåve 1
Du jobbar på eit team med 5 utviklarar. De bruker GitHub Flow. Prosjektet er ein nettbutikk.

a) Skildr steg-for-steg korleis du ville implementert ein ny feature: "Kundeanmeldelser av produkt".
b) Kva gjer du hvis ein kollega allereie har endra same fil du jobbar på?
c) Når i prosessen bør du be om code review?
d) Kva gjer du hvis CI/CD-testane feilar på din PR?

Samleoppgåve 2
Eit team opplever følgjande situasjon:
- Developer A har jobba på feature/search i 2 veker
- Main har fått 50 nye commits i mellomtida
- Developer A prøver å merge, får 15 merge conflicts

a) Kvifor oppstod så mange konfliktar?
b) Forklar korleis Developer A kunne unngått dette problemet.
c) Skildr to strategiar for å løyse situasjonen no.
d) Kva for team-rutinar kunne førebygd problemet?

Oppsummering

I dette kapittelet har du lært:

- Versjonskontroll: sporar endringar og samarbeid.
- Branchar: parallelle utviklingslinjer.
- Merge og konfliktar: flette saman og løyse konfliktar.
- Feature branch workflow: vanleg arbeidsflyt.
- Samarbeid: koordinere arbeid mellom utviklarar.

Nøkkelomgrep


OmgrepForklaring
BranchParallell utviklingslinje i Git
MergeÅ flette saman branchar
Merge-konfliktMotstridande endringar som må løysast manuelt

Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.