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
- https://github.com/gitextensions/gitextensions
- 100% open source.
- Startede som plugin til VS 2015.
- Benyt som stand alone, ikke VS plugin.
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.
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.
Cherry pick er bare at overføre de samme "file changes" et andet sted i commit træet.
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.
Merge feature branches (PR) eller hotfixes. Alternativt Squash commits.
Imellem development/master/release branches.
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.
- 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
- Fetch og rebase på "upstream"
- 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.
- 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.
- 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.
--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.
- 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
- Kort svar: Aldrig!
- Bruges KUN når der er sket noget katestrofalt forkert i develop eller master
"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.
index.lock file locked. - Død process har lås. Nemmeste løsning er genstart + slet index.lock.
- Soft reset
- Hard reset (paaaaas på!)
- Multiple branches
- Shared feature branches "Team branches"