Een tijdreizigersgids voor Git

Schrijver: Randy Alexander
Datum Van Creatie: 28 April 2021
Updatedatum: 15 Kunnen 2024
Anonim
RPC-916 het handboek voor tijdreizigers | beta-geel | chronologische rpc
Video: RPC-916 het handboek voor tijdreizigers | beta-geel | chronologische rpc

Inhoud

Terwijl wetenschappers de droom om terug in de tijd te reizen hebben verpletterd, biedt Git controle over de vierde dimensie wanneer de fouten uit het verleden moeten worden gecorrigeerd. Met het gedistribueerde versiebeheersysteem kunnen commits worden gewijzigd, verwijderd, opnieuw geordend en aangepast om de geschiedenis van een repository te scrubben.

Maar let op de waarschuwingen van een ervaren tijdreiziger. Git gehoorzaamt de wet van causaliteit; elke commit in een Git-repository is onlosmakelijk verbonden met de commit ervoor. Het veranderen van een commit verandert alle commits die erna komen, waardoor een alternatieve realiteit ontstaat. Het verleden veranderen kan gevaarlijk zijn en mag - behalve in zeldzame omstandigheden - alleen worden gedaan als de gebeurtenissen die worden gewijzigd niet door iemand anders zijn waargenomen. Takken die al naar een afstandsbediening zijn gepusht, mogen niet worden gewijzigd.

Ga met me mee terwijl we manieren onderzoeken om de geschiedenis met Git te herschrijven.

01. Pas recente geschiedenis aan

Om welke reden dan ook, het menselijk brein lijkt zo bedraad te zijn om iets belangrijks te onthouden net nadat je op de knop ‘Verzenden’ in een e-mail hebt gedrukt, en de juiste woorden komen altijd in je op nadat een gesprek is afgelopen. Evenzo realiseer ik me vaak dat ik een fout heb gemaakt onmiddellijk na het maken van een commit in Git. De veiligste en meest gebruikelijke vorm van het herschrijven van de Git-geschiedenis is om de laatste commit te wijzigen.


Dit artikel is geschreven in een Git-opslagplaats. De eerste commit was om een ​​README te maken waarin het doel van de repository werd uitgelegd.

$ git add.
$ git commit -am ’README toevoegen’
[master (root-commit) 6261ead] README toevoegen
2 bestanden gewijzigd, 12 invoegingen (+)
maak modus 100644 README.md
aanmaken mode 100644 article.md

Oeps, na het begaan, realiseerde ik me dat ik had gepleegd artikel.md, dat waren slechts enkele opmerkingen en de eerste paar zinnen van de inleiding. Ik was nog niet van plan om dat bestand vast te leggen, dus laten we het uit de geschiedenis verwijderen.

$ git rm - gecached article.md
rm ’article.md’

De - in de cache argument voor git rm vertelt Git om het verwijderen van het bestand te stagen, maar het bestand niet echt van het bestandssysteem te verwijderen. Als u het bestand ook wilt verwijderen, laat dat argument dan gewoon weg.

We kunnen ook andere wijzigingen aanbrengen zoals we zouden doen als we een andere commit zouden maken, zoals het maken van bewerkingen in het README.md en enscenering met git add. Wijzig de vorige commit door de --wijzigen vlag naar git commit:


$ git commit --amend
[master 667f8c9] README toevoegen
1 bestand gewijzigd, 7 invoegingen (+)
maak modus 100644 README.md

Git zal een editor openen om het vorige vastleggingsbericht te kunnen bewerken. Het Git-logboek laat nu zien dat er nog maar één commit is, en die commit heeft er maar één README.md.

$ git log --oneline --stat
667f8c9 README toevoegen
README.md | 7 +++++++
1 bestand gewijzigd, 7 invoegingen (+)

Laten we dit artikel vastleggen nu er vooruitgang is geboekt.

$ git add article.md $ git commit -m ’eerste concept van wijzigingssectie’ [master 8dbf5d5] eerste concept van wijzigingssectie 1 bestand gewijzigd, 47 invoegingen (+) aanmaakmodus 100644 article.md

02. Maak recente geschiedenis ongedaan

Soms bevat een commit zoveel fouten dat het gemakkelijker is om het gewoon ongedaan te maken. Misschien is het vastgelegd in de verkeerde branch, of is er per ongeluk een map met ongewenste bestanden toegevoegd.

$ git reset HEAD ^

