Interactieve rebase wordt soms het “Zwitsers zakmes” van Git genoemd – omdat het zoveel verschillende tools bevat, voor zoveel verschillende gebruikssituaties! Maar er is één overkoepelend gebruik: het opschonen van je lokale commit geschiedenis.
Denk aan het woord “lokaal”: het zou alleen gebruikt moeten worden voor het opschonen van je eigen, lokale commit geschiedenis, bijvoorbeeld voordat je een van je feature branches integreert in een team branch. Het zou daarentegen NIET gebruikt moeten worden op commit geschiedenis die al gepushed en gedeeld is op een remote repository. Interactieve rebase is een van die tools die de Git historie “herschrijven” – en je zou dit niet moeten doen op commits die al met anderen gedeeld zijn.
Met deze kleine waarschuwing uit de weg, laten we eens kijken naar wat praktische voorbeelden!
Note: om de scenario’s en workflows in deze post makkelijker te visualiseren, heb ik de “Tower” Git desktop GUI gebruikt in sommige van mijn screenshots.
Een oud commit bericht corrigeren
Soms zie je een typfout in een oud commit bericht – of je bent iets vergeten te noemen in de beschrijving dat opmerkelijk is. Als we het over de allerlaatste commit hadden, dan hadden we gewoon de --amend
optie van het git commit
commando kunnen gebruiken. Maar voor oudere commits zul je interactieve rebase moeten gebruiken om ze achteraf te wijzigen.
Hier is een voorbeeld van een commit boodschap die vreselijk fout is gegaan en die we willen corrigeren:
Een slechte commit boodschap die gecorrigeerd moet worden
De eerste stap in iedere interactieve rebase sessie is om te bepalen welk deel van de commit geschiedenis je wilt manipuleren. Om nogmaals het bovenstaande voorbeeld te nemen: om deze slechte commit te veranderen, moeten we de sessie bij zijn bovenliggende commit starten.
Start onze interactieve rebase sessie
We kunnen nu de hash van deze start commit aan het interactieve rebase commando toevoeren:
$ git rebase -i 0023cddd
Een editor venster zal nu openen, met daarin een lijst van de commits die je zojuist geselecteerd hebt om te manipuleren. En wees niet verbaasd omdat ze in omgekeerde volgorde staan: in een interactieve rebase sessie, zal Git de oude commits opnieuw toepassen, item na item – wat betekent dat het omkeren van de volgorde correct is vanuit Git’s perspectief.
Editor venster met de geselecteerde commits
Eén ander belangrijk ding om op te merken over dit editor venster: je voert hier niet de daadwerkelijke manipulaties uit! Of, in dit concrete voorbeeld, ga je NIET de commit boodschap hier veranderen. In plaats daarvan markeer je alleen de commit die je wilt veranderen met een actie sleutelwoord. In ons geval, omdat we de boodschap van een commit willen veranderen, markeren we de regel met “reword”. Als je dan dit editor venster opslaat en sluit, zal er een nieuw venster geopend worden, met daarin de oude commit boodschap. Nu is het tijd om eindelijk je wijzigingen door te voeren:
Eindelijk kunnen we onze wijzigingen doorvoeren
Na nogmaals opslaan en sluiten, is de interactieve rebase sessie compleet en onze oude commit boodschap is gecorrigeerd!
Meerdere commits in één combineren
Een ander gebruik voor interactieve rebase is als je meerdere oude commentaren in één wilt combineren. Hoewel, natuurlijk, de gouden regel van versiebeheer van toepassing is: in de meeste situaties is het gunstig om meer en kleinere commits te maken in plaats van een paar grote. Maar, zoals met alles, kunnen we erachter komen dat we dit hebben overdreven en nu twee of meer oude commits willen samenvoegen tot een enkele.
Om een concreet voorbeeld te maken, laten we zeggen dat we de volgende geselecteerde commits in een enkele willen combineren:
Laten we meerdere commits in een combineren
Net als in ons eerste geval, beginnen we met het starten van de interactieve rebase sessie op zijn minst bij de ouder commit van degene die we willen manipuleren.
$ git rebase -i 2b504bee
Opnieuw zal er een editor venster openen, die dat deel van onze commit geschiedenis weergeeft dat we willen manipuleren:
Regels markeren met “squash”
Het actie sleutelwoord dat we hier gaan gebruiken heet “squash.” En er is maar één belangrijk stukje informatie dat je moet weten over squash om het te kunnen gebruiken: de regel die we markeren met het “squash” sleutelwoord zal gecombineerd worden met de regel er direct boven. Dat is waarom, zoals je in mijn screenshot hierboven kunt zien, ik regel #2 met “squash” gemarkeerd heb om het met regel #1 te combineren.
We kunnen nu opslaan en het editor venster sluiten en weer kijken en er verschijnt een nieuw venster: we worden nu gevraagd om een commit boodschap op te geven voor de nieuwe commit die gecreëerd wordt als we die twee oude commit combineren.
Een nieuw bericht voor de nieuwe, geplette commit
Na het opslaan en sluiten van dit editor venster, zul je zien dat er een nieuwe commit is aangemaakt die de changesets van beide oude commits bevat. Voila!
Een fout herstellen
Een ander gebruik voor interactieve rebase is als je een fout hebt gevonden in een van je eerdere commits. En het maakt niet uit wat je precies verknoeid hebt: je kunt vergeten zijn om een bepaalde wijziging toe te voegen, je had een bestand moeten verwijderen, of gewoon een typefout geïntroduceerd hebben…
De natuurlijke neiging, in zo’n situatie, is om gewoon een nieuwe commit te maken die de fout corrigeert. Maar aan de andere kant, zal dit onze commit geschiedenis verknoeien: een originele commit maken, en dan een “pleister” commit toevoegen alleen om wat fouten te herstellen… dat is een rommelige manier van werken. Je commit geschiedenis zal al snel moeilijk te begrijpen worden, omdat het bezaaid is met al die kleine “snelle reparatie commits”!
Dit is waar “fixup,” één van de gereedschappen die bij interactieve rebase geleverd worden, erg handig is. Fixup neemt deze “quick fix” commit, past zijn wijzigingen toe op de originele commit (en corrigeert deze daarmee), en verwijdert dan de pleister commit:
Hoe “fixup” werkt
Nadat we klaar zijn, ziet het eruit alsof er nooit een probleem met onze originele commit is geweest! Dus laten we dit doornemen met een praktisch voorbeeld.
De eerste stap is om alles te doen wat nodig is om het probleem op te lossen: dit kan betekenen dat je een nieuw bestand toevoegt, wijzigingen aanbrengt in bestaande bestanden, verouderde bestanden verwijdert… je hoeft “alleen maar” de wijzigingen aan te brengen die de fout corrigeren.
De volgende stap is om deze wijzigingen naar het archief te committen – maar met een beetje extra: bij het maken van de commit, gaan we de --fixup
vlag gebruiken en Git de commit hash van onze slechte commit vertellen:
$ git add corrections.txt$ git commit --fixup 2b504bee
Als je nu naar de commit geschiedenis kijkt, zul je zien dat er een vrij normaal uitziende commit is gemaakt – waarschijnlijk niet de magie en het vuurwerk dat je verwacht zou hebben. Maar als je beter kijkt, zul je zien dat er iets aan de hand is: de nieuwe commit is automatisch voorafgegaan door “fixup !” en het commit onderwerp van onze slechte commit.
De originele commit en de fix commit
De derde stap is nu om de interactieve rebase sessie te starten. Nogmaals, we kiezen de ouder van onze slechte commit als het startpunt…
$ git rebase -i 0023cddd --autosquash
… en als het tweede deel van de geheime saus, gebruiken we de --autosquash
vlag. Deze optie zorgt ervoor dat we niets hoeven te doen in het editor venster dat nu open is. Kijk eens goed naar de situatie:
Onze fix commit is gemarkeerd als “fixup” en naar de juiste positie gesorteerd
Je zult zien dat Git automatisch twee dingen voor ons heeft gedaan:
- Het heeft onze pleister commit gemarkeerd als “fixup.”
- Het heeft de regels opnieuw geordend, zodat onze pleister commit direct onder onze slechte commit verschijnt. Dit is omdat fixup precies zo werkt als squash, in die zin dat het combineert met de regel erboven.
Met andere woorden: er zit niets anders op dan op te slaan en het editor venster te sluiten.
Laten we nog eens naar de commit geschiedenis kijken:
Een happy end!
Niet alleen bevat onze oorspronkelijk slechte commit nu de wijzigingen van onze band-aid commit. Maar daar bovenop, is de lelijke commit van de pleister verdwenen uit de commit geschiedenis! Alles is netjes en schoon, net alsof er nooit een probleem is geweest!
Ontdek de kracht van interactieve rebase
Er zijn veel gebruikssituaties voor interactieve rebase – en de meeste daarvan in de afdeling van “fouten herstellen”. Voor een overzicht van andere nuttige dingen die je kunt doen, raad ik de gratis “First Aid Kit for Git” aan: het is een verzameling korte video’s (2-3 min per aflevering) die je helpen om fouten ongedaan te maken met interactieve rebase en andere Git tools.
Note van de redacteur: Ik moest interactieve rebase gebruiken toen ik dit bericht aan het nakijken was! Een van mijn commits bevatte een afbeelding die groter was dan 1MB, wat tegen de regels is voor GitLab website project. Ik moest teruggaan en die commit repareren om een afbeelding van de juiste grootte erin te zetten. Bedankt voor de les, universum! 😁
Meer Git tips en trucs
- 15 Git tips om je workflow te verbeteren
- Hoe Git Partial Clone je alleen het grote bestand laat ophalen dat je nodig hebt
- Git happens! 6 Veelgemaakte Git fouten en hoe ze op te lossen
Over de gast auteur
Tobias Günther is de CEO van Tower, de populaire Git desktop client die meer dan 100.000 ontwikkelaars over de hele wereld helpt om productiever te zijn met Git.
Bedrukking afbeelding door David Taljat op Pexels