Skip to content

Instantly share code, notes, and snippets.

@PolarbearDK
Last active December 5, 2023 07:12
Show Gist options
  • Save PolarbearDK/b79e65e0a9eba5e80b654c502167c788 to your computer and use it in GitHub Desktop.
Save PolarbearDK/b79e65e0a9eba5e80b654c502167c788 to your computer and use it in GitHub Desktop.

Rebase! Not Merge

Git a-la Philip


Git er et værktøj i udvikler værktøjskassen på lige linie med IDE og compilers.

Det er noget man skal sætte sig ind i og blive god til.

Er du god til Git er det nemt at:

  • Hurtigt skifte imellem opgaver (branches), hvis der dukker en vigtigere opgave op.
  • Håndtere mange branches samtidig.
  • Håndtere flere branches med indbyrdes afhængigheder.

Philip siger:

Benyt et dedikeret Git værktøj (eller CMD) Benyt ikke det i IDE fordi:

  • Oftest kun et subset af Git operationer.
  • Skjuler rettelser udenfor workspace.
  • "Låser" dig til ét IDE eller at lære flere Git UI’er

Kort præsentation af GitExtensions (Philips valg)

Kan med fordel intalleres med choco (https://chocolatey.org) pakke manager ("npm/nuget" til windows)

Choco kan bruges til at installere fx:

  • Git for Windows
  • Git Extensions
  • KDiff3
  • NVM (Node version manager)
  • Total Commander

Opsætning

  • Konfigurer diff værktøj til 3-Way-Merger. Kdiff3 (Philips valg)
  • Setup Clone location
  • View -> Show artificial commits: Off

Features:

  • Toolbar
  • Compose commit dialog:
    • Add/Remove single lines
    • Type ahead Commit message
    • Ammend commit
  • Cleanup local branches (Gone)
  • Plugins

Philip siger: Undgå mentalt at blande "Code mode" med "Versionsstyrings mode".

Når man er i "Versionsstyrings mode":

  • Review egen kode
  • Undgå unødvendige konflikter med andres rettelser:
    • Undo formatting-only rettelser.
    • Overvej - Giver denne rettelse værdi for kunden - Undo ellers.

Anatomi af et commit (simplificeret)

File Hash = {
    Hash of previous commit
    ...changed files
}

Commit Hash = hash (sha1) af {
    meta data
        commit message
        committer
        commit date
        author
        authoring date
    File Hash
}
  • Baseret på et Parent commit
  • Indeholder snapshot af alle ændrede filer (hele filen).
  • En branch er bare en fil som peger på et commit hash.

Vigtigt! Hvis 2 udviklere laver den samme ændring giver det den samme File Hash.

(Merge commits har 2 parent commits)

Cherry pick

Cherry pick er bare at overføre de samme "file changes" et andet sted i commit træet.


Philip siger: Rebase not Merge

Hvorfor det?

Merge:

  • Kompliceret! - Jeg forstår det nogen gange ikke.
  • Svært læselig (for mennesker) Git historik.
  • Kan give merge konflikter i filer du ikke har ændret.
  • Merge commits ender som "bastard commits" - Ingen vil kendes ved dem.
  • "Hvorfor er den fil med i min branch/Det er ikke mig der har ændret den fil"
  • Enkel (én) konflikt håndtering.

Rebase:

  • Simpel. Konflikt håndtering laves i DINE commits.
  • Let læselig Git historik
  • Resultatet er åbenlyst. Man er aldrig i tvivl om hvilke rettelser der er med i branch.
  • Bøvlet (pr. commit) konflikt håndtering. - Ikke godt hvis konflikt fil er rettet i efterfølgende commits.

Rebase er ikke farligt. Gør det ofte og bliv god til det.

Hvis noget "går galt" så undo og gør det på en anden måde.


Hvornår skal man bruge merge?

Merge feature branches (PR) eller hotfixes. Alternativt Squash commits.

Imellem development/master/release branches.


Interaktiv rebase (kort gennemgang)

Interactive rebase åbner editor med liste af commits der skal med i rebase.

Eksempel:

pick a7403f1 Added feature "Foo"

Hver linie består af en kommando, et commit hash (forkortet) og første linie i commit besked.

Rækkefølge på linier kan ændres (hvis der ikke er fil afhængigheder).

Man kan slette uønskede commits ved bare at fjerne linien.

Kommandoer:
pick = cherry pick: Rebase er bare en serie-cherry-picker!
s = squash: Smelt sammen med linien før, og rediger commit besked.
f = fixup: Smelt sammen med linien før. Brug commit besked fra første commit.
r = reword: Ændre commit besked for commit.
b = break: pick commit, og stop rebase. Du kan nu lave rettelser til commit. git rebase --continue for at fortsætte.

Der findes andre mere eksotiske kommandoer som man sjældent bruger.

Tip! Hvis du føler dig usikker så lav en temp branch før rebase.


Philips udviklings workflow

Lav lokal branch udfra upstream (develop/main/master/whatever)

  • Commit ofte, små commits (commit-hooks gør dette laangsomt)
  • Brug ammend til at tilføje/ændre seneste commit.
  • Fetch og rebase periodisk (et par gange om dagen?).
  • Brug ALDRIG merge. ALDRIG!
  • Hvis der opstår konflikter i en fil som er rettet i flere commits, så abort rebase, squash commits, og rebase igen.
  • Hvis man har benyttet "Git Mergetool" til konflikt håndtering, kan der ligge filer tilbage med endelsen *.orig. De kan bare slettes. Se Git Mergetool Temporary Files

Klargøring af PR når feature er done

  1. Fetch og rebase på "upstream"
  2. Afhængigt af rettelsernes størrelse og karakter:
    • Option 1: Benyt dine commits "as is".
    • Option 2: Benyt interaktiv rebase til at squashe commits til ét eller flere commits og giv hvert commit en god beskrivelse.
    • Option 3: Lav "soft reset" og lav 1 eller flere commits fra de stagede filer.

Push branch til upstream og lav Pull request

Review flow

  • Fix PR comments.
  • Lav commit med rettelser. Lav evt. rettelser direkte i eksisterende commits.
  • Rebase på origin/develop. Dette sørger for at holde koden "up to date" hvis review tager lang tid.
  • git push --force-with-lease.
  • Gentag review flow indtil alle comments er resolved.

Rebase af branch efter push til upstream?

  • En lille smule kontroversielt, da man ændrer i git historik.
  • Ikke for alle! "You are doing it wrong!".

Azure DevOps "Semi-linear merge" er faktisk en rebase efterfulgt af merge.

Hvis du sidder og resolver merge konflikter med din egen branch, så gør du det forkert.


Forskel på --force og --force-with-lease

--force-with-lease sikrer at du ikke mister commits ved at checke at remote branch har samme commits som som den lokale tracking branch har.

Hvornår må man bruge --Force-with-lease?

  • På dine private branches.
  • På dine PR branches hvis ingen andre comitter til den branch.
  • På team feature branches, men det kræver koordinering med alle team medlemmer

Hvornår må man bruge --Force

  • Kort svar: Aldrig!
  • Bruges KUN når der er sket noget katestrofalt forkert i develop eller master

Hvad gør man når man har kvajet sig?

"Erfaring er at genkende en fejl når man laver den igen"

Committed på forkert branch:

  • Cherry pick
  • Rebase with advanced options. --Onto

Når det er gået helt galt: Reflog

  • Find operationen før det gik galt, og lav en branch.

Pas på casing (store/små bogstaver) i branch folder navne.


Førstehjælpskasse

index.lock file locked. - Død process har lås. Nemmeste løsning er genstart + slet index.lock.


Advanced topics

  • Soft reset
  • Hard reset (paaaaas på!)
  • Multiple branches
  • Shared feature branches "Team branches"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment