“rebase alsjeblieft bovenop master en we mergen je pull request”.
” kun je alsjeblieft je commits samen squashen zodat we een schone, omkeerbare githistory krijgen?”.
” kun je het bericht van je commit herschrijven om het probleem beter te beschrijven dat het oplost, en hoe het het oplost?”.
vragen zoals deze worden vaak gesteld in pull requests. Laten we eens kijken waarom ze bestaan, hoe ze uit te voeren, en hun mogelijke problemen.,
Herword Het Laatste commit bericht
een van de eenvoudigste geschiedenisherschrijvingen die we kunnen doen met git is het veranderen van het laatste Commit bericht. Stel dat je direct na het maken van een commit een typefout in de beschrijving vindt, of je vindt een betere manier om de wijzigingenset te beschrijven. Om de correction te maken, gebruik je:
git commit --amend
Het zal een editor openen met het laatste commit bericht, zodat je het kunt wijzigen. Na het opslaan wordt een nieuwe commit aangemaakt met dezelfde wijzigingen en het nieuwe bericht, waarbij de commit wordt vervangen door het vorige bericht.,
dit kan handig zijn om bestanden op te nemen die u vergeten bent te volgen, of om wijzigingen in te voegen aan de bestanden die u zojuist hebt commited. Om dit te doen, kunt u de wijzigingen toevoegen en vervolgens de wijziging uitvoeren:
git add README.md config/routes.rb git rm notes.txt git commit --amend
naast het bewerken van het commit-bericht, zal de nieuwe commit de wijzigingen bevatten die gespecificeerd zijn met git add
en git rm
. U kunt ook de auteur bewerken. Voorbeeld:
git commit --amend --author="Tute Costa and Dan Croak <[email protected]>"
prestatie ontgrendeld!, Je kunt nu de laatste commit van je repository wijzigen om nieuwere wijzigingen in de bestanden op te nemen, en/of om het Commit bericht te verbeteren. Maar begin niet met het wijzigen van alle-de-dingen voordat het begrijpen van de laatste sectie van deze blog post getiteld “gevaar”.
andere commit-berichten herformuleren
zou hier nu graag over willen spreken, maar we moeten eerder een algemenere tool begrijpen. Blijf kijken! Al het andere zal makkelijker zijn als we lezen over…
interactieve Rebase
git rebase
past commits opnieuw toe, één byone, in volgorde, van je huidige branch op een andere., Het accepteert verschillende opties en parameters, dus dat is een topje van de ijsberg uitleg, genoeg om de kloof te overbruggen tussen StackOverflow of GitHub opmerkingen en de git man pagina ‘ s.
een interessante optie die het accepteert is --interactive
(-i
kortweg), die een editor wil openen met een lijst van de commits die op het punt staan te worden gewijzigd. Thislist accepteert commando ‘ s, waardoor de gebruiker de lijst kan bewerken voordat de basis actie wordt gestart.
laat een voorbeeld zien.,
andere commit berichten, neem 2
laten we zeggen dat ik een van de laatste 4 commits van deze blog wil herformuleren. Ik voer dangit rebase -i HEAD~4
, en dit is wat ik zie:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend # Rebase 8db7e8b..fa20af3 onto 8db7e8b # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out
we zien de vier laatste commits, van ouder naar nieuwer. Zie het commentaar hieronder de lijst met commits? Goed uitgelegd, git! pick
(p
kortweg) is de standaardactie. In dit geval zou het de commit opnieuw toepassen zoals deze is, geen wijzigingen in de inhoud of het bericht. Het opslaan (en uitvoeren) van dit bestand zou geen wijzigingen aan de repository maken.,
Als ik zeg reword
(r
voor kort) in een vastlegging ik wil bewerken:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls r 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Wanneer ik opslaan en sluit de editor, dan zal git volg de beschreven opdrachten, landingmyself in de editor opnieuw als ik had gewijzigd commit 3e7ee36
. Ik Bewerk datcommit-bericht, Sla de editor op en sluit deze af, en hier is de uitvoer:
nu zegt Caleb in zijn commit-bericht “Stop alle accentuering”, of je nu een kind bent of niet.
prestatie ontgrendeld! U kunt nu de boodschap van anycommit die u wilt wijzigen., U kunt dit doen, maar zorg ervoor dat u begrijpt de “gevaar” sectie.
Squash pleegt samen
Twee andere commando ‘ s interactieve rebase ons biedt, zijn:
-
squash
(s
kort), die groepjes de vastlegging in de vorige (theone in de lijn voor) -
fixup
(f
voor de korte), die fungeert als “squash”, maar verwijdert deze commit’smessage
We zullen blijven werken aan de rebase voorbeeld we workedbefore., We hadden vier pleegt, mijn eigen voor deze blog post, endrie anderen van Kaleb, die gerelateerd waren aan zijn vorige post op PGP:
pick 07c5abd Introduce OpenPGP and teach basic usage pick de9b1eb Fix PostChecker::Post#urls pick 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
Laten we zeggen dat ik wil groepje Kaleb pleegt samen, omdat ze behoren tot hetzelfde logische changeset, en zo kunnen we git revert
gemakkelijk als we vinden weprefer niet om deze wijzigingen in deze repository. We willen het eerste commit bericht behouden, en de twee volgende commits squashen naar de vorige., Ik verander pick
naar squash
waar van toepassing:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls s 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
opslaan, en ik land in de editor om het commit bericht van de meldedthree commits te bepalen (zie hoe ze na elkaar worden samengevoegd):
# This is a combination of 3 commits. # The first commit's message is: Introduce OpenPGP and teach basic usage Besides demystifying a relatively complex tool, protocol, and etiquette, this post is intended to help with problems such as the one outlined in this tweet: > Emailed sensitive info to someone with PGP. They replied, with my > original email, all in clear text. They didn't realize it. # This is the 2nd commit message: Fix PostChecker::Post#urls # This is the 3rd commit message: Hey kids, stop all the highlighting # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Author: Caleb Hearth # Date: Tue Sep 2 09:39:07 2014 -0500 # # rebase in progress; onto 71d4789 # You are currently editing a commit while rebasing branch 'tc-git-rebase' on '71d4789'.
Ik besluit het derde Commit-bericht te verwijderen en een meer relevante notitie toe te voegen aan het tweede Commit-bericht. Red de editor, en de vier commits werden getransformeerd in twee: de ene van Caleb, en de mijne erna. Goed!,
we hadden het fixup
Commando kunnen gebruiken, als we eerder hadden gezien dat we de wijzigingen willen, maar niet het commit bericht, van de derde commit. In dat geval zouden de commands eruit hebben gezien als:
pick 07c5abd Introduce OpenPGP and teach basic usage s de9b1eb Fix PostChecker::Post#urls f 3e7ee36 Hey kids, stop all the highlighting pick fa20af3 git interactive rebase, squash, amend
wanneer opgeslagen, zou de editor het derde commit bericht hebben opgenomen dat al voor ons is becommentarieerd:
Save, en outputs:
resultaat is hetzelfde: 2 commits in plaats van 4, elk met een enkele, verschillende blogpost.
prestatie ontgrendeld! Je kunt nu commits samenvoegen. Denk altijd aan de gevarenzone.,
Rebase bovenop master
we forken een open source bibliotheek, beginnen te werken aan een feature branch, en master in het upstream project gaat verder. Onze geschiedenis ziet er als volgt uit:
A---B---C feature / D---E---F---G upstream/master
De bibliotheekbeheerder vraagt om “rebase on top of master”, dus we repareren alle mergeconflicten die kunnen ontstaan tussen beide branches, en houden onze wijzigingenset bij elkaar.De beheerder wil graag een geschiedenis zien als:
A'--B'--C' feature / D---E---F---G upstream/master
We willen onze commits één voor één opnieuw toepassen op de master van upstream.,Klinkt als de beschrijving van het rebase Commando! Laten we eens kijken welke commando ‘ s ons in het gewenste scenario zouden plaatsen:
# Point our `upstream` remote to the original fork git remote add upstream https://github.com/thoughtbot/factory_girl.git # Fetch latest commits from `upstream` (the original fork) git fetch upstream # Checkout our feature branch git checkout feature # Reapply it onto upstream's master git rebase upstream/master # Fix conflicts, then `git rebase --continue`, repeat until done # Push to our fork git push --force origin feature
prestatie ontgrendeld! Je feature branch wordt toegepast bovenop de laatste master van de originele fork.
en zo komen we bij…
gevaar: u herschrijft geschiedenis
zie het --force
in het laatste git push
Commando? Dat betekent dat we de geschiedenis van repository overschrijven., Dit is altijd veilig om te doen in commits die we niet delen met andere teamleden, of in branches die van ons zijn (zie mijn initialen in het voorbeeld van deze blogpost).
maar als je push-edities forceert die al met het team zijn gedeeld (commits die buiten mijn repository bestaan, zoals de wijzigingen die ik heb aangebracht in de PGP-commits die al zijn gedeeld), dan raakt de branch van iedereen niet gesynchroniseerd.
het herschrijven van de geschiedenis betekent bestaande commits verlaten en nieuwe maken, die erg op elkaar lijken, maar anders zijn., Als anderen het werk baseren op je eerdere commits, en dan herschrijf je en forceer je je commits, dan zullen je teamleden hun werk opnieuw moeten mergen (als ze het potentiële verlies opmerken).
bij thoughtbot voegen we onze branches voor met onze initialen, wat aangeeft dat diecommits herschreven kunnen worden en dat anderen geen commits aan de branch moeten toevoegen. Wanneer deze commits land in master of een gedeelde branch zullen we ze nooit meer herschrijven.
herschrijf dus de git geschiedenis, op voorwaarde dat herschreven commits alleen in je repository bestaan, of jij en je team weten dat niemand anders er werk van zou moeten baseren.,
prestatie ontgrendeld! Je weet nu hoe je moet rebasen terwijl je een goede burger bent.