Interactive rebase kaldes nogle gange for Gits “schweizerkniv” – fordi den indeholder så mange forskellige værktøjer til så mange forskellige brugssituationer! Der er dog én vigtig, overordnet brugssag: oprydning i din lokale commit-historik.
Husk på ordet “lokal”: det bør kun bruges til at rydde op i din egen, lokale commit-historik, f.eks. før du integrerer en af dine feature-grenene i en teamgren. I modsætning hertil bør det IKKE bruges på commit-historik, der allerede er blevet skubbet og delt på et eksternt repository. Interactive rebase er et af de værktøjer, der “omskriver” Git-historikken – og du bør ikke gøre det på commits, der allerede er blevet delt med andre.
Med denne lille advarselsmeddelelse ude af vejen, lad os se på nogle praktiske eksempler!
Bemærk: For nemmere at visualisere scenarierne og arbejdsgangene i dette indlæg, har jeg brugt Git desktop GUI’en “Tower” i nogle af mine skærmbilleder.
Korrektion af en gammel commit-meddelelse
Sommetider opdager du en slåfejl i en gammel commit-meddelelse – eller du har glemt at nævne noget i beskrivelsen, som er bemærkelsesværdigt. Hvis vi talte om den allersidste commit, kunne vi blot have brugt --amend
-indstillingen i kommandoen git commit
. Men for ældre commits skal du bruge interaktiv rebase til at ændre dem efterfølgende.
Her er et eksempel på en commit-meddelelse, der er gået grueligt galt, og som vi ønsker at rette:
En dårlig commit-meddelelse, der skal rettes
Det første skridt i enhver interaktiv rebase-session er at bestemme, hvilken del af commit-historikken du ønsker at manipulere. For igen at tage ovenstående eksempel: For at ændre dette dårlige commit skal vi starte sessionen på dets overordnede commit.
Start af vores interaktive rebase-session
Vi kan nu fodre denne startcommits hash til den interaktive rebase-kommando:
$ git rebase -i 0023cddd
Et editor-vindue åbnes nu med en liste over de commits, som du netop har valgt til manipulation. Og bliv ikke overrasket, fordi de er i omvendt rækkefølge: I en interaktiv rebase-session vil Git genanvende de gamle commits, element efter element – hvilket betyder, at det er korrekt fra Gits perspektiv at vende rækkefølgen om.
Editorvindue med de valgte commits
En anden vigtig ting at bemærke om dette editorvindue: Du udfører ikke de egentlige manipulationer her! Eller, i dette konkrete eksempel, du går IKKE videre og ændrer commit-meddelelsen her. I stedet markerer du kun den commit, du vil ændre, med et nøgleord for handling. I vores tilfælde, fordi vi ønsker at ændre en commit-meddelelse, markerer vi linjen med “reword”. Hvis du derefter gemmer og lukker dette redigeringsvindue, åbnes et nyt vindue, der indeholder den gamle commit-meddelelse. Nu er det tid til endelig at foretage dine ændringer:
Endeligt kan vi foretage vores ændringer
Efter at have gemt og lukket endnu en gang er den interaktive rebase-session afsluttet, og vores gamle commit-meddelelse er blevet rettet!
Kombinere flere commits til én
Et andet anvendelsesområde for interaktiv rebase er, når du ønsker at kombinere flere gamle kommentarer til én. Selv om den gyldne regel for versionsstyring selvfølgelig gælder: I de fleste situationer er det en fordel at oprette flere og mindre commits i stedet for nogle få store. Som med alting kan vi dog finde ud af, at vi har overdrevet og nu ønsker at smelte to eller flere gamle commits sammen til et enkelt.
For at lave et konkret eksempel, lad os sige, at vi ønsker at kombinere følgende udvalgte commits til et enkelt:
Lad os kombinere flere commits til et
Som i vores første tilfælde begynder vi med at starte den interaktive rebase-session i det mindste ved det overordnede commit for det commit, vi ønsker at manipulere.
$ git rebase -i 2b504bee
Et editorvindue åbnes igen og viser den del af vores commit-historik, som vi ønsker at manipulere:
Mærkning af linjer med “squash”
Aktionsnøgleordet, som vi vil bruge her, hedder “squash”. Og der er kun én vigtig oplysning, som du skal kende til squash for at kunne bruge det: Den linje, vi markerer med nøgleordet “squash”, vil blive kombineret med den linje, der ligger lige over. Derfor har jeg, som du kan se på mit skærmbillede ovenfor, markeret linje #2 med “squash” for at kombinere den med linje #1.
Vi kan nu gemme og lukke editor-vinduet og igen se og et nyt vindue vises: Vi bliver nu bedt om at angive en commit-meddelelse for det nye commit, der bliver oprettet ved at kombinere de to gamle commit.
Indtastning af en ny meddelelse for det nye, sammenpressede commit
Når vi gemmer og lukker dette editorvindue, vil du se, at der blev oprettet et nyt commit, som indeholder ændringssættene fra de to gamle commits. Voila!
Rettelse af en fejl
Et andet anvendelsestilfælde for interaktiv rebase er, når du har fundet en fejl i en af dine tidligere commits. Og det er ligegyldigt, hvad det præcis var, du lavede rod i: du kunne have glemt at tilføje en bestemt ændring, skulle have slettet en fil, eller blot have indført en slåfejl…
Den naturlige tendens i en sådan situation er simpelthen at oprette et nyt commit, der retter fejlen. Men på den anden side vil dette ødelægge vores commit-historik: at lave et originalt commit, og derefter tilføje et “plaster på såret” commit bare for at rette nogle fejl… det er en rodet måde at arbejde på. Din commit-historik vil snart blive svær at forstå, fordi den er fyldt med alle de små “quick fix commits”!
Det er her “fixup”, et af de værktøjer, der følger med interactive rebase, kommer meget belejligt. Fixup tager dette “quick fix”-commit, anvender sine ændringer på det oprindelige commit (og retter det derved) og fjerner derefter band-aid-cittet:
Hvordan “fixup” virker
Når vi er færdige, ser det ud som om der aldrig havde været et problem med vores oprindelige commit! Så lad os gennemgå dette ved hjælp af et praktisk eksempel.
Det første skridt er at gøre, hvad der er nødvendigt for at rette problemet: det kan betyde at tilføje en ny fil, foretage ændringer i eksisterende filer, slette forældede filer… du skal “bare” producere de ændringer, der retter fejlen.
Det næste skridt er at committe disse ændringer til repositoriet – men med lidt ekstra: Når vi laver commit’et, vil vi bruge --fixup
-flaget og fortælle Git commit-hash’en for vores dårlige commit:
$ git add corrections.txt$ git commit --fixup 2b504bee
Når du nu kigger på commit-historikken, vil du se, at der er blevet lavet et ret almindeligt udseende commit – sandsynligvis ikke den magi og det fyrværkeri, du havde forventet. Men hvis du kigger nærmere efter, vil du se, at der sker noget: den nye commit er automatisk blevet forsynet med “fixup !” og commit-emnet for vores dårlige commit.
Den oprindelige commit og den rette commit
Det tredje trin er nu at starte den interaktive rebase-session. Igen vælger vi vores dårlige commit’s forælder som startpunkt…
$ git rebase -i 0023cddd --autosquash
… og som den anden del af den hemmelige sauce bruger vi --autosquash
-flaget. Denne indstilling sørger for, at vi ikke behøver at gøre noget i det editorvindue, der nu er åbent. Se nærmere på situationen:
Vor fix commit er markeret som “fixup” og sorteret til den rigtige position
Du vil se, at Git automatisk gjorde to ting for os:
- Det markerede vores band-aid commit som “fixup”.”
- Det omarrangerede linjerne, så vores band-aid commit vises direkte under vores dårlige commit. Dette skyldes, at fixup fungerer nøjagtigt som squash, idet den kombineres med linjen ovenover.
Med andre ord: Der er ikke andet tilbage at gøre for os end at gemme og lukke editorvinduet.
Lad os tage et nyt kig på commit-historikken:
En lykkelig slutning!
Nu indeholder vores oprindeligt dårlige commit ikke kun ændringerne fra vores band-aid-cit. Men oven i købet er det grimme band-aid commit forsvundet fra commit-historikken! Alt er pænt og rent, præcis som om der aldrig havde været et problem!
Opdag kraften i interaktiv rebase
Der er masser af anvendelsesmuligheder for interaktiv rebase – og de fleste af dem i afdelingen for “rettelse af fejl”. For at få et overblik over andre nyttige ting, du kan gøre, anbefaler jeg den gratis “First Aid Kit for Git”: det er en samling af korte videoer (2-3 min. pr. episode), der hjælper dig med at lære at fortryde fejl ved hjælp af interaktiv rebase og andre Git-værktøjer.
Redaktørens note: Jeg måtte bruge interaktiv rebase, da jeg gennemgik netop dette indlæg! En af mine commits indeholdt et billede, der var større end 1 MB, hvilket er i strid med reglerne for GitLab-webstedprojektet. Jeg var nødt til at gå tilbage og rette den commit til at inkludere et billede af korrekt størrelse i stedet. Tak for læren, univers! 😁
Mere Git tips og tricks
- 15 Git tips til at forbedre din arbejdsgang
- Hvordan Git Partial Clone lader dig kun hente den store fil, du har brug for
- Git sker! 6 almindelige Git-fejl, og hvordan du retter dem
Om gæsteforfatteren
Tobias Günther er administrerende direktør for Tower, den populære Git-desktopklient, der hjælper mere end 100.000 udviklere verden over med at være mere produktive med Git.
Oversigtsbillede af David Taljat på Pexels