Wanneer gebruik je Git rebase in plaats van Git merge?

Wanneer wordt aangeraden om Git rebase te gebruiken versus Git merge?

Moet ik nog steeds samenvoegen na een succesvolle rebase?


Antwoord 1, autoriteit 100%

Korte versie

  • Samenvoegen neemt alle wijzigingen in één branch en voegt ze samen in een andere branch in één commit.
  • Rebase zegt dat ik wil dat het punt waarop ik vertakt heb naar een nieuw startpunt gaat

Dus wanneer gebruik je een van beide?

Samenvoegen

  • Stel dat je een branch hebt gemaakt met als doel een enkele functie te ontwikkelen. Als je die wijzigingen weer onder de knie wilt krijgen, wil je waarschijnlijk samenvoegen(je geeft er niet om om alle tussentijdse commits te behouden).

Rebase

  • Een tweede scenario zou zijn als je wat aan ontwikkeling begon en een andere ontwikkelaar een niet-gerelateerde wijziging aanbracht. U wilt waarschijnlijk pullen en vervolgens rebaseom uw wijzigingen van de huidige versie uit de repository te baseren.

Antwoord 2, autoriteit 34%

Het is eenvoudig. Met rebase zeg je dat je een andere branch moet gebruiken als de nieuwe basevoor je werk.

Als je bijvoorbeeld een branch masterhebt, maak je een branch aan om een nieuwe functie te implementeren, en zeg je dat je die cool-featurenoemt, natuurlijk, de master branch is de basis voor je nieuwe feature.

Nu, op een bepaald moment, wil je de nieuwe functie toevoegen die je hebt geïmplementeerd in de masterbranch. Je kunt gewoon overschakelen naar masteren de branch cool-featuresamenvoegen:

$ git checkout master
$ git merge cool-feature

Maar op deze manier wordt er een nieuwe dummy-commit toegevoegd. Als je spaghettigeschiedenis wilt vermijden, kun je rebasen:

$ git checkout cool-feature
$ git rebase master

En voeg het dan samen in master:

$ git checkout master
$ git merge cool-feature

Deze keer, aangezien de topic branch dezelfde commits heeft van master plus de commits met de nieuwe functie, zal de merge alleen maar een fast-forward zijn.


Antwoord 3, autoriteit 25%

TL;DR

Als je twijfelt, gebruik dan samenvoegen.

Kort antwoord

De enige verschillen tussen een rebase en een merge zijn:

  • De resulterende boomstructuur van de geschiedenis (over het algemeen alleen merkbaar als je naar een commit-grafiek kijkt) is anders (de ene zal vertakkingen hebben, de andere niet).
  • Samenvoegen zal over het algemeen een extra commit creëren (bijv. knooppunt in de boom).
  • Samenvoegen en opnieuw baseren behandelen conflicten anders. Rebase zal conflicten één commit tegelijk presenteren, terwijl merge ze allemaal tegelijk zal presenteren.

Het korte antwoord is dus om rebase of merge te kiezen op basis van hoe u wilt dat uw geschiedenis eruitziet.

Lang antwoord

Er zijn een paar factoren waarmee u rekening moet houden bij het kiezen van de te gebruiken bewerking.

Wordt de branch waarvan je wijzigingen krijgt gedeeld met andere ontwikkelaars buiten je team (bijv. open source, openbaar)?

Zo ja, rebase niet. Rebase vernietigt de branch en die ontwikkelaars zullen kapotte/inconsistente repositories hebben, tenzij ze git pull --rebasegebruiken. Dit is een goede manier om andere ontwikkelaars snel van streek te maken.

Hoe bekwaam is uw ontwikkelteam?

Rebase is een destructieve bewerking. Dat betekent dat als u het niet correct toepast, u toegewijd werk kunt verliezen en/of de consistentie van de repositories van andere ontwikkelaars kunt verbreken.

