-
1. Aan die slag
- 1.1 Oor Weergawebeheer
- 1.2 Wat is Git?
- 1.3 Die Opdragreël
- 1.4 Git Installeer
- 1.5 Git klaarmaak vir eerste gebruik
- 1.6 Hulp Verkry
- 1.7 Opsomming
-
2. Git Basics
-
3. Git Branching
-
4. Git on the Server
- 4.1 Die Protokolle (The Protocols)
- 4.2 Git op 'n Bediener kry (Getting Git on a Server)
- 4.3 Jou Publieke SSH-sleutel Genereer (Generating Your SSH Public Key)
- 4.4 Die Bediener Opstel (Setting Up the Server)
- 4.5 Git Daemon
- 4.6 Slim HTTP (Smart HTTP)
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Derdeparty-gasheuroplossings (Third-Party Hosting Solutions)
- 4.10 Summary
-
5. Distributed Git
-
6. GitHub
-
7. Git Tools
- 7.1 Hersieningseleksie (Revision Selection)
- 7.2 Interaktiewe Voorbereiding (Interactive Staging)
- 7.3 Bêre en Skoonmaak (Stashing and Cleaning)
- 7.4 Ondertekening van Jou Werk (Signing Your Work)
- 7.5 Soek (Searching)
- 7.6 Herskryf van Geskiedenis (Rewriting History)
- 7.7 Reset Ontmystifiseer (Reset Demystified)
- 7.8 Gevorderde Saamsmelting (Advanced Merging)
- 7.9 Rerere
- 7.10 Ontfouting met Git (Debugging with Git)
- 7.11 Submodules
- 7.12 Bundeling (Bundling)
- 7.13 Vervang (Replace)
- 7.14 Die Stoor van Aanmeldbewyse (Credential Storage)
- 7.15 Summary
-
8. Customizing Git
-
9. Git and Other Systems
- 9.1 Git as a Client
- 9.2 Migrating to Git
- 9.3 Summary
-
10. Git Internals
7.13 Git Tools - Vervang (Replace)
Vervang (Replace)
Soos ons vroeër beklemtoon het, is die objekte in Git se objekdatabasis onveranderlik, maar Git bied wel 'n interessante manier om te maak asof dit objekte in sy databasis met ander objekte vervang.
Die replace opdrag laat jou toe om 'n objek in Git te spesifiseer en te sê "elke keer as jy na hierdie objek verwys, maak asof dit 'n ander objek is".
Dit is die nuttigste om een vaslegging (commit) in jou geskiedenis met 'n ander te vervang sonder om die hele geskiedenis te hoef te herbou met, sê maar, git filter-branch.
Byvoorbeeld, sê nou jy het 'n massiewe kodegeskiedenis en wil jou bewaarplek (repository) opsplits in een kort geskiedenis vir nuwe ontwikkelaars en een baie langer en groter geskiedenis vir mense wat belangstel in data-ontginning (data mining). Jy kan die een geskiedenis op die ander ent (graft) deur die vroegste vaslegging in die nuwe lyn te "vervang" met die nuutste vaslegging in die oue. Dit is lekker omdat dit beteken dat jy nie eintlik elke vaslegging in die nuwe geskiedenis hoef te herskryf nie, soos wat jy normaalweg sou moes doen om hulle aan mekaar te koppel (omdat die afkoms die SHA-1’s beïnvloed).
Kom ons probeer dit uit.
Kom ons neem 'n bestaande bewaarplek, deel dit op in twee bewaarplekke, een resente en een historiese, en dan sal ons sien hoe ons hulle kan herkombineer sonder om die resente bewaarplek se SHA-1-waardes via replace te wysig.
Ons sal 'n eenvoudige bewaarplek met vyf eenvoudige vasleggings gebruik:
$ git log --oneline
ef989d8 Fifth commit
c6e1e95 Fourth commit
9c68fdc Third commit
945704c Second commit
c1822cf First commit
Ons wil dit opbreek in twee lyne van geskiedenis. Een lyn loop van vaslegging een tot vaslegging vier - dit sal die historiese een wees. Die tweede lyn sal net vasleggings vier en vyf wees - dit sal die resente geskiedenis wees.
Wel, om die historiese geskiedenis te skep is maklik; ons kan net 'n tak in die geskiedenis plaas en dan daardie tak na die master tak van 'n nuwe afgeleë bewaarplek (remote repository) push.
$ git branch history c6e1e95
$ git log --oneline --decorate
ef989d8 (HEAD, master) Fifth commit
c6e1e95 (history) Fourth commit
9c68fdc Third commit
945704c Second commit
c1822cf First commit
history takNou kan ons die nuwe history tak na die master tak van ons nuwe bewaarplek push:
$ git remote add project-history https://github.com/schacon/project-history
$ git push project-history history:master
Counting objects: 12, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (12/12), 907 bytes, done.
Total 12 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (12/12), done.
To git@github.com:schacon/project-history.git
* [new branch] history -> master
Oukei, so ons geskiedenis is gepubliseer. Nou is die moeiliker deel om ons resente geskiedenis af te knot (truncate) sodat dit kleiner is. Ons het 'n oorvleueling nodig sodat ons 'n vaslegging in die een kan vervang met 'n ekwivalente vaslegging in die ander, so ons gaan dit afknot na net vasleggings vier en vyf (so vaslegging vier oorvleuel).
$ git log --oneline --decorate
ef989d8 (HEAD, master) Fifth commit
c6e1e95 (history) Fourth commit
9c68fdc Third commit
945704c Second commit
c1822cf First commit
Dit is in hierdie geval nuttig om 'n basisvaslegging (base commit) te skep wat instruksies het oor hoe om die geskiedenis uit te brei, sodat ander ontwikkelaars weet wat om te doen as hulle die eerste vaslegging in die afgeknotte geskiedenis tref en meer nodig het. So, wat ons gaan doen, is om 'n aanvanklike vasleggingsobjek as ons basispunt met instruksies te skep, en dan die oorblywende vasleggings (vier en vyf) bo-op dit te rebase.
Om dit te doen, moet ons 'n punt kies om af te splits, wat vir ons die derde vaslegging is, wat 9c68fdc in SHA-taal is.
Dus sal ons basisvaslegging op daardie boom (tree) gebaseer wees.
Ons kan ons basisvaslegging skep met behulp van die commit-tree opdrag, wat net 'n boom neem en vir ons 'n splinternuwe, ouerlose vasleggingsobjek SHA-1 teruggee.
$ echo 'Get history from blah blah blah' | git commit-tree 9c68fdc^{tree}
622e88e9cbfbacfb75b5279245b9fb38dfea10cf
|
Note
|
Die |
commit-tree
Goed, aangesien ons nou 'n basisvaslegging het, kan ons die res van ons geskiedenis bo-op dit rebase met git rebase --onto.
Die --onto argument sal die SHA-1 wees wat ons pas van commit-tree af teruggekry het en die rebase-punt sal die derde vaslegging wees (die ouer van die eerste vaslegging wat ons wil behou, 9c68fdc):
$ git rebase --onto 622e88 9c68fdc
First, rewinding head to replay your work on top of it...
Applying: fourth commit
Applying: fifth commit
Goed, ons het nou ons resente geskiedenis herskryf bo-op 'n weggooi-basisvaslegging wat nou instruksies in het oor hoe om die hele geskiedenis te hersaamstel as ons wou. Ons kan daardie nuwe geskiedenis na 'n nuwe projek push en nou as mense daardie bewaarplek kloon, sal hulle net die mees onlangse twee vasleggings sien en dan 'n basisvaslegging met instruksies.
Kom ons ruil nou rolle om na iemand wat die projek vir die eerste keer kloon en wat die hele geskiedenis wil hê. Om die geskiedenisdata te kry na die kloning van hierdie afgeknotte bewaarplek, sal mens 'n tweede remote vir die historiese bewaarplek moet byvoeg en afhaal (fetch):
$ git clone https://github.com/schacon/project
$ cd project
$ git log --oneline master
e146b5f Fifth commit
81a708d Fourth commit
622e88e Get history from blah blah blah
$ git remote add project-history https://github.com/schacon/project-history
$ git fetch project-history
From https://github.com/schacon/project-history
* [new branch] master -> project-history/master
Nou sal die medewerker (collaborator) hul resente vasleggings in die master tak hê en die historiese vasleggings in die project-history/master tak.
$ git log --oneline master
e146b5f Fifth commit
81a708d Fourth commit
622e88e Get history from blah blah blah
$ git log --oneline project-history/master
c6e1e95 Fourth commit
9c68fdc Third commit
945704c Second commit
c1822cf First commit
Om hulle te kombineer, kan jy eenvoudig git replace aanroep met die vaslegging wat jy wil vervang en dan die vaslegging waarmee jy dit wil vervang.
Ons wil dus die "vierde" vaslegging in die master tak vervang met die "vierde" vaslegging in die project-history/master tak:
$ git replace 81a708d c6e1e95
As jy nou na die geskiedenis van die master tak kyk, blyk dit om so te lyk:
$ git log --oneline master
e146b5f Fifth commit
81a708d Fourth commit
9c68fdc Third commit
945704c Second commit
c1822cf First commit
Koel, nê? Sonder om al die SHA-1’s stroomop te hoef verander, kon ons een vaslegging in ons geskiedenis vervang met 'n heeltemal ander vaslegging en al die normale gereedskap (bisect, blame, ens.) sal werk soos ons sou verwag.
git replace
Interessant genoeg wys dit steeds 81a708d as die SHA-1, alhoewel dit eintlik die c6e1e95 vasleggingsdata gebruik waarmee ons dit vervang het.
Selfs al voer jy 'n opdrag soos cat-file uit, sal dit vir jou die vervangde data wys:
$ git cat-file -p 81a708d
tree 7bc544cf438903b65ca9104a1e30345eee6c083d
parent 9c68fdceee073230f19ebb8b5e7fc71b479c0252
author Scott Chacon <schacon@gmail.com> 1268712581 -0700
committer Scott Chacon <schacon@gmail.com> 1268712581 -0700
fourth commit
Onthou dat die werklike ouer van 81a708d ons plekhouer-vaslegging (placeholder commit - 622e88e) was, nie 9c68fdce soos dit hier aandui nie.
Nog 'n interessante ding is dat hierdie data in ons verwysings (references) gehou word:
$ git for-each-ref
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/heads/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/remotes/history/master
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/HEAD
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040
Dit beteken dat dit maklik is om ons vervanging met ander te deel, want ons kan dit na ons bediener push en ander mense kan dit maklik aflaai. Dit is nie so nuttig in die geskiedenis-entings-scenario (history grafting scenario) waaroor ons hier gegaan het nie (aangesien almal in elk geval albei geskiedenisse sou aflaai, so hoekom hulle skei?), maar dit kan nuttig wees in ander omstandighede.