Interaktiv rebase kallas ibland för Gits ”schweiziska armékniv” – eftersom den innehåller så många olika verktyg, för så många olika användningsområden! Det finns dock ett huvudanvändningsfall: att städa upp din lokala commit-historik.
Håll dig till ordet ”lokal”: det bör endast användas för att städa upp din egen, lokala commit-historik, till exempel innan du integrerar en av dina funktionsgrenar i en teamgren. Det ska däremot INTE användas för commit-historik som redan har pushats och delats i ett fjärrarkiv. Interactive rebase är ett av de verktyg som ”skriver om” Git-historiken – och du bör inte göra detta på commits som redan har delats med andra.
Med detta lilla varningsmeddelande ur vägen, låt oss titta på några praktiska exempel!
Notera: för enklare visualisering av scenarierna och arbetsflödena i det här inlägget har jag använt Git desktop GUI ”Tower” i några av mina skärmdumpar.
Korrigera ett gammalt commit-meddelande
Ibland upptäcker du ett stavfel i ett gammalt commit-meddelande – eller så har du glömt att nämna något i beskrivningen som är anmärkningsvärt. Om vi pratade om den allra sista commit kunde vi helt enkelt ha använt alternativet --amend
i kommandot git commit
. Men för äldre commits måste du använda interactive rebase för att ändra dem i efterhand.
Här är ett exempel på ett commitmeddelande som gått fruktansvärt fel och som vi vill korrigera:
Ett dåligt commitmeddelande som behöver korrigeras
Det första steget i en interaktiv rebase-session är att bestämma vilken del av commithistoriken du vill manipulera. För att återigen ta exemplet ovan: för att ändra denna dåliga commit måste vi starta sessionen på dess överordnade commit.
Startar vår interaktiva rebase-session
Vi kan nu mata denna startcommits hash till kommandot för interaktiv rebase:
$ git rebase -i 0023cddd
Ett redigeringsfönster kommer nu att öppnas, som innehåller en lista med de commits som du just valde för manipulation. Och bli inte förvånad eftersom de är i omvänd ordning: i en interaktiv rebase-session kommer Git att återanvända de gamla commits, objekt efter objekt – vilket innebär att omvänd ordning är korrekt ur Gits perspektiv.
Editorfönster med de markerade commits
En annan viktig sak att notera om det här editorfönstret: du utför inte de faktiska manipulationerna här! Eller, i det här konkreta exemplet, du går INTE vidare och ändrar commit-meddelandet här. Istället markerar du bara den commit du vill ändra med ett nyckelord för handling. I vårt fall, eftersom vi vill ändra en commits meddelande, markerar vi raden med ”reword”. Om du sedan sparar och stänger det här redigeringsfönstret öppnas ett nytt fönster med det gamla meddelandet. Nu är det dags att äntligen göra dina ändringar:
Äntligen kan vi göra våra ändringar
Efter att ha sparat och stängt en gång till är den interaktiva rebase-sessionen avslutad och vårt gamla commit-meddelande har korrigerats!
Kombinera flera commits till en
Ett annat användningsområde för interaktiv rebase är när du vill kombinera flera gamla kommentarer till en. Även om den gyllene regeln för versionskontroll naturligtvis gäller: i de flesta situationer är det fördelaktigt att skapa fler och mindre commits istället för några få stora. Men som med allting kan det hända att vi upptäcker att vi har överdrivit och nu vill smälta ihop två eller flera gamla commits till en enda.
För att göra ett konkret exempel, låt oss säga att vi vill kombinera följande utvalda commits till en enda:
Let’s combine multiple commits into one
Som i vårt första fall börjar vi med att starta den interaktiva rebase-sessionen åtminstone vid den överordnade commiten till den vi vill manipulera.
$ git rebase -i 2b504bee
Ett redigeringsfönster öppnas och listar den del av vår commit-historik som vi vill manipulera:
Markering av rader med ”squash”
Aktionsnyckelordet som vi kommer att använda här kallas ”squash”. Och det finns bara en viktig information som du behöver känna till om squash för att kunna använda det: den rad vi markerar med nyckelordet ”squash” kommer att kombineras med raden direkt ovanför. Därför har jag, som du kan se i min skärmdump ovan, markerat linje #2 med ”squash” för att kombinera den med linje #1.
Vi kan nu spara och stänga redigeringsfönstret och återigen titta på och ett nytt fönster dyker upp: vi ombeds nu att ange ett commitmeddelande för den nya commit som skapas när vi kombinerar de två gamla.
Insättning av ett nytt meddelande för det nya, krossade commit
Efter att ha sparat och stängt det här redigeringsfönstret kommer du att se att ett nytt commit har skapats som innehåller ändringssatserna från de båda gamla commits. Voila!
Rätta ett misstag
Ett annat användningsområde för interaktiv rebase är när du har hittat ett misstag i en av dina tidigare commits. Och det spelar ingen roll vad exakt du klantade dig med: du kan ha glömt att lägga till en viss ändring, borde ha raderat en fil eller helt enkelt ha infört ett skrivfel…
Den naturliga tendensen, i en sådan situation, är att helt enkelt skapa en ny commit som rättar till misstaget. Men å andra sidan kommer detta att ställa till det i vår commit-historik: att göra en ursprunglig commit och sedan lägga till en ”plåster-commit” bara för att rätta till några misstag… det är ett rörigt sätt att arbeta. Din commit-historik kommer snart att bli svår att förstå, eftersom den är översållad med alla dessa små ”quick fix commits”!
Det är här som ”fixup”, ett av verktygen som följer med interactive rebase, kommer till stor nytta. Fixup tar denna ”quick fix”-commit, tillämpar sina ändringar på den ursprungliga commiten (och korrigerar den därmed) och gör sig sedan av med plåstercommiten:
Hur ”fixup” fungerar
När vi är klara ser det ut som om det aldrig hade funnits ett problem med vår ursprungliga commit! Så låt oss gå igenom detta med hjälp av ett praktiskt exempel.
Det första steget är att göra vad som är nödvändigt för att rätta till problemet: det kan innebära att lägga till en ny fil, göra ändringar i befintliga filer, ta bort föråldrade filer… du behöver ”bara” göra de ändringar som rättar till misstaget.
Nästa steg är att lägga in dessa ändringar i repositoriet – men med lite extra: när vi lägger in ändringen kommer vi att använda flaggan --fixup
och tala om för Git vad vår dåliga commit har för hash:
$ git add corrections.txt$ git commit --fixup 2b504bee
När du nu tar en titt på commit-historiken kommer du att se att en ganska vanligt utseende commit har skapats – troligen inte den magi och de fyrverkerier som du skulle ha förväntat dig. Men om du tittar närmare kommer du att se att något är på gång: den nya commit har automatiskt fått ett prefix med ”fixup !” och commit-subjektet för vår dåliga commit.
Den ursprungliga commit och fix commit
Det tredje steget är nu att starta den interaktiva rebase-sessionen. Återigen väljer vi föräldern till vår dåliga commit som startpunkt…
$ git rebase -i 0023cddd --autosquash
… och som den andra delen av den hemliga såsen använder vi flaggan --autosquash
. Detta alternativ ser till att vi inte behöver göra något i redigeringsfönstret som nu är öppet. Ta en närmare titt på situationen:
Vår fix commit är markerad som ”fixup” och sorterad till rätt position
Du kommer att se att Git automatiskt gjorde två saker åt oss:
- Det markerade vår band-aid commit som ”fixup.”
- Det ordnade om raderna så att vårt band-aid commit visas direkt under vårt dåliga commit. Detta beror på att fixup fungerar precis som squash genom att det kombineras med raden ovanför.
Med andra ord: Det finns inget kvar att göra för oss förutom att spara och stänga redigeringsfönstret.
Vi tar en ny titt på commit-historiken:
Ett lyckligt slut!
Det är inte bara så att vår ursprungligen dåliga commit nu innehåller ändringarna från vår band-aid commit. Men dessutom har den fula band-aid commit försvunnit från commit-historiken! Allt är snyggt och rent, precis som om det aldrig hade funnits något problem!
Upptäck kraften i interaktiv rebase
Det finns många användningsområden för interaktiv rebase – och de flesta av dem ligger inom avdelningen för att ”rätta till misstag”. För en översikt över andra användbara saker du kan göra rekommenderar jag den kostnadsfria ”First Aid Kit for Git”: det är en samling korta videor (2-3 min per avsnitt) som hjälper dig att lära dig att ångra misstag med hjälp av interaktiv rebase och andra Git-verktyg.
Redaktörens anmärkning: Jag var tvungen att använda interaktiv rebase när jag granskade just det här inlägget! En av mina commits innehöll en bild som var större än 1 MB, vilket strider mot reglerna för GitLab-webbplatsprojektet. Jag var tvungen att gå tillbaka och korrigera den commit för att inkludera en korrekt storlek på bilden istället. Tack för lektionen, universum! 😁
Mer Git tips och tricks
- 15 Git tips för att förbättra ditt arbetsflöde
- Hur Git Partial Clone låter dig hämta endast den stora filen du behöver
- Git happens! 6 vanliga Git-fel och hur du åtgärdar dem
Om gästförfattaren
Tobias Günther är vd för Tower, den populära Git-klienten som hjälper mer än 100 000 utvecklare runt om i världen att bli mer produktiva med Git.
Omslagsbild av David Taljat på Pexels