Ik heb aan teams gewerkt waar de ontwikkelaars allemaal afkomstig waren van een tijd dat bedrijven het toegewijde personeel konden veroorloven om met vertakking en samenvoeging om te gaan. Die ontwikkelaars weten niet veel over git en willen niet veel weten. In deze teams zou ik niet riskeren dat het rebasing om welke reden dan ook aanbeveelt.

vertegenwoordigt de tak zelf nuttige informatie

Sommige teams gebruiken het filiaal-per-feature-model waarbij elke branch een functie (of bugfix of subfunctie, enz.) In dit model vertegenwoordigt, helpt de branch om sets van verwante commits te identificeren. Men kan bijvoorbeeld snel een functie terugkeren door de fusie van die tak terug te keren (om eerlijk te zijn, dit is een zeldzame bediening). Of diff een kenmerk door het vergelijken van twee takken (vaker). Rebase zou de tak vernietigen en dit zou niet rechtlijnig zijn.

Ik heb ook aan teams gewerkt die het filiaal-per-ontwikkelaarsmodel gebruikten (we zijn er allemaal geweest). In dit geval geeft de tak zelf geen aanvullende informatie over (de commit heeft al de auteur). Er zou geen kwaad in rebasing zijn.

Mogelijk wilt u de fuse om welke reden dan ook opnieuw wilt weergeven?

Terugkeer (zoals in het ongedaan maken) is een rebase aanzienlijk moeilijk en / of onmogelijk (als de rebase conflicten had) vergeleken met het terugkeren van een samenvoeging. Als u denkt dat er een kans is dat u wilt terugkeren en gebruik dan samenvoegen.

Werk je aan een team? Als dat zo is, bent u bereid om een ​​alles of niets nadert op deze tak?

Rebase-operaties moeten worden getrokken met een overeenkomstige git pull --rebase. Als u zelf werkt, kunt u misschien onthouden welke u op het juiste moment moet gebruiken. Als u aan een team werkt, is dit erg moeilijk om te coördineren. Dit is de reden waarom de meeste rebase-workflows raden aan het gebruik te gebruiken voor alle fucten (en git pull --rebasevoor alle trekkers).

Gemeenschappelijke mythen

Merge vernietigt geschiedenis (Squashes Commits)

Aangenomen dat u de volgende samenvoeging hebt:

   B -- C
   /      \
  A--------D

Sommige mensen zullen aangeven dat de samenvoeging “de begaangeschiedenis” vernietigt, want als u naar het logboek van alleen de Master Branch (A-D) zou kijken, zou u de belangrijke commit-berichten in B en C.

Als dit waar waren, zouden we Vragen zoals deze . In principe zul je b en c zien tenzij je expliciet vraagt ​​om ze niet te zien (met behulp van – eerste ouder). Dit is heel gemakkelijk om zelf te proberen.

REBASE maakt veiliger / eenvoudiger mogelijk gemaakt

De twee benaderingen samenvoegen anders, maar het is niet duidelijk dat men altijd beter is dan de andere en het kan afhangen van de werkstroom van de ontwikkelaar. Als een ontwikkelaar bijvoorbeeld regelmatig vastlegt (bijvoorbeeld, kunnen ze twee keer per dag begaan als ze overgaan van werk naar huis), dan kan er veel commits zijn voor een bepaalde tak. Veel van die committen kijken misschien niet zoiets als het eindproduct (ik heb de neiging om mijn aanpak één of twee keer per functie te refactoreren). Als iemand anders aan een gerelateerd gebied van de code werkte en ze probeerden mijn veranderingen opnieuw in te dienen, zou het een vrij vervelende operatie kunnen zijn.

Rebase is koeler / sexier / professioneler

Als u wilt alias rmNAAR rm -rfNAAR “SAVE TIME” DAN DAN MILIEU WERK IS VOOR JOU.

Mijn twee centen

Ik denk altijd dat ik op een dag een scenario tegenkom waar Git Rebase de geweldige tool is die het probleem oplost. Zoals ik denk dat ik een scenario tegenkom waar Git Reflock een geweldige tool is die mijn probleem oplost. Ik heb al meer dan vijf jaar met Git gewerkt. Het is niet gebeurd.

