-
1. Pričetek
- 1.1 O nadzoru različic
- 1.2 Kratka zgodovina Git-a
- 1.3 Osnove Git
- 1.4 The Command Line
- 1.5 Git namesitev
- 1.6 Prva namestitev Git-a
- 1.7 Pridobitev pomoči
- 1.8 Povzetek
-
2. Osnove Git
- 2.1 Pridobitev repozitorija Git
- 2.2 Snemanje sprememb repozitorija
- 2.3 Pregled zgodovine pošiljanja
- 2.4 Razveljavljanje stvari
- 2.5 Delo z daljavami
- 2.6 Označevanje
- 2.7 Git aliasi
- 2.8 Povzetek
-
3. Veje Git
- 3.1 Veje na kratko
- 3.2 Osnove vej in združevanja
- 3.3 Upravljanje vej
- 3.4 Potek dela z vejami
- 3.5 Oddaljene veje
- 3.6 Ponovno baziranje (rebasing)
- 3.7 Povzetek
-
4. Git na strežniku
- 4.1 Protokoli
- 4.2 Pridobiti Git na strežnik
- 4.3 Generiranje vaših javnih ključev SSH
- 4.4 Nastavitev strežnika
- 4.5 Prikriti proces Git
- 4.6 Pametni HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Tretje osebne opcije gostovanja
- 4.10 Povzetek
-
5. Distribuirani Git
- 5.1 Distribuirani poteki dela
- 5.2 Prispevanje projektu
- 5.3 Vzdrževanje projekta
- 5.4 Povzetek
-
6. GitHub
-
7. Orodja Git
- 7.1 Revision Selection
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Signing Your Work
- 7.5 Searching
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Advanced Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Credential Storage
- 7.15 Povzetek
-
8. Prilagoditev Git-a
- 8.1 Git Configuration
- 8.2 Git Attributes
- 8.3 Git kljuke
- 8.4 An Example Git-Enforced Policy
- 8.5 Povzetek
-
9. Git in drugi sistemi
- 9.1 Git kot klient
- 9.2 Migracija na Git
- 9.3 Povzetek
-
10. Notranjost Git-a
- 10.1 Napeljava in porcelan
- 10.2 Git Objects
- 10.3 Git References
- 10.4 Packfiles
- 10.5 The Refspec
- 10.6 Transfer Protocols
- 10.7 Maintenance and Data Recovery
- 10.8 Environment Variables
- 10.9 Povzetek
-
A1. Appendix A: Git v drugih okoljih
- A1.1 Grafični vmesniki
- A1.2 Git v Visual Studiu
- A1.3 Git v Eclipse
- A1.4 Git V Bash-u
- A1.5 Git v Zsh
- A1.6 Git v Powershell-u
- A1.7 Povzetek
-
A2. Appendix B: Vključevanje Git-a v vašo aplikacijo
- A2.1 Git v ukazni vrstici
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Git Commands
- A3.1 Setup and Config
- A3.2 Getting and Creating Projects
- A3.3 Basic Snapshotting
- A3.4 Branching and Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
7.13 Orodja Git - Replace
Replace
Objekti v Git-u niso spremenljivi, vendar ponuja zanimiv način pretvarjanja zamenjave objektov v njegovi podatkovni bazi z drugimi objekti.
Ukaz replace
vam omogoča določiti objekt v Git-u in povedati "vsakič ko to vidite, se pretvarjaj, da gre za drugo stvar".
To je najpogostejše uporabno za zamenjavo enega pošiljanja v vaši zgodovini z drugim.
Na primer, predpostavimo, da imate veliko zgodovino kode in želite cepiti vaš repozitorij v eno hitro zgodovino za nove razvijalce in enega z veliko daljšo in večjo zgodovino za ljudi, ki jih zanima kopanje podatkov. Transplatirate lahko eno zgodovino v drugo z zamenjavo (replace) prejšnjih pošiljanj v novi vrstici z najnovejšim pošiljanjem na stari. To je lepo, ker pomeni, da vam ni potrebno dejansko prepisati vsakega pošiljanja v novi zgodovini, kot bi običajno morali, da ju združite skupaj (ker starševstvo vpliva na SHA-1).
Poskusimo to.
Naredimo obstoječi repozitorij, ga cepimo v dva repozitorija, enega zadnjega in enega zgodovinskega in nato bomo videli, kako lahko ponovno kombiniramo oba brez sprememb zadnjih SHA-1 vrednosti repozitorija preko replace
.
Uporabili bomo enostaven repozitorij s petimi enostavnimi pošiljanji:
$ git log --oneline
ef989d8 fifth commit
c6e1e95 fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Želimo to prelomiti v dve vrstici zgodovine. Ena vrstica gre iz prvega pošiljanja v četro pošiljanje - ta bo zgodovinski. Druga vrstica bosta samo pošiljanja 4 in 5.

