Wat is Git Rebase en hoe is het anders dan samenvoegen?

0
232

Samenvoegen en rebasen bereiken vergelijkbare doelen, maar gaan op verschillende manieren te werk. Beide helpen bij het werken met branches en samenwerken met meerdere mensen, maar ze zijn niet uitwisselbaar en rebasen kan schadelijk zijn als het niet goed wordt gedaan.

Wat is de deal met rebasen?

Rebasen is erg ingewikkeld, dus het is belangrijk om te begrijpen hoe git onder de motorkap werkt als we er iets van willen begrijpen .

Git slaat je code op als een reeks bewerkingen. Je kunt dit zien als een ketting die achteruit werkt. Elke bewerking, of “commit,” verwijst naar de ID van de vorige commit en bevat wat er is gewijzigd ten opzichte van de vorige commit. Deze keten wordt alleen op uw computer opgeslagen; je Git-client praat niet met andere Git-clients, tenzij het een fetch of push uitvoert (pull is eigenlijk gewoon fetch + merge met je lokale branch), en zelfs dan is het alleen praten naar een gedeelde externe opslagplaats.

Takken zijn ingewikkelder. Git slaat maar één ding op als het om branches gaat: de ID van de commit aan het einde van de branch. Op deze manier kun je ze zien als de afspeelkop op een platenspeler; je zet de takkop op een specifieke positie, en het werkt zijn weg terug door de ketting, “spelend” uw code en komen tot een definitieve versie. Telkens wanneer je commit, zal je lokale git-client de afspeelkop automatisch naar de nieuwe commit verplaatsen.

Als je een functie in master wilt samenvoegen, voer je het volgende uit:

git checkout master git merge feature Advertisement

Dit creëert een nieuwe merge-commit, en als er conflicten zijn, moet je deze handmatig oplossen. Het git merge-commando verplaatst de master-afspeelkop naar de nieuwe merge-commit en verwijdert de feature-afspeelkop, omdat dit niet langer nodig is.

Deze methode voor het samenvoegen van code levert drie problemen op:

  • Er kunnen wijzigingen zijn op de master-branch die de feature-branch zou willen opnemen, vooral als de ontwikkeling van de functie even duurt.
  • Het is vervelend om elke keer dat je met branches wilt werken het merge proces te moeten doorlopen.
  • De commit geschiedenis is rommelig, hoewel dit grotendeels een esthetisch probleem is.

Rebasing probeert deze problemen op te lossen, met wisselend succes. Wijzigingen rebasen waar u uw filiaal bent begonnen. De hele tak wordt opgetild en naar het einde van de huidige mastertak getransporteerd, waar het verbinding maakt met het einde. De master branch blijft onaangeroerd, en is vrij om commits te blijven ontvangen.

De commits worden echter niet echt verplaatst, omdat commits onveranderlijk zijn. In plaats daarvan worden ze gekopieerd, wat resulteert in nieuwe commit-ID's. De vorige commits blijven gestrand, verstopt in je Git-bestanden maar worden nooit meer gezien, omdat de afspeelkop ergens anders is verhuisd.

Om dit proces vanaf de opdrachtregel uit te voeren, zou je uitvoeren:

git checkout-functie git pull git rebase master

Dit opent de vertakking, trekt de huidige wijzigingen naar de master en baseert vervolgens de feature-branch naar de master-branch.

Op dit punt is de code in de feature-branch nu meer up-to-date, wat de enige echte functie van git rebase. Rebasen voegt geen branches samen, omdat het geen merge-commits maakt of de afspeelkop van de master verplaatst.

Als je wilt mergen na het rebasen, voer je het volgende uit:

git checkout master git merge functie Advertentie

Dat zou er als volgt uitzien, waarbij de hoofdafspeelkop de functie-afspeelkop vervangt:

Dus rebasen lost uiteindelijk het probleem van het omgaan met merges niet op, aangezien je toch aan het einde moet mergen om de master branch bij te werken. Het eigenlijke merge-commando aan het einde zou echter probleemloos moeten verlopen, aangezien het proces van rebasen vereist dat je “merge” in veranderingen, die toch voor conflicten kunnen zorgen. En als je nog steeds aan je branch wilt blijven werken, moet je nog steeds “merge” in wijzigingen.

Gedeelde vertakkingen niet opnieuw baseren

Weet je nog hoe rebasen van kopieën commits maakt en een gestrande afspeelkop achterlaat? Dat is eigenlijk een groot probleem als je met gedeelde code werkt. Laten we zeggen dat je de feature branch hebt gemaakt en deze naar je repo hebt gepusht zodat je collega's hem kunnen testen. Dat is helemaal prima, maar als een van hen van je branch wil vertakken, als je uiteindelijk rebaset, krijg je dit:

De feature2-tak van je collega verwijst nu naar een oude reeks commits. Je Git-client kan dit niet weten, aangezien de feature2-branch op de computer van je collega is opgeslagen. Ze kunnen ook niet weten of je opnieuw hebt gebasseerd totdat je je wijzigingen doorzet.

Toen je rebased, kopieerde het niet de feature2 branch toen het alle commits kopieerde. Zelfs als het zou kunnen, zou het de lokale Git-repo van je collega niet beïnvloeden, waardoor alles niet meer synchroon loopt. De oplossing hier zou zijn om feature2 te rebasen op feature op de plek waar het zou zijn, maar dat is rommelig, zelfs volgens Git-normen, en dit is slechts een heel eenvoudig voorbeeld.

Bottom line is, niet opnieuw baseren als u niet lokaal werkt.

Wanneer is rebasen beter dan samenvoegen?

Als uw branch enige tijd nodig heeft om zich te ontwikkelen, lost rebasen het probleem van "branch-syndroom" op," waar uw code veel te verouderd is met de werkende master en u deze moet bijwerken om te blijven werken. Over het algemeen gesproken, je moet proberen dit probleem zoveel mogelijk te vermijden, maar rebasen kan het oplossen wanneer het zich voordoet.

Advertentie

Als je alleen kleine, incrementele, dagelijkse wijzigingen aan het maken bent, zou je in plaats daarvan aan een lokale master-branch moeten werken en Pull Requests gebruiken als je klaar bent om je wijzigingen te pushen. Deze gebruiken het model van topicale branches, speciaal gemaakt om je code op te slaan voordat deze is goedgekeurd voor een samenvoeging.

Maar als je werkt aan een wekelijkse tijdspanne, en je gaat uiteindelijk meerdere pull-verzoeken maakt en meerdere keren samenvoegt, kunt u wat langer aan uw code werken, lokaal rebasen voor updates en aan het einde één pull-verzoek uitvoeren om de hoeveelheid testen en praten met supervisors te verminderen. Rebasen is in de eerste plaats een lokale aangelegenheid, dus je kunt het doen op je staging branches zonder te wachten op goedkeuring.

Als niemand anders afhankelijk is van je branch, kun je rebasen voordat een branch merged wordt om de commit geschiedenis schoon te maken en eendimensionaal. Hoewel je zou kunnen stellen dat traditioneel samenvoegen, hoewel zeker lelijker, gemakkelijker te volgen en te debuggen is, aangezien merge-commits volledig niet-destructief zijn. Hoe dan ook, de rebasing moet worden uitgevoerd vlak voordat uw wijzigingen worden samengevoegd, of u kunt het probleem tegenkomen dat de master wordt bijgewerkt voordat uw wijzigingen worden goedgekeurd.