Rommelige geschiedenissen zijn nooit echt een probleem voor mij geweest. Ik lees mijn commit-geschiedenis niet zomaar als een spannende roman. Een meerderheid van de tijd dat ik een geschiedenis nodig heb, ga ik toch Git Blazen of Git bisect gebruiken. In dat geval is het hebben van de merge-commit eigenlijk nuttig voor mij, want als de merge het probleem heeft geïntroduceerd, is dat voor mij zinvolle informatie.

Update (4/2017)

Ik voel me verplicht om te vermelden dat ik persoonlijk minder gebruik heb gemaakt van rebase, hoewel mijn algemene advies nog steeds geldt. Ik heb de laatste tijd veel interactie met het Angular 2 Material-project. Ze hebben rebase gebruikt om een zeer schone commit-geschiedenis bij te houden. Hierdoor kon ik heel gemakkelijk zien welke commit een bepaald defect heeft verholpen en of die commit al dan niet in een release was opgenomen. Het is een goed voorbeeld van het correct gebruiken van rebase.


Antwoord 4, autoriteit 22%

Als aanvulling op mijn eigen antwoordvermeld door TSamper,

  • een rebase is vaak een goed idee om te doen voor een merge, omdat het de bedoeling is dat je in je branch Yhet werk van de branch Bwaarop je gaat fuseren.
    Maar nogmaals, voordat je gaat mergen, los je elk conflict op in jebranch (dwz: “rebase”, zoals in “speel mijn werk opnieuw af in mijn branch vanaf een recent punt van de branch B).
    Als het correct wordt gedaan, kan de daaropvolgende samenvoeging van je branch naar branch Bfast-forward zijn.

  • een samenvoeging heeft direct invloed op de bestemmingstak B, wat betekent dat de samenvoegingen beter triviaal zijn, anders kan het lang duren voordat die tak Bterug is naar een stabiele staat (tijd om alle conflicten op te lossen)


het punt van samenvoegen na een rebase?

In het geval dat ik beschrijf, rebase ik Bnaar mijn branch, alleen om de mogelijkheid te hebben om mijn werk opnieuw af te spelen vanaf een recenter punt van B, maar terwijl in mijn filiaal blijven.
In dit geval is nog steeds een samenvoeging nodig om mijn “opnieuw afgespeelde” werk naar Bte brengen.

Het andere scenario (beschreven in Git Readybijvoorbeeld), is om je werk rechtstreeks in Bte brengen via een rebase (waardoor al je mooie commits behouden blijven, of je zelfs de mogelijkheid geeft om ze opnieuw te ordenen via een interactieve rebase).
In dat geval (waar je rebaset terwijl je in de B branch bent), heb je gelijk: er is geen verdere merge nodig:

Standaard een Git-tree wanneer we niet hebben samengevoegd of gerebaseerd

we krijgen door te rebasen:

Dat tweede scenario gaat over: hoe krijg ik nieuwe functies terug in master.

Mijn punt, door het eerste rebase-scenario te beschrijven, is om iedereen eraan te herinneren dat een rebase ook kan worden gebruikt als een voorbereidende stap daarvoor (dat is “nieuwe functie terug in master krijgen”).
Je kunt rebase gebruiken om eerst master “in” de new-feature branch te brengen: de rebase zal nieuwe-feature commits van de HEAD masteropnieuw afspelen, maar nog steeds in de new-feature branch, waardoor je branch effectief wordt verplaatst startpunt van een oude master commit naar HEAD-master.
Dat stelt je in staat om eventuele conflicten in jebranch op te lossen (dat wil zeggen, in isolatie, terwijl master tegelijkertijd kan blijven evolueren als je conflictoplossingsfase te lang duurt).
Dan kun je overschakelen naar master en new-featuresamenvoegen (of new-featurerebasen op masterals je commits wilt behouden die zijn gedaan in je new-featurebranch).