Torej ustvarjanje zgodovinske zgodovine je enostavno, lahko samo damo vejo v zgodovino in nato potisnemo to vejo v glavno vejo novega oddaljenega repozitorija.
$ 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

Sedaj lahko potisnemo novo vejo history
v vejo master
našega novega repozitorija:
$ 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
Dobro, sedaj je naša zgodovina objavljena. Sedaj je težji del krajšanje naše zadnje zgodovine navzdol, da je manjša. Narediti moramo prekriavnje, da lahko zamenjamo pošiljanje v enem ekvivalentnem pošiljanju v drugem, torej bomo skrajšali to na samo pošiljanja 4 in 5 (torej se pošiljanje 4 prekrije).
$ git log --oneline --decorate
ef989d8 (HEAD, master) fifth commit
c6e1e95 (history) fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
V tem primeru je uporabno ustvariti osnovno pošiljanje, da ima navodila, kako razširiti zgodovino, da drugi razvijalci vejo, kaj narediti, če pridejo do prvega pošiljanja v prekriti zgodovini in potrebujejo več. Torej, kar bomo naredili je ustvarjanje začetnega objekta pošiljanja kot našo osnovno točko z navodili, nato naredili rebase ostalih pošiljanj (4 in 5) na vrhu le tega.
Da to naredimo, potrebujemo izbrati točko za cepitev, ki bo za nas tretje pošiljanje, ki je 9c68fdc
v besedi SHA.
Torej naše osnovno pošiljanje bo osnovano na tem drevesu.
Lahko ustvarimo naše osnovno pošiljanje z uporabo ukaza commit-tree
, ki samo vzame drevo in nam vrne popolnoma nov objekt pošiljanja SHA-1 brez starša.
$ echo 'get history from blah blah blah' | git commit-tree 9c68fdc^{tree}
622e88e9cbfbacfb75b5279245b9fb38dfea10cf
Note
|
Ukaz |

Torej sedaj ko imamo osnovno pošiljanje, lahko naredimo t.i. rebase na naši preostali zgodovini na vrhu tega, z git rebase --onto
.
Argument --onto
bo SHA-1, ki smo ga ravno dobili iz commit-tree
in točke rebase-a bo tretje pošiljanje (starš prvega pošiljanja, ki ga želimo obdržati 9c68fdc
):
$ git rebase --onto 622e88 9c68fdc
First, rewinding head to replay your work on top of it...
Applying: fourth commit
Applying: fifth commit

Torej sedaj smo prepisali našo zadnjo zgodovino na vrhu ovrženeega osnovnega pošiljanja, ki ima sedaj navodila v njem, kako rekonstruirati celotno zgodovino, če to želimo. Lahko pošljemo to novo zgodovino v nov projekt in sedaj, ko ljudje klonirajo ta repozitorij, bodo videli samo zadnji dve pošiljanji in nato osnovno pošiljanje z navodili.
Sedaj preklopimo vloge nekomu, ki prvič klonira projekt in želi celotno zgodovino. Da dobimo podatke zgodovine po kloniranju tega skrajšanega repozitorija, bi nekdo moral dodati drugo daljavo za zgodovinski repozitorij in jo ujeti:
$ 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
Sedaj bi sodelavec moral imeti svoja zadnja pošiljanja v veji master
in zgodovinsko pošiljanje v veji project-history/master
.
$ 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
Da jih kombiniramo, lahko enostavno pokličete git replace
s pošiljanjem, ki ga želite zamenjati in nato poslati, kar želite z njim zamenjati.
Torej želimo zamenjati četrto pošiljanje v veji master s četrtim pošiljanjem v veji project-history/master
:
$ git replace 81a708d c6e1e95
Sedaj, če pogledate zgodovino veje master
, izgleda nekako takole:
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Kul, kajne? Brez, da moramo spremeniti vse SHA-1 zgornjega toka, smo lahko zamenjali eno pošiljanje v naši zgodovini s popolnoma drugim pošiljanjem in vsa običajna orodja (bisect
, blame
itd) bodo delovala kakor pričakujemo.

Zanimivo še vedno kaže 81a708d
kot SHA-1, čeprav dejansko uporablja c6e1e95
, podatke pošiljanja, s katerimi smo jih zamenjali.
Tudi če poženete ukaz, kot je cat-file
, vam bo pokazal zamenjane podatke:
$ 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
Zapomniti si je dobro, da je bil dejanski starš 81a708d
ograda pošiljanja (622e88e
) in ne 9c68fdce
kakor je tu zabeleženo.
Druga zanimiva stvar je, da so ti podatki obdržani v naši referenci:
$ 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
To pomeni, da je enostavno deliti našo zamenjavo z drugimi, ker lahko potisnemo to na naš strežnik in drugi ljudje lahko to enostavno prenesejo. To ni v pomoč v zgodovini scenarija presadka, ko smo šli skozi tu (ker bi vsak prenesel obe zgodovini tako ali tako, torej zakaj ju ločiti?), vendar je lahko uporabno v drugih okoliščinah.