Dit vertelt Git om te verwijderen naar de vorige commit, maar om de veranderingen die door die commit zijn geïntroduceerd lokaal te houden. git reset is krachtig en kan bij onjuist gebruik destructief zijn. Het is de moeite waard om er meer over te lezen op git-scm.com.


Het logboek laat nu zien dat de laatste commit weg is, maar artikel.md is nog steeds gewijzigd.

$ git log --oneline
667f8c9 README toevoegen

$ git status -s
M artikel.md

Vanaf hier kunnen de wijzigingen worden vastgelegd op een andere tak, opgeslagen, weggegooid of gewijzigd en opnieuw worden toegevoegd.

03. Zorg voor een opgeruimde geschiedenis

Als je Git met een team hebt gebruikt, lijdt het geen twijfel dat je een push hebt afgewezen.

$ git push oorsprong master
Aan [email protected]: bkeepers / git-history.git
! [afgewezen] master -> master (niet snel vooruitspoelen)
fout: sommige referenties kunnen niet worden gepusht naar ’[email protected]: bkeepers / git-history.git’
hint: Updates zijn afgewezen omdat de tip van je huidige branch achterloopt
hint: zijn tegenhanger op afstand. Voeg de externe wijzigingen samen (bijv. ’Git pull’)
hint: voordat u opnieuw drukt.
hint: zie de ’Opmerking over vooruitspoelen’ in ’git push --help’ voor details.

Hoewel dit bericht er groot en eng uitziet, is het eigenlijk best nuttig. De hints vertellen ons dat sinds we met ons werk zijn begonnen, een van onze teamleden veranderingen heeft doorgevoerd en we deze moeten krijgen, meestal door te rennen git pull. De hint beveelt ook aan om de opmerking over ‘vooruitspoelen’ in de Git-documenten te lezen. Ik steun die aanbeveling.

Rennen git pull zal de externe wijzigingen ophalen en een nieuwe commit maken die ze samenvoegt met onze lokale wijzigingen. Hoewel er niets mis is met de merge-commit, voegt het onnodige complexiteit toe aan de revisiegeschiedenis.

$ git log --decorate --graph --oneline
* aaf6c0c (HEAD, master) Merge branch ’master’ van oorsprong
|
| * 9f7e4de Update README
* | 00165a8 eerste ontwerp van wijzigingsgedeelte
|/
* 667f8c9 (oorsprong / reset) README toevoegen

Wat onze geschiedenis duidelijker en leesbaarder zou maken, is een manier om onze wijzigingen over te nemen en ze toe te passen bovenop de veranderingen op afstand, zoals:

$ git pull --rebase oorsprong master
Eerst het hoofd terugspoelen om je werk er bovenop af te spelen ...
Toepassen: update README

Hierdoor wordt de revisiegeschiedenis weergegeven alsof de wijziging is aangebracht nadat een teamlid een vastlegging heeft gemaakt.

$ git log --decorate --graph --oneline
* 8dbf5d5 eerste versie van wijzigingssectie
* c408281 update README
* 667f8c9 README toevoegen

Je kunt zien dat onze Git-geschiedenis nu veel schoner en gemakkelijker te scannen is.

Tenzij een repository naar meerdere afstandsbedieningen wordt gepusht, is rebasen tijdens het trekken bijna altijd een goed idee. Ik heb Git geconfigureerd om automatisch te rebasen.

$ git config --global branch.autosetuprebase altijd

Het overzichtelijk houden van de revisiegeschiedenis lijkt misschien oppervlakkig, maar het helpt enorm bij het beheren van een groot project.

04. Ruim de recente geschiedenis op

Soms is het pas na een paar misstappen duidelijk dat er een beter pad is. De flexibiliteit van Git maakt het gemakkelijk om onderweg controlepunten te creëren, wat een punt biedt om naar terug te keren als er iets misgaat.

In mijn dagelijkse ontwikkeling zet ik me zo vaak mogelijk in. Elke keer als ik bij mezelf denk: "Oké, dat is gebeurd, wat nu?", Leg ik vast. Hoewel dit leidt tot een revisiegeschiedenis die de volgorde van de gebeurtenissen nauwkeurig weergeeft, kan het lawaai van vele kleine commits de onderhoudbaarheid van grote projecten in feite belemmeren. Dus zodra ik klaar ben om mijn wijzigingen met mijn team te delen, bekijk ik mijn niet-gepubliceerde commits en ruim ik ze op.

Een interactieve rebase laat toe om commits te bewerken, samen te persen of volledig te verwijderen uit de recente geschiedenis van een branch.