Dus:

  • “rebase vs. merge” kan worden gezien als twee manieren om een werk te importeren op bijvoorbeeld master.
  • Maar “rebase then merge” kan een geldige workflow zijn om conflicten eerst afzonderlijk op te lossen en vervolgens uw werk terug te brengen.

Antwoord 5, autoriteit 16%

Veel antwoorden hier zeggen dat samenvoegen al je commits in één verandert, en stellen daarom voor om rebase te gebruiken om je commits te behouden. Dit is onjuist. En een slecht idee als je je commits al hebt gepusht.

Samenvoegen nietvernietigt je commits. Samenvoegen bewaart geschiedenis! (kijk maar naar gitk) Rebase herschrijft de geschiedenis, wat een slechte zaak is nadat je erop hebt geduwd.

Gebruik samenvoegen — niet opnieuw baserenwanneer je al hebt gepusht.

Hier is Linus’ (auteur van Git) het overnemen(nu gehost op mijn eigen blog, als hersteld door de Wayback Machine). Het is echt goed te lezen.

Of je kunt mijn eigen versie van hetzelfde idee hieronder lezen.

Rebasen van een branch op master:

  • geeft een onjuist idee van hoe commits zijn gemaakt
  • vervuilt de master met een heleboel tussentijdse commits die misschien niet goed zijn getest
  • zou eigenlijk build-breaks kunnen introduceren op deze tussenliggende commits vanwege wijzigingen die zijn aangebracht om te masteren tussen het moment waarop de oorspronkelijke onderwerpbranch werd gemaakt en het moment waarop deze opnieuw werd gebaseerd.
  • maakt het moeilijk om goede plaatsen in de master te vinden om af te rekenen.
  • Zorgt ervoor dat de tijdstempels op commits niet overeenkomen met hun chronologische volgorde in de boom. Dus je zou zien dat commit A voorafgaat aan commit B in master, maar commit B is eerst geschreven. (Wat?!)
  • Produceert meer conflicten, omdat individuele commits in de topic branch elk merge conflicten met zich mee kunnen brengen die individueel moeten worden opgelost (verder liegend in de geschiedenis over wat er in elke commit is gebeurd).
  • is een herschrijving van de geschiedenis. Als de branch die wordt gerebaseerd ergens is gepusht (gedeeld met iemand anders dan jezelf), dan heb je iedereen die die branch heeft verknald sinds je de geschiedenis hebt herschreven.

In tegenstelling, een onderwerpbranch samenvoegen met master:

  • bewaart de geschiedenis van waar onderwerpvertakkingen zijn gemaakt, inclusief eventuele samenvoegingen van de hoofdvertakking naar de onderwerpvertakking om het actueel te houden. Je krijgt echt een nauwkeurig idee van met welke code de ontwikkelaar werkte toen ze aan het bouwen waren.
  • master is een branch die voornamelijk uit merges bestaat, en elk van die merge commits zijn typisch ‘goede punten’ in de geschiedenis die veilig zijn om uit te checken, omdat daar de topic branch klaar was om te worden geïntegreerd.
  • alle individuele commits van de topic branch blijven behouden, inclusief het feit dat ze zich in een topic branch bevonden, dus het isoleren van die veranderingen is natuurlijk en je kunt inzoomen waar nodig.
  • merge-conflicten hoeven maar één keer te worden opgelost (op het moment van de merge), dus tussentijdse commit-wijzigingen die in de topic-branch zijn gemaakt, hoeven niet onafhankelijk te worden opgelost.
  • kan meerdere keren soepel worden gedaan. Als je je topic branch periodiek integreert om te masteren, kunnen mensen blijven bouwen aan de topic branch, en het kan onafhankelijk blijven worden samengevoegd.

Antwoord 6, autoriteit 7%

TLDR: Het hangt af van wat het belangrijkste is: een opgeruimde geschiedenis of een waarheidsgetrouwe weergave van de volgorde van ontwikkeling

