-
1. Začetek
- 1.1 O nadzoru različic
- 1.2 Kratka zgodovina Gita
- 1.3 Kaj je Git?
- 1.4 Ukazna vrstica
- 1.5 Namestitev Gita
- 1.6 Prva nastavitev Gita
- 1.7 Pridobivanje pomoči
- 1.8 Povzetek
-
2. Osnove Git
- 2.1 Pridobivanje repozitorija Git
- 2.2 Snemanje sprememb v repozitorij
- 2.3 Pregled zgodovine potrditev
- 2.4 Razveljavljanje stvari
- 2.5 Delo z daljavami
- 2.6 Označevanje
- 2.7 Aliasi Git
- 2.8 Povzetek
-
3. Veje Git
- 3.1 Veje na kratko
- 3.2 Osnove vej in združevanja
- 3.3 Upravljanje vej
- 3.4 Poteki dela z vejami
- 3.5 Oddaljene veje
- 3.6 Ponovno baziranje
- 3.7 Povzetek
-
4. Git na strežniku
- 4.1 Protokoli
- 4.2 Pridobitev Gita na strežniku
- 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 Možnosti gostovanja pri tretjih ponudnikih
- 4.10 Povzetek
-
5. Porazdeljeni Git
- 5.1 Porazdeljeni poteki dela
- 5.2 Prispevek k projektu
- 5.3 Vzdrževanje projekta
- 5.4 Povzetek
-
6. GitHub
-
7. Orodja Git
- 7.1 Izbira revizije
- 7.2 Interaktivno pripravljanje
- 7.3 Shranjevanje na varno (angl. stashing) in čiščenje
- 7.4 Podpisovanje vašega dela
- 7.5 Iskanje
- 7.6 Prepisovanje zgodovine
- 7.7 Demistifikacija ponastavitve
- 7.8 Napredno združevanje
- 7.9 Rerere
- 7.10 Razhroščevanje z Gitom
- 7.11 Podmoduli
- 7.12 Povezovanje v pakete
- 7.13 Zamenjava
- 7.14 Shramba poverilnic
- 7.15 Povzetek
-
8. Prilagoditev Gita
- 8.1 Konfiguracija Git
- 8.2 Atributi Git
- 8.3 Kljuke Git
- 8.4 Primer pravilnika, ki ga uveljavlja Git
- 8.5 Povzetek
-
9. Git in ostali sistemi
- 9.1 Git kot odjemalec
- 9.2 Migracija na Git
- 9.3 Povzetek
-
10. Notranjost Gita
- 10.1 Napeljava in keramika
- 10.2 Objekti Git
- 10.3 Reference Git
- 10.4 Packfiles (datoteke zmanjšanih podatkov)
- 10.5 Refspec
- 10.6 Protokoli prenosa
- 10.7 Vzdrževanje in obnovitev podatkov
- 10.8 Spremenljivke okolja
- 10.9 Povzetek
-
A1. Dodatek A: Git v drugih okoljih
- A1.1 Grafični vmesniki
- A1.2 Git v Visual Studio
- A1.3 Git v Visual Studio Code
- A1.4 Git v IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git v Sublime Text
- A1.6 Git v Bashu
- A1.7 Git v Zsh
- A1.8 Git v Powershellu
- A1.9 Povzetek
-
A2. Dodatek B: Vdelava Gita v vašo aplikacijo
- A2.1 Git v ukazni vrstici
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Dodatek C: Ukazi Git
- A3.1 Nastavitev in konfiguracija
- A3.2 Pridobivanje in ustvarjanje projektov
- A3.3 Osnove posnetkov
- A3.4 Veje in združevanje
- A3.5 Deljenje in posodabljanje projektov
- A3.6 Pregled in primerjava
- A3.7 Razhroščevanje
- A3.8 Popravljanje
- A3.9 E-pošta
- A3.10 Zunanji sistemi
- A3.11 Administracija
- A3.12 Orodja za sisteme napeljave
9.2 Git in ostali sistemi - Migracija na Git
Migracija na Git
Če imate obstoječo bazo kode v drugem VCS-ju, vendar ste se odločili začeti uporabljati Git, morate migrirati vaš projekt na en ali drug način. Ta razdelek gre skozi nekaj uvoznikov za pogoste sisteme in nato demonstrira, kako razviti vašega lastnega uvoznika. Naučili se boste, kako uvažati podatke iz nekaj največjih profesionalnih uporabljenih sistemov SCM (upravljanje izvorne kode, angl. source code management), kar je glavnina uporabnikov, ki preklapljajo, in ker so visoko kakovostna orodja zanje enostavna za dobiti.
Subversion
Če ste prebrali prejšnji razdelek o uporabi git svn
, lahko enostavno uporabite ta navodila za git svn clone
repozitorija; nato prenehajte uporabljati strežnik Subversion, potisnite na novi strežnik Git in ga začnite uporabljati.
Če želite zgodovino, lahko to dosežete, kakor hitro lahko povlečete podatke iz strežnika Subversion (kar lahko vzame nekaj časa).
Vendar uvažanje ni popolno; in ker bo vzelo nekaj časa, lahko tudi naredite, kakor je prav.
Prvi problem so informacije avtorja.
V Subversionu ima vsaka oseba, ki potrjuje, uporabnika na sistemu, ki je posnet v informacijah potrditve.
Primeri v prejšnjem razdelku prikazujejo na nekaterih mestih schacon
, kot je izpis blame
in git svn log
.
Če želite preslikati to na boljše podatke avtorja v Gitu, morate preslikati uporabnike iz Subversiona na avtorje Git.
Ustvarite datoteko imenovano users.txt
, ki ima to preslikavo v naslednji obliki:
schacon = Scott Chacon <schacon@geemail.com>
selse = Someo Nelse <selse@geemail.com>
Da dobite seznam imen avtorjev, ki jih uporablja SVN, lahko poženete to:
$ svn log --xml --quiet | grep author | sort -u | \
perl -pe 's/.*>(.*?)<.*/$1 = /'
To generira izpis dnevnika v formatu XML, nato obdrži samo vrstice z informacijami avtorja, opusti duplikate in izpusti značke XML.
Očitno to deluje samo na napravi z nameščenimi grep
, sort
in perl
.
Nato preusmerite ta izpis v vašo datoteko users.txt
, da lahko dodate enakovredne podatke uporabnika Git zraven vsakega vnosa.
Opomba
|
Če to poskušate na napravi Windows, je to točka, kjer boste naleteli na težave. Microsoft je ponudil nekaj dobrih nasvetov in primerov na https://learn.microsoft.com/en-us/azure/devops/repos/git/perform-migration-from-svn-to-git. |
To datoteko lahko ponudite git svn
, da bolj točno pomaga preslikati podatke avtorja.
Poveste lahko tudi, naj git svn
ne vključuje metapodatkov, ki jih Subvestion običajno uvaža s podajanjem --no-metadata
k ukazoma clone
ali init
.
Ti metapodatki vključujejo git-svn-id
znotraj vsakega sporočila potrditve, ki jih bo Git generiral med vnosom.
To lahko napihne vaš dnevnik Git in ga naredi nekoliko nejasnega.
Opomba
|
Te metapodatke morate obdržati, ko želite prezrcaliti potrditve narejene v repozitoriju Git nazaj na prvotni repozitorij SVN.
Če ne želite te sinhronizacije v svojem dnevniku potrditev, lahko tudi spustite parameter |
To naredi, da je vaš ukaz import
videti naslednje:
$ git svn clone http://my-project.googlecode.com/svn/ \
--authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_project
Sedaj morate imeti lepši uvoz Subversiona v vašem direktoriju my_project
.
Namesto potrditev, ki so videti takole:
commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
be05-5f7a86268029
so videti takole:
commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <schacon@geemail.com>
Date: Sun May 3 00:12:22 2009 +0000
fixed install - go to trunk
Ne samo, da je polje Author videti veliko boljše, ampak tudi git-svn-id
ni več tam.
Sedaj bi morali narediti tudi nekaj čiščenja po uvozu.
Za eno stvar, bi morali počistiti čudne reference, ki jih je nastavil git svn
.
Najprej boste premaknili oznake, da so dejansko oznake namesto čudnih oddaljenih vej in nato boste premaknili preostanek vej, da so lokalne.
Da premaknete oznake, da so ustrezne oznake Git, poženite:
$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done
To vzame reference, ki so oddaljene veje in se začnejo z refs/remotes/tags/
, ter jih naredi realne (enostavne) oznake.
Naslednje, premaknite preostanek referenc pod refs/remotes
, da so lokalne veje:
$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done
Lahko se zgodi, da boste videli nekatere dodatne veje, ki nimajo pripone @xxx
(kjer je xxx število), medtem ko boste v Subversion videli samo eno vejo.
To je dejansko lastnost v Subversionu imenovana »peg-revisions«, kar je nekaj, za kar Git enostavno nima sintaktične protipostavke.
Torej, git svn
enostavno doda številko različice SVN k imenu veje na isti način, kot bi napisali, da naslovite SVN za peg-revision
tiste veje.
Če vas peg-revision
ne skrbi več, jih enostavno odstranite:
$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
Sedaj so vse stare veje prave veje Git in vse stare oznake so prave oznake Git.
Še nekaj je treba počistiti.
Na žalost git svn
ustvari dodatno vejo imenovano trunk
, ki preslika privzete veje Subversiona, vendar pa kaže točka ref trunk
na isto mesto kot master
.
Ker je master
idiomatsko bolj Gitov, takole odstranite dodatno vejo:
$ git branch -d trunk
Zadnja stvar, ki jo morate narediti, je dodati vaš novi strežnik Git kot daljavo in potisniti nanj. Tu je primer dodajanja vašega strežnika kot daljavo:
$ git remote add origin git@my-git-server:myrepository.git
Ker želite dodati gor vse vaše veje in oznake, lahko sedaj poženete to:
$ git push origin --all
$ git push origin --tags
Vse vaše veje in oznake bi morale biti na vašem novem strežniku Git z lepim in čistim uvozom.
Mercurial
Ker imate Mercurial in Git precej podobna modela za predstavitev verzij in ker je Git nekoliko bolj prilagodljiv, je pretvorba repozitorija iz Mercurial na Git precej enostavna z uporabo orodja imenovanega »hg-fast-export«, ki ga boste morali kopirati:
$ git clone https://github.com/frej/fast-export.git
Prvi korak pretvorbe je dobiti polni klon repozitorija Mercurial, ki ga želite pretvoriti:
$ hg clone <remote repo URL> /tmp/hg-repo
Naslednji korak je ustvariti datoteko preslikave avtorja.
Mercurial je nekoliko bolj odpustljiv kot Git, zaradi česar bo dal polje avtorja za skupke sprememb, torej je to dober čas za čiščenje hiše.
Generiranje tega je ukaz ene vrstice v lupini bash
:
$ cd /tmp/hg-repo
$ hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
To bo vzelo nekaj sekund, odvisno od tega kako dolga je zgodovina vašega projekta in potem bo datoteka /tmp/authors
videti nekako takole:
bob
bob@localhost
bob <bob@company.com>
bob jones <bob <AT> company <DOT> com>
Bob Jones <bob@company.com>
Joe Smith <joe@company.com>
V tem primeru je ista oseba (Bob) ustvarila skupek sprememb pod štirimi različnimi imeni, ena izmed njih je dejansko videti v redu in ena od njih bi bila popolnoma neveljavna za potrditev Git.
Hg-fast-export nam omogoča to popraviti s spremembo vsake vrstice v pravilo: "<input>"="<output>"
, kar preslika <input>
v <output>
.
Znotraj nizov <input>
in <output>
so podprta vsa ubežana zaporedja, ki jih razume Python kodiran string_escape
.
Če datoteka s preslikavami avtorjev ne vsebuje prilegajočega se <input>
, bo ta avtor posredovan naprej Gitu nespremenjen.
Če so vsa uporabniška imena videti v redu, te datoteke sploh ne bomo potrebovali.
V tem primeru želimo, da je naša datoteka videti takole:
"bob"="Bob Jones <bob@company.com>"
"bob@localhost"="Bob Jones <bob@company.com>"
"bob <bob@company.com>"="Bob Jones <bob@company.com>"
"bob jones <bob <AT> company <DOT> com>"="Bob Jones <bob@company.com>"
Enaka datoteka preslikave se lahko uporabi za preimenovanje vej in oznak, ko ime Mercuriala to ne dovoljuje z Gitom.
Naslednji korak je ustvariti naš novi repozitorij Git in pognati izvozni skript:
$ git init /tmp/converted
$ cd /tmp/converted
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Zastaviva -r
pove hg-fast-export, kje najti repozitorij Mercurial, ki ga želimo pretvoriti, zastavica -A
pa mu pove, kje najti datoteko preslikav avtorjev (datoteke preslikav vej in oznak so določene z zastavicama -B
in -T
flags).
Skript prevede skupke sprememb Mercuriala in jih pretvori v skript za Gitovo lastnost »fast-import« (o kateri bomo govorili v podrobnosti nekoliko kasneje).
To vzame nekaj časa (čeprav je veliko hitreje, kot bi bilo preko omrežja) in izpis je precej opisen:
$ /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Loaded 4 authors
master: Exporting full revision 1/22208 with 13/0/0 added/changed/removed files
master: Exporting simple delta revision 2/22208 with 1/1/0 added/changed/removed files
master: Exporting simple delta revision 3/22208 with 0/1/0 added/changed/removed files
[…]
master: Exporting simple delta revision 22206/22208 with 0/4/0 added/changed/removed files
master: Exporting simple delta revision 22207/22208 with 0/2/0 added/changed/removed files
master: Exporting thorough delta revision 22208/22208 with 3/213/0 added/changed/removed files
Exporting tag [0.4c] at [hg r9] [git :10]
Exporting tag [0.4d] at [hg r16] [git :17]
[…]
Exporting tag [3.1-rc] at [hg r21926] [git :21927]
Exporting tag [3.1] at [hg r21973] [git :21974]
Issued 22315 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 120000
Total objects: 115032 ( 208171 duplicates )
blobs : 40504 ( 205320 duplicates 26117 deltas of 39602 attempts)
trees : 52320 ( 2851 duplicates 47467 deltas of 47599 attempts)
commits: 22208 ( 0 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 109 ( 2 loads )
marks: 1048576 ( 22208 unique )
atoms: 1952
Memory total: 7860 KiB
pools: 2235 KiB
objects: 5625 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 90430
pack_report: pack_mmap_calls = 46771
pack_report: pack_open_windows = 1 / 1
pack_report: pack_mapped = 340852700 / 340852700
---------------------------------------------------------------------
$ git shortlog -sn
369 Bob Jones
365 Joe Smith
To je večinoma vse, kar je. Vse oznake Mercuriala so bile pretvorjene v oznake Git in veje z zaznamki Mercurial so bili pretvorjeni v veje Git. Sedaj ste pripravljeni potisniti repozitorij na njegov novi strežniški dom:
$ git remote add origin git@my-git-server:myrepository.git
$ git push origin --all
Perforce
Naslednji sistem, ki ga boste pogledali pri uvažanju, je Perforce. Kot smo govorili zgoraj, sta dva načina, da omogočimo Gitu in Perforcu govoriti drug z drugim: git-p4 in Perforce Git Fusion.
Perforce Git Fusion
Git Fusion naredi ta proces precej neboleč. Samo nastavite nastavitve svojega projekta, preslikave uporabnika in veje, ki uporabljajo nastavitveno datoteko (kot je omenjeno v Git Fusion) in klonirajte repozitorij. Git Fusion vas pusti z nečim, kar je videti kot domači repozitorij Git, ki je nato pripravljen za potiskanje na domačega gostitelja Git, če želite. Perforce bi lahko uporabili celo kot vaš gostitelj Git, če želite.
Git-p4
Git-p4 se lahko obnaša tudi kot uvozno orodje. Kot primer, bomo uvozili projekt Jam iz Perforce Public Depot. Da nastavite svojega odjemalca, morate izvoziti okoljsko spremenljivko P4PORT, da kaže na depo Perforce:
$ export P4PORT=public.perforce.com:1666
Opomba
|
Da sledite zraven, boste za povezavo potrebovali depo Perforce. Za svoj primer bomo uporabljali javni depo na public.perforce.com, vendar lahko uporabite tudi katerikoli drugi depo, do katerega imate dostop. |
Poženite ukaz git p4 clone
, da uvozite projekt Jam iz strežnika Perforce, kar dobavlja depo in pot projekta ter pot, v katero želite uvoziti projekt:
$ git-p4 clone //guest/perforce_software/jam@all p4import
Importing from //guest/perforce_software/jam@all into p4import
Initialized empty Git repository in /private/tmp/p4import/.git/
Import destination: refs/remotes/p4/master
Importing revision 9957 (100%)
Ta določeni projekt ima samo eno vejo, vendar če imate veje, ki so nastavljive s pogledi vej (ali samo skupkom direktorijev), lahko uporabite zastavico --detect-branches
na git p4 clone
, da uvozite tudi vse veje projekta.
Glejte razdelek Veje za nekoliko več podrobnosti o tem.
Na tej točki ste že skoraj končali.
Če greste v direktorij p4import
in poženete git log
, lahko vidite svoje uvoženo delo:
$ git log -2
commit e5da1c909e5db3036475419f6379f2c73710c4e6
Author: giles <giles@giles@perforce.com>
Date: Wed Feb 8 03:13:27 2012 -0800
Correction to line 355; change </UL> to </OL>.
[git-p4: depot-paths = "//public/jam/src/": change = 8068]
commit aa21359a0a135dda85c50a7f7cf249e4f7b8fd98
Author: kwirth <kwirth@perforce.com>
Date: Tue Jul 7 01:35:51 2009 -0800
Fix spelling error on Jam doc page (cummulative -> cumulative).
[git-p4: depot-paths = "//public/jam/src/": change = 7304]
Vidite lahko, da je git-p4
pustil identifikator v vsakem sporočilu potrditve.
V redu je obdržati ta identifikator tam v primeru, če se morate kasneje sklicevati na število spremembe Perforce.
Vendar če želite odstraniti identifikator, je to sedaj čas, da naredite — preden začnete delati na novem repozitoriju.
Lahko uporabite git filter-branch
, da odstranite nize identifikatorja v celoti:
$ git filter-branch --msg-filter 'sed -e "/^\[git-p4:/d"'
Rewrite e5da1c909e5db3036475419f6379f2c73710c4e6 (125/125)
Ref 'refs/heads/master' was rewritten
Če poženete git log
, lahko vidite, da so bile vse kontrolne vsote SHA-1 za potrditve spremenjene, vendar nizi git-p4
niso več v sporočilih potrditev:
$ git log -2
commit b17341801ed838d97f7800a54a6f9b95750839b7
Author: giles <giles@giles@perforce.com>
Date: Wed Feb 8 03:13:27 2012 -0800
Correction to line 355; change </UL> to </OL>.
commit 3e68c2e26cd89cb983eb52c024ecdfba1d6b3fff
Author: kwirth <kwirth@perforce.com>
Date: Tue Jul 7 01:35:51 2009 -0800
Fix spelling error on Jam doc page (cummulative -> cumulative).
Vaš uvoz je sedaj pripravljen za potisk na vaš novi strežnik Git.
Uvažanje po meri
Če vaš sistem ni eden od zgoraj omenjenih, poiščite uvoznika na spletu — kakovostni uvozniki so na voljo za mnoge druge sisteme, vključno s CVS, Clear Case, Visual Source Safe in celo imenikom arhivov.
Če nobeno od teh orodij ne deluje za vas, ali imate bolj zapleteno orodje, ali pa potrebujete drugačen postopek uvoza, uporabite git fast-import
.
Ta ukaz preprosto prebere navodila iz standardnega vhoda za pisanje določenih podatkov Git.
Na ta način je veliko lažje ustvariti objekte Git kot z uporabo surovih ukazov Git ali poskusom pisanja surovih objektov (za več informacij glejte poglavje Notranjost Gita).
Na ta način lahko napišete uvozni skript, ki iz sistema, iz katerega uvažate, bere potrebne informacije in izpiše preprosta navodila na standardni izhod.
Nato lahko to program poženete in njegov izhod preusmerite skozi git fast-import
.
Za hitro demonstracijo boste napisali preprost program za uvažanje.
Predpostavimo, da delate v mapi current
, svoj projekt pa varnostno kopirate tako, da občasno kopirate mapo v varnostno kopijo back_YYYY_MM_DD
z oznako datuma, in to želite uvoziti v Git.
Vaša mapa je videti takole:
$ ls /opt/import_from
back_2014_01_02
back_2014_01_04
back_2014_01_14
back_2014_02_03
current
Če želite uvoziti Gitov direktorij, morate pregledati, kako Git shranjuje svoje podatke.
Kot se morda spomnite, je Git v osnovi povezan seznam objektov potrditev, ki kažejo na posnetek vsebine.
Vse, kar morate storiti, je povedati fast-import
, kaj so posnetki vsebine, na kaj kažejo podatki potrditve in v kakšnem vrstnem redu gredo.
Vaša strategija bo, da boste posamezne posnetke poiskali po vrstnem redu in za vsako mapo ustvarili potrditev z vsebino te mape, pri tem pa vsako potrditev povezali s prejšnjo.
Kot smo storili v Primer pravilnika, ki ga uveljavlja Git, bomo to napisali v Rubyju, ker gre za jezik, s katerim se običajno ukvarjamo, in ker je običajno enostaven za branje.
Ta primer lahko precej enostavno napišete v katerem koli drugem jeziku, ki ga poznate — le ustrezne podatke morate izpisati v stdout.
Če delate v sistemu Windows, bodite pozorni, da ne vnesete vsebnosti pomika na konec vrstice — git fast-import
zelo natančno zahteva samo vrstice (LF), ne pa vsebnosti pomika s karetom (CRLF), ki jih uporablja Windows.
Najprej se boste premaknili v ciljni imenik in identificirali vsak podimenik, ki predstavlja posnetek, ki ga želite uvoziti kot potrditev. Za vsak podimenik se boste premaknili vanj in natisnili ukaze, ki so potrebni za izvoz. Osnovna zanka je videti tako:
last_mark = nil
# loop through the directories
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
V vaši metodi print_export
v vsaki mapi zaženete funkcijo, ki vzame manifest in označbo (angl. mark) prejšnje različice posnetka in vrne manifest in označbo za trenutno različico; tako jih lahko pravilno povežete.
»Označba« je izraz v fast-import
, ki se nanaša na identifikator, ki ga daste potrditvi; vsakič, ko ustvarite potrditev, ji dodelite označbo, ki jo lahko uporabite za povezavo z drugimi potrditvami.
Torej, prva stvar, ki jo morate storiti v vaši metodi print_export
, je generirati označbo iz imena mape:
mark = convert_dir_to_mark(dir)
To boste naredili z ustvarjanjem polja direktorijev in uporabili vrednost indeksa kot označbo, saj mora biti označba celo število. Vaša metoda je videti takole:
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir) + 1).to_s
end
Zdaj, ko imate celoštevilsko predstavitev svoje potrditve, potrebujete datum za metapodatke potrditve.
Ker je datum izražen v imenu mape, ga boste razčlenili.
Naslednja vrstica v vaši datoteki print_export
je:
date = convert_dir_to_date(dir)
kjer je convert_dir_to_date
definiran kot:
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
To vrne celoštevilsko vrednost za podatke v vsakem direktoriju. Zadnji del metapodatkov, ki ga potrebujete za vsako potrditev, so podatki potrjevalca, ki ga vgradite v kodo preko globalne spremenljivke:
$author = 'John Doe <john@example.com>'
Zdaj ste pripravljeni za začetek izpisa podatkov o potrditvi za svoj program uvažanja. Začetni podatki navajajo, da opredeljujete objekt potrditve in na kateri veji je, nato sledi oznaka, ki ste jo generirali, podatki o potrditelju in sporočilu potrditve, nato pa še prejšnja potrditev, če obstaja. Koda je videti tako:
# print the import information
puts 'commit refs/heads/master'
puts 'mark :' + mark
puts "committer #{$author} #{date} -0700"
export_data('imported from ' + dir)
puts 'from :' + last_mark if last_mark
Časovni pas zacementirate v kodo (-0700), ker je to enostavno. Če uvažate iz drugega sistema, morate časovni pas določiti kot odmik. Sporočilo potrditve mora biti izraženo v posebnem formatu:
data (size)\n(contents)
Format sestoji iz podatka besede, velikosti podatkov, ki jih je treba prebrati, nove vrstice in nazadnje samih podatkov.
Ker morate kasneje uporabiti isti format za določanje vsebine datoteke, ustvarite pomožno metodo export_data
:
def export_data(string)
print "data #{string.size}\n#{string}"
end
Vse, kar je še ostalo, je določiti vsebino datoteke za vsak posnetek.
To je enostavno, saj imate vsak posnetek v mapi — lahko natisnete ukaz deleteall
, nato pa vsebino vsake datoteke v mapi.
Git bo nato ustrezno zabeležil vsak posnetek:
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
Opomba: Ker se mnogi sistemi nanašajo na svoje revizije kot spremembe med eno potrditvijo in drugo, lahko hitri uvoz vzame tudi ukaze z vsako potrditvijo, ki določajo, katere datoteke so bile dodane, odstranjene ali spremenjene ter kakšne so nove vsebine.
Lahko bi izračunali razlike med posnetki in zagotovili samo te podatke, vendar je to bolj zapleteno — raje dajte Gitu vse podatke in ga pustite, da sam ugotovi.
Če je to bolj primerno za vaše podatke, preverite stran priročnika fast-import
za podrobnosti o tem, kako zagotoviti svoje podatke na ta način.
Format za naštevanje novih vsebin datotek ali določanje spremenjene datoteke z novimi vsebinami je naslednji:
M 644 inline path/to/file
data (size)
(file contents)
Tukaj je način 644 (če imate izvršljive datoteke, morate zaznati in določiti namesto tega 755), in znotraj vrstice pove, da boste takoj po tej vrstici našteli vsebine.
Vaša metoda inline_data
je videti tako:
def inline_data(file, code = 'M', mode = '644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
Ponovno uporabljate metodo export_data
, ki ste jo prej definirali, ker je enaka načinu, kako ste določili podatke za sporočilo o potrditvi.
Zadnja stvar, ki jo morate storiti, je vrniti trenutno označbo, da jo lahko prenesete v naslednjo ponovitev:
return mark
Opomba
|
Če delujete v sistemu Windows, morate poskrbeti za dodaten korak.
Kot je bilo že omenjeno, sistem Windows uporablja znake CRLF za nove vrstice, medtem ko
|
To je vse. Tu je skript v svoji celoti:
#!/usr/bin/env ruby
$stdout.binmode
$author = "John Doe <john@example.com>"
$marks = []
def convert_dir_to_mark(dir)
if !$marks.include?(dir)
$marks << dir
end
($marks.index(dir)+1).to_s
end
def convert_dir_to_date(dir)
if dir == 'current'
return Time.now().to_i
else
dir = dir.gsub('back_', '')
(year, month, day) = dir.split('_')
return Time.local(year, month, day).to_i
end
end
def export_data(string)
print "data #{string.size}\n#{string}"
end
def inline_data(file, code='M', mode='644')
content = File.read(file)
puts "#{code} #{mode} inline #{file}"
export_data(content)
end
def print_export(dir, last_mark)
date = convert_dir_to_date(dir)
mark = convert_dir_to_mark(dir)
puts 'commit refs/heads/master'
puts "mark :#{mark}"
puts "committer #{$author} #{date} -0700"
export_data("imported from #{dir}")
puts "from :#{last_mark}" if last_mark
puts 'deleteall'
Dir.glob("**/*").each do |file|
next if !File.file?(file)
inline_data(file)
end
mark
end
# Loop through the directories
last_mark = nil
Dir.chdir(ARGV[0]) do
Dir.glob("*").each do |dir|
next if File.file?(dir)
# move into the target directory
Dir.chdir(dir) do
last_mark = print_export(dir, last_mark)
end
end
end
Če poženete ta skript, boste dobili vsebino, ki je videti nekako takole:
$ ruby import.rb /opt/import_from
commit refs/heads/master
mark :1
committer John Doe <john@example.com> 1388649600 -0700
data 29
imported from back_2014_01_02deleteall
M 644 inline README.md
data 28
# Hello
This is my readme.
commit refs/heads/master
mark :2
committer John Doe <john@example.com> 1388822400 -0700
data 29
imported from back_2014_01_04from :1
deleteall
M 644 inline main.rb
data 34
#!/bin/env ruby
puts "Hey there"
M 644 inline README.md
(...)
Za zagon uvoznika morate izhodno datoteko preusmeriti v git fast-import
, medtem ko ste v mapi Git, kamor želite uvoziti podatke.
Lahko ustvarite novo mapo in nato v njej začnete z git init
, nato pa zaženete svoj skript:
$ git init
Initialized empty Git repository in /opt/import_to/.git/
$ ruby import.rb /opt/import_from | git fast-import
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects: 5000
Total objects: 13 ( 6 duplicates )
blobs : 5 ( 4 duplicates 3 deltas of 5 attempts)
trees : 4 ( 1 duplicates 0 deltas of 4 attempts)
commits: 4 ( 1 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 1 ( 1 loads )
marks: 1024 ( 5 unique )
atoms: 2
Memory total: 2344 KiB
pools: 2110 KiB
objects: 234 KiB
---------------------------------------------------------------------
pack_report: getpagesize() = 4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 10
pack_report: pack_mmap_calls = 5
pack_report: pack_open_windows = 2 / 2
pack_report: pack_mapped = 1457 / 1457
---------------------------------------------------------------------
Kot vidite, vam po uspešnem zaključku poda cel kup statističnih podatkov o doseženem napredku.
V tem primeru ste skupaj uvozili 13 objektov za 4 potrditve v 1 vejo.
Sedaj lahko za ogled nove zgodovine zaženete git log
:
$ git log -2
commit 3caa046d4aac682a55867132ccdfbe0d3fdee498
Author: John Doe <john@example.com>
Date: Tue Jul 29 19:39:04 2014 -0700
imported from current
commit 4afc2b945d0d3c8cd00556fbe2e8224569dc9def
Author: John Doe <john@example.com>
Date: Mon Feb 3 01:00:00 2014 -0700
imported from back_2014_02_03
In to je to — lep in čist repozitorij Git.
Pomembno je opozoriti, da nič ni izvlečeno — na začetku nimate nobene datoteke v svoji delovni mapi.
Da bi jih dobili, morate ponastaviti svojo vejo na trenutno stanje veje master
:
$ ls
$ git reset --hard master
HEAD is now at 3caa046 imported from current
$ ls
README.md main.rb
Z orodjem fast-import
lahko storite veliko več — obvladovanje različnih načinov, binarnih podatkov, več vej in združevanje, oznak, kazalnikov napredka in še več.
V mapi contrib/fast-import
izvorne kode Git je na voljo več primerov bolj zapletenih scenarijev.