Toen ik mijn vorderingen met dit artikel bekeek, ontdekte ik een paar gênante typefouten. Omdat de repository nog met niemand was gedeeld, heb ik mijn sporen gecorrigeerd door de typefouten in de originele commit te corrigeren. Ik heb mijn oorspronkelijke fout behouden, dus je kunt meegaan door de typefouten-tak van de repository te bekijken.

Eerst heb ik twee nieuwe commits gemaakt om de typefouten te corrigeren.

$ git log --oneline
7445019 Spelfout van wijzig
b0377f9 Typefout in titel corrigeren
b1cdd72 eerste versie van pull --rebase
2fbe35b eerste concept van reset
7bb9109 eerste ontwerp van wijzigingsgedeelte
667f8c9 README toevoegen

Let op de commit die moet worden hersteld. Beide typefouten waren van commit 7bb9109, eerste ontwerp van wijzigingsgedeelte. Start de rebase bij de revisie vóór:

$ git rebase -i 7bb9109 ^

Git zal de editor openen met de lijst met commits en een zeer nuttig bericht.

kies 7bb9109 eerste concept van wijzigingssectie
kies 2fbe35b eerste concept van reset
kies b1cdd72 eerste versie van pull --rebase
kies b0377f9 Typefout in titel corrigeren
kies 7445019 Spelfout van wijzig

# Rebase 667f8c9..7445019 naar 667f8c9
#
# Commando's:
# p, pick = gebruik commit
# r, reword = gebruik vastleggen, maar bewerk het vastleggingsbericht
# e, edit = gebruik commit, maar stop om te wijzigen
# s, squash = gebruik vastleggen, maar versmelten met de vorige vastlegging
# f, fixup = like "squash", maar negeer het logbericht van deze commit
# x, exec = run commando (de rest van de regel) met shell
#
# Deze regels kunnen opnieuw worden besteld; ze worden van boven naar beneden uitgevoerd.
#
# Als je hier een regel verwijdert, ZAL DIE COMMIT VERLOREN WORDEN.
#
# Als u echter alles verwijdert, wordt de rebase afgebroken.
#
# Merk op dat lege commits worden uitgecommentarieerd

Zoals de notitie uitlegt, kunnen commits worden herschikt om hun volgorde te wijzigen, of plukken kan worden gewijzigd in een van de andere commando's.

kies 7bb9109 eerste versie van wijzigingssectie
fixup b0377f9 Typefout in titel corrigeren
fixup 7445019 Spelfout van wijzig
kies 2fbe35b eerste concept van reset
kies b1cdd72 eerste versie van pull --rebase

Ik heb de twee typfixes verplaatst naar net na de commit waar ze werden geïntroduceerd en veranderde de pick in reparatie om ze aan te melden bij de oorspronkelijke commit. Na het opslaan en sluiten van de editor, zal Git de wijzigingen toepassen:

[vrijstaande HEAD 00165a8] eerste versie van wijzigingsgedeelte
1 bestand gewijzigd, 47 invoegingen (+)
aanmaken mode 100644 article.md
Met succes rebased en bijgewerkt refs / heads / master.

Het logboek laat zien dat de typefout-fixerende commits nu verdwenen zijn. De fixes zijn toegepast op de originele commits en er is geen bewijs van mijn slechte spelling (in deze branche).

$ git log --oneline
4787614 eerste versie van pull --rebase
ee719e9 eerste concept van reset
00165a8 eerste ontwerp van wijzigingsgedeelte
667f8c9 README toevoegen

Deze rebase werkte zonder enige andere interactie, maar af en toe vereist een rebase handmatige fixes voor samenvoegconflicten. Als dat gebeurt, raak dan niet in paniek. Lees gewoon de berichten. Git helpt je meestal om uit de problemen te komen.

05. Herschrijf de hele geschiedenis

Alle Git-commando's die we tot nu toe hebben onderzocht, zijn nuttig voor het wijzigen van recente commits, maar soms zijn extremere maatregelen nodig, of het nu gaat om het verwijderen van gevoelige of extreem grote bestanden, of om een ​​project simpelweg gemakkelijker te beheren te maken.

git filter-branch ondersteunt een hand vol aangepaste filters die de revisiegeschiedenis kunnen herschrijven voor een reeks commits.

Mijn eerste legitieme gebruik van git filter-branch was op een groot project waarbij de server en de client zich allebei in dezelfde repository bevonden. Naarmate er meer mensen aan het team werden toegevoegd en de spanningen tussen de hipsters en nekbaarden toenamen, werd het duidelijk dat twee opslagplaatsen geschikter zouden zijn.