Als een opgeruimde geschiedenis het belangrijkste is, dan zou je eerst rebasen en dan je wijzigingen samenvoegen, zodat het precies duidelijk is wat de nieuwe code is. Als je je branch al hebt gepusht, rebase dan niet, tenzij je de gevolgen kunt opvangen.

Als de juiste weergave van de reeks het belangrijkste is, zou je samenvoegen zonder rebasen.

Samenvoegen betekent: Maak een enkele nieuwe commit die mijn wijzigingen samenvoegt met de bestemming. Opmerking:Deze nieuwe commit zal twee ouders hebben – de laatste commit van je reeks commits en de laatste commit van de andere branch die je aan het mergen bent.

Rebase betekent: Maak een hele nieuwe reeks commits, gebruik mijn huidige set commits als hints. Met andere woorden, bereken hoe mijn wijzigingen eruit zouden hebben gezien als ik ze had gemaakt vanaf het punt waarop ik rebas. Na de rebase moet u uw wijzigingen daarom mogelijk opnieuw testen en tijdens de rebase kunt u mogelijk een paar conflicten krijgen.

Waarom zou je dan opnieuw beren? Gewoon om de ontwikkelingsgeschiedenis helder te houden. Laten we zeggen dat je werkt aan functie x en wanneer je klaar bent, voeg je je veranderingen samen. De bestemming heeft nu een enkele commit die iets zou zeggen in de trant van “Toegevoegd functie X”. Nu, in plaats van samen te voegen, als u opnieuw is samengevoegd en vervolgens samengevoegd, zou de geschiedenis van de ontwikkelingsontwikkeling alle individuele commits bevatten in een enkele logische progressie. Dit maakt het beoordelen van wijzigingen later op veel eenvoudiger. Stel je voor hoe hard je het zou vinden om de ontwikkelingsgeschiedenis te bekijken als 50 ontwikkelaars de hele tijd verschillende functies samenvoegen.

Dat gezegd hebbende, als je al de tak hebt geduwd, werk je aan stroomopwaarts, moet je niet opnieuw baren, maar in plaats daarvan samenvoegen. Voor filialen die niet stroomopwaarts zijn geduwd, opnieuw inbrengen, testen en samenvoegen.

Een andere keer dat u misschien wilt weerhouden, is wanneer u zich wilt ontdoen van commits uit uw vestiging voordat u stroomopwaarts duwt. Bijvoorbeeld: commits die een aantal foutopsporingscode vroeg en andere introduceert die verder begaat op die reinig die code. De enige manier om dit te doen is door een interactieve rebase uit te voeren: git rebase -i <branch/commit/tag>

UPDATE: U wilt ook REBASE gebruiken wanneer u GIT gebruikt om te interface naar een versiesysteem met versies dat niet-lineaire geschiedenis niet ondersteunt (Subversion bijvoorbeeld). Wanneer het gebruik van de GIT-SVN-brug, is het erg belangrijk dat de wijzigingen die u weer in de subversie samenvoegt, een sequentiële lijst van wijzigingen bovenop de meest recente wijzigingen in de kofferbak. Er zijn slechts twee manieren om dat te doen: (1) Handmatig opnieuw maken van de wijzigingen en (2) met behulp van de opdracht Rebase, die een stuk sneller is.

UPDATE 2: Een andere manier om aan een rebase te denken, is dat het een soort mapping mogelijk maakt van je ontwikkelstijl naar de stijl die is geaccepteerd in de repository waar je je aan vasthoudt. Laten we zeggen dat je het leuk vindt om je in kleine, kleine stukjes te binden. Je hebt één commit om een typefout te herstellen, één commit om ongebruikte code te verwijderen enzovoort. Tegen de tijd dat je klaar bent met wat je moet doen, heb je een lange reeks commits. Laten we nu zeggen dat de repository waar je je aan vastlegt grote commits aanmoedigt, dus voor het werk dat je doet, zou je een of misschien twee commits verwachten. Hoe pak je je reeks commits en comprimeer je ze tot wat er wordt verwacht? Je zou een interactieve rebase gebruiken en je kleine commits in minder grotere brokken pletten. Hetzelfde geldt als het omgekeerde nodig was – als je stijl een paar grote commits was, maar de repository lange reeksen kleine commits eiste. Je zou ook een rebase gebruiken om dat te doen. Als je in plaats daarvan had samengevoegd, heb je nu je commit-stijl op de hoofdrepository geënt. Als er veel ontwikkelaars zijn, kun je je voorstellen hoe moeilijk het zou zijn om na verloop van tijd een geschiedenis met verschillende commit-stijlen te volgen.

UPDATE 3: Does one still need to merge after a successful rebase?Ja, dat doe je. De reden is dat een rebase in wezen een “verschuiving” van commits inhoudt. Zoals ik hierboven heb gezegd, worden deze commits berekend, maar als je 14 commits had vanaf het punt van vertakking, en aangenomen dat er niets mis gaat met je rebase, dan ben je 14 commits voor (van het punt waarop je rebast) na de rebase is gedaan. Je had een filiaal voor een rebase. Je hebt daarna een tak van dezelfde lengte. U moet nog steeds samenvoegen voordat u uw wijzigingen publiceert. Met andere woorden, rebase zo vaak als u wilt (opnieuw, alleen als u uw wijzigingen niet stroomopwaarts hebt gepusht). Pas samenvoegen nadat u opnieuw hebt gebasseerd.


Antwoord 7, autoriteit 6%

Hoewel samenvoegen absoluut de gemakkelijkste en meest gebruikelijke manier is om wijzigingen te integreren, is het niet de enige: Rebaseis een alternatieve manier van integratie.

Samenvoegen een beetje beter begrijpen

Als Git een merge uitvoert, zoekt het naar drie commits:

  • (1) Gemeenschappelijke voorouder commit. Als je de geschiedenis van twee branches in een project volgt, hebben ze altijd minstens één commit gemeen: op dit moment hadden beide branches dezelfde inhoud en evolueerden ze anders.
  • (2) + (3) Eindpunten van elke tak. Het doel van een integratie is om de huidige toestanden van twee takken te combineren. Daarom zijn hun respectieve laatste herzieningen van bijzonder belang.
    Het combineren van deze drie commits zal resulteren in de integratie waar we naar streven.

Snel vooruitspoelen of samenvoegen toezegging

In zeer eenvoudige gevallen heeft een van de twee branches geen nieuwe commits sinds de branching heeft plaatsgevonden – de laatste commit is nog steeds de gemeenschappelijke voorouder.

In dit geval is het uitvoeren van de integratie doodeenvoudig: Git kan gewoon alle commits van de andere branch toevoegen aan de gemeenschappelijke voorouder-commit. In Git wordt deze eenvoudigste vorm van integratie een “fast-forward” merge genoemd. Beide vestigingen delen dan exact dezelfde geschiedenis.

In veel gevallen gingen beide takken echter afzonderlijk vooruit.

Om een integratie te maken, zal Git een nieuwe commit moeten maken die de verschillen tussen beide bevat – de merge commit.

Menselijke verplichtingen & Toezeggingen samenvoegen

Normaal gesproken wordt een commit zorgvuldig gemaakt door een mens. Het is een zinvolle eenheid die alleen gerelateerde wijzigingen omhult en van aantekeningen voorziet met een opmerking.

Een merge-commit is een beetje anders: in plaats van te worden gemaakt door een ontwikkelaar, wordt het automatisch gemaakt door Git. En in plaats van een reeks gerelateerde veranderingen in te pakken, is het de bedoeling om twee takken met elkaar te verbinden, net als een knoop. Als je een merge-operatie later wilt begrijpen, moet je de geschiedenis van beide branches en de bijbehorende commit-grafiek bekijken.

Integreren met Rebase

Sommige mensen geven de voorkeur aan zulke automatische merge commits. In plaats daarvan willen ze dat de geschiedenis van het project eruitziet alsof het in één rechte lijn is geëvolueerd.Er is geen aanwijzing dat het ooit in meerdere takken is opgesplitst.

Laten we stap voor stap een rebase-bewerking doornemen. Het scenario is hetzelfde als in de vorige voorbeelden: we willen de wijzigingen van branch-B in branch-A integreren, maar nu door rebase te gebruiken.

We doen dit in drie stappen

  1. git rebase branch-A // Synchronises the history with branch-A
  2. git checkout branch-A // Change the current branch to branch-A
  3. git merge branch-B // Merge/take the changes from branch-B to branch-A

Ten eerste, Git zal “ongedaan maken” alle commits op tak – A die is gebeurd nadat de lijnen begonnen te takken (na de gemeenschappelijke voorouder commit). Natuurlijk zal het ze echter niet weggooien: in plaats daarvan kun je bedenken aan die commits als ‘tijdelijk opgeslagen’.

Vervolgens past het de commits van Branch-B toe die we willen integreren. Op dit punt zien beide filialen er precies hetzelfde uit.

In de laatste stap worden de nieuwe commits op tak-A nu opnieuw toegewezen – maar op een nieuwe positie, bovenop de geïntegreerde commits van Branch-B (ze zijn opnieuw gevestigd).

Het resultaat lijkt erop dat de ontwikkeling in een rechte lijn was gebeurd. In plaats van een samenvoegende commit die alle gecombineerde veranderingen bevat, werd de oorspronkelijke Plaatsstructuur bewaard gebleven.

Ten slotte krijgt u een schone tak filiaal-a zonder ongewenste en automatische gegenereerde commits.

Opmerking: genomen van de geweldige Post by git-tower. De nadelen van van rebaseis ook een goede lees in dezelfde post.


8, Autoriteit 5%

Vóór het samenvoegen / Rebase:

A <- B <- C    [master]
^
 \
  D <- E       [branch]

Na git merge master:

A <- B <- C
^         ^
 \         \
  D <- E <- F

Na git rebase master:

A <- B <- C <- D' <- E'

(A, B, C, D, E en F zijn commits)

Dit voorbeeld en veel meer goed geïllustreerde informatie over Git is te vinden in Git The Basics Tutorial.


Antwoord 9, autoriteit 3%

Deze zin snapt het:

Over het algemeen kun je het beste van twee werelden krijgen door lokaal te rebasen
wijzigingen die je hebt aangebracht, maar nog niet hebt gedeeld, voordat je ze invoert
om je verhaal op te schonen, maar rebas nooit iets dat je hebt gepusht
ergens.

Bron: 3.6 Git Branching – Rebasen, Rebase vs. Samenvoegen


Antwoord 10

De pro git boek heeft een heel goed Uitleg over de rebasing pagina .

In feite neemt een samenvoeging twee commits en combineert ze.

Een rebase gaat naar de gemeenschappelijke voorouder op de twee en brengt de wijzigingen op elkaar voort. Dit zorgt voor een ‘schoner’ en meer lineaire geschiedenis.

Maar wanneer u terugbrengt, verlaat u de vorige commits en maak u nieuwe. Dus je moet nooit een repository opnieuw inbrengen die openbaar is. De andere mensen die aan de repository werken, zullen je haten.

Alleen al die reden alleen fuseer ik bijna uitsluitend. 99% van de tijd dat mijn takken niet zoveel verschillen, dus als er conflicten zijn, is het alleen op een of twee plaatsen.


11

  • Gebruik in het algemeen samenvoegen
  • Als u slechts één ontwikkelaar bent, kunt u Rebase gebruiken om een ​​duidelijke geschiedenis te hebben.
  • in gedeelde projecten Niet Gebruik Rebase omdat cachesamenstellingen worden gewijzigd


12

Git Rebase wordt gebruikt om de vertakkingspaden in de geschiedenisreiniger en de repositorystructuur lineair te maken.

Het wordt ook gebruikt om de takken die door u zijn gecreëerd, zoals na het rebaseren en duwen van de wijzigingen in de server, als u uw filiaal verwijdert, is er geen bewijs van filiaal waar u aan hebt gewerkt. Dus uw tak is nu uw lokale zorg.

Nadat we een terugvraag hebben gedaan, worden we ook een extra commit af die we gebruikten als we een normale samenvoeging doen.

En ja, je moet nog steeds mergen na een succesvolle rebase, aangezien het rebase-commando je werk gewoon bovenop de branch plaatst die je noemde tijdens rebase, zeg master, en de eerste commit van je branch maakt als een directe afstammeling van de mastertak. Dit betekent dat we nu een fast forward merge kunnen doen om veranderingen van deze branch naar de master branch te brengen.


Antwoord 13

Enkele praktische voorbeelden, enigszins verbonden met grootschalige ontwikkeling waarbij Gerritwordt gebruikt voor beoordeling en leveringsintegratie:

Ik merge wanneer ik mijn feature branch verhef naar een nieuwe remote master. Dit geeft minimaal opbeurend werk en het is gemakkelijk om de geschiedenis van de ontwikkeling van functies te volgen in bijvoorbeeld gitk.

git fetch
git checkout origin/my_feature
git merge origin/master
git commit
git push origin HEAD:refs/for/my_feature

Ik voeg samen wanneer ik een leveringsverplichting voorbereid.

git fetch
git checkout origin/master
git merge --squash origin/my_feature
git commit
git push origin HEAD:refs/for/master

Ik rebase wanneer mijn leveringscommit om welke reden dan ook niet kan worden geïntegreerd, en ik moet het bijwerken naar een nieuwe externe master.

git fetch
git fetch <gerrit link>
git checkout FETCH_HEAD
git rebase origin/master
git push origin HEAD:refs/for/master

Antwoord 14

Er is vaak uitgelegd wat rebase en wat merge is, maar wanneer moet je wat gebruiken?

Wanneer moet je rebase gebruiken?

Rebase “tilt” uw wijzigingen op en plaatst alle wijzigingen van de gerebased vertakking in uw huidige vertakking en plaatst uw wijzigingen daarbovenop. Het verandert dus de geschiedenis van uw filiaal.

  • wanneer je de branch niet hebt gepusht / niemand anders eraan werkt
  • je wilt dat je al je wijzigingen op één punt samen ziet wanneer je terug samenvoegt naar de bronvertakking
  • je wilt de automatisch gegenereerde “merged ..” commit-berichten vermijden

Ik zei “je wilt al je wijzigingen op één plek zien” omdat soms een merge-operatie al je wijzigingen samenbrengt in één commit (sommige: merged from … message). Rebase zorgt ervoor dat je wijziging eruitziet alsof je je commits achter elkaar hebt gedaan zonder dat iemand anders iets ertussen doet. Dit maakt het gemakkelijker om te zien wat u voor uw functie heeft gewijzigd.

Zorg er echter voor dat je git merge feature-branch –ff-only gebruikt om er zeker van te zijn dat er geen conflicten zijn bij het maken van een enkele commit wanneer je je feature weer samenvoegt om te ontwikkelen/masteren.

Wanneer moet je samenvoegen gebruiken?

  • wanneer je de branch gepusht hebt / werken anderen er ook aan (rebase wordt erg ingewikkeld als anderen ook aan die branch werken!)
  • je hebt niet de volledige geschiedenis(*) nodig / je feature hoeft zijn commits niet allemaal op één plek te hebben.

(*) je kunt voorkomen dat je feature maar één “merged ..” commit krijgt door eerst de ontwikkel-branch samen te voegen met je feature en dan je feature weer samen te voegen met develope. Dit geeft je nog steeds een “merged ..” commit, maar in ieder geval zijn alle commits van je feature nog steeds zichtbaar.


Antwoord 15

Wanneer gebruik ik git rebase? Bijna nooit, omdat het de geschiedenis herschrijft. git mergeheeft bijna altijd de voorkeur, omdat het respecteert wat er feitelijk in je project is gebeurd.

Other episodes