Een eenvoudige oplossing zou zijn geweest om de repository twee keer te klonen, de onnodige bestanden te verwijderen en de resterende bestanden te verplaatsen. Maar dat laat twee repositories met dubbele geschiedenissen die onnodige ruimte in beslag nemen. In plaats daarvan hebben we de repository twee keer gekloond en de --subdirectory-filter om twee nieuwe repositories te maken die alleen de wijzigingen voor de relevante delen van de applicatie bevatten.

$ git rebase -i 7bb9109 ^

Veel mensen gebruiken verschillende e-mailadressen voor persoonlijke en werkprojecten, wat gemakkelijk kan resulteren in commits naar een repository met het verkeerde e-mailadres. De --env-filter kan basismetadata over een vastlegging wijzigen, zoals informatie over de auteur of de vastlegdatum.

$ git filter-branch --env-filter ’
if [$ GIT_AUTHOR_EMAIL = [email protected]];
dan [email protected];
fi; GIT_AUTHOR_EMAIL ’exporteren
Herschrijven f853027b7979756bab7146d3bb34d8829b81a884 (8/8)
Ref ’refs / heads / master’ is herschreven

Stel dat iemand in het begin van een project een aantal extreem grote activa heeft vastgelegd, en nu moet iedereen die de repository kloont, wachten tot die activa zijn gedownload. Of misschien gebruikt u een open source voor een project waarin gevoelige gegevens zijn opgeslagen.

$ git filter-branch --index-filter ’git rm -r --cached --ignore-unmatch docs / designs’
--prune-empty --tag-name-filter cat - --all

Alle volgende wijzigingen zullen de volledige geschiedenis van een repository herschrijven, waardoor het in wezen een nieuwe repository wordt. Pushen naar dezelfde afstandsbediening die oorspronkelijk werd gebruikt, wordt geweigerd.

$ git push
! [afgewezen] master -> master (niet vooruitspoelen)

Het is mogelijk om Git te dwingen alle wijzigingen naar een bestaande afstandsbediening te pushen, maar onthoud dat dit nadelige effecten kan hebben voor alle anderen die aan het project werken.

$ git push --force --all --tags

06. Kracht en flexibiliteit

De krachtige functies, extreme flexibiliteit en vaak niet-intuïtieve commandoregel van Git lijken misschien overweldigend, maar de tijd nemen om te leren en te experimenteren is een investering die de moeite waard is. Geef bij twijfel door --helpen naar elk Git-commando voor meer informatie. Als u begrijpt hoe en wanneer u de revisiegeschiedenis moet herschrijven, krijgt u volledige controle over uw projecten en kunt u ze gemakkelijker beheren.

Afbeelding gebruikt met dank aan JohnGoode onder Creative Commons-licentieverlening

Brandon Keepers is een maker en breaker van dingen bij GitHub en werkt voornamelijk aan Speaker Deck. Als zijn gezicht niet vaag wordt verlicht door een computerscherm, kun je hem vinden met een boek in zijn handen, racquetball of basketbal spelen, rennen met zijn hond of genieten van lekker eten en drinken met zijn vrouw.

Vond dit leuk? Lees deze!

  • Een app bouwen: probeer deze geweldige tutorials
  • Nu gratis grafische ontwerpsoftware voor u beschikbaar!
  • Briljante selectie van Wordpress-tutorials
Zorg Ervoor Dat Je Eruit Ziet
Hoe je een klassiek schilderij opnieuw kunt bedenken
Lees Verder

Hoe je een klassiek schilderij opnieuw kunt bedenken

Het leven van een kun tenaar i er een van con tante uitdagingen, en de groot te daarvan i in piratie. Of liever: waar kun je het vinden? Natuurlijk zijn er genoeg bronnen waar je naar kunt verwijzen, ...
Lettergieterij verandert oude borden in geweldige lettertypen
Lees Verder

Lettergieterij verandert oude borden in geweldige lettertypen

In piratie chuilt in de mee t alledaag e ituatie , zolang je er maar naar uitkijkt. Voor ontwerper en letterkundige Je ica Krcmarik, de oprichter van lettergieterij Gratiot en Riopelle, wa het de wand...
Videotutorial: werk met de Envelope Distort-effecten van Illustrator
Lees Verder

Videotutorial: werk met de Envelope Distort-effecten van Illustrator

De hulpmiddelen voor het vervormen van enveloppen van Illu trator zijn buitengewoon handig, of u nu illu tratie maakt waarvoor een gevoel van reali me verei t i , of dat u eenvoudig vormen en objecten...