Skip to content

Latest commit

 

History

History
671 lines (552 loc) · 29.4 KB

File metadata and controls

671 lines (552 loc) · 29.4 KB

Git in Perforce

Perforce je zelo priljubljen sistem za nadzor različic v korporativnih okoljih. Obstaja že od leta 1995, kar ga uvršča med najstarejše sisteme, ki so obravnavani v tem poglavju. Zasnovan je bil z omejitvami njegovega časa; predpostavlja, da ste vedno povezani z enim samim osrednjim strežnikom in da je na lokalnem disku shranjena le ena različica. Njegove lastnosti in omejitve so zagotovo primerne za več specifičnih problemov, vendar obstaja veliko projektov, kjer bi Git dejansko deloval bolje kot Perforce.

Če želite kombinirati uporabo Perforce in Gita, imate na voljo dve možnosti. Prva, o kateri bomo govorili, je most »Git Fusion« izdelovalcev Perforce, ki vam omogoča izpostavljanje poddreves repozitorija Perforce kot bralno-pisalnega repozitorija Git. Druga možnost pa je git-p4, most na strani odjemalca, ki vam omogoča uporabo Gita kot odjemalca Perforce, brez potrebe po ponovni konfiguraciji strežnika Perforce.

Git Fusion

Perforce ponuja izdelek, imenovan Git Fusion (dostopen na https://www.perforce.com/manuals/git-fusion), ki sinhronizira strežnik Perforce z repozitoriji Git na strežniški strani.

Nastavitev

Za svoje primere bomo uporabili najlažjo namestitveno metodo Git Fusion in sicer prenos virtualne naprave, ki poganja prikriti proces Perforce in Git Fusion. Sliko virtualne naprave lahko dobite na https://www.perforce.com/downloads in ko se prenos konča, ga uvozite v svoj najljubši program za virtualizacijo (uporabili bomo VirtualBox).

Ob prvem zagonu naprave vas prosi, da prilagodite geslo za tri uporabnike v sistemu Linux (root, perforce in git) ter podate ime instance, ki se lahko uporabi za razlikovanje te namestitve od drugih v istem omrežju. Ko je vse to dokončano, boste videli to:

Zagonski zaslon virtualne naprave Git Fusion
Figure 1. Zagonski zaslon virtualne naprave Git Fusion

Zabeležiti si morate IP-naslov, ki je prikazan tukaj, saj ga bomo kasneje uporabili. Naslednji korak je ustvarjanje uporabnika Perforce. Izberite možnost »Login« na dnu in pritisnite enter (ali se povežite na napravo preko SSH) ter se prijavite kot root. Uporabite naslednje ukaze za ustvarjanje uporabnika:

$ p4 -p localhost:1666 -u super user -f john
$ p4 -p localhost:1666 -u john passwd
$ exit

Prvi ukaz bo odprl urejevalnik VI za prilagajanje uporabnika, vendar lahko sprejmete privzete vrednosti tako, da vpišete :wq in pritisnete enter. Drugi ukaz vas bo pozval, da dvakrat vnesete geslo. To je vse, kar morate narediti s pomočjo ukazne lupine, zato zapustite sejo.

Naslednje, kar morate storiti, da boste lahko sledili navodilom, je, da Gitu poveste, naj ne preverja certifikatov SSL. Slika Git Fusion ima certifikat, vendar je namenjen domeni, ki se ne ujema z IP-naslovom vaše virtualne naprave, zato Git zavrne povezavo HTTPS. Če bo to trajna namestitev, se obrnite na priročnik za Perforce Git Fusion, da namestite drugačen certifikat; za naš namen bo to zadostovalo:

$ export GIT_SSL_NO_VERIFY=true

Sedaj lahko stestiramo, če vse deluje.

$ git clone https://10.0.1.254/Talkhouse
Cloning into 'Talkhouse'...
Username for 'https://10.0.1.254': john
Password for 'https://[email protected]':
remote: Counting objects: 630, done.
remote: Compressing objects: 100% (581/581), done.
remote: Total 630 (delta 172), reused 0 (delta 0)
Receiving objects: 100% (630/630), 1.22 MiB | 0 bytes/s, done.
Resolving deltas: 100% (172/172), done.
Checking connectivity... done.

Slika virtualne naprave je opremljena s primerom projekta, ki ga lahko klonirate. Tukaj ga kloniramo prek HTTPS, z uporabnikom john, ki smo ga ustvarili zgoraj; Git vas bo zaprosil za poverilnice za to povezavo, vendar bo predpomnilnik poverilnic omogočil, da boste lahko preskočili ta korak za vsa nadaljnja zahtevanja.

Nastavitev Fusiona

Ko ste namestili Git Fusion, boste želeli prilagoditi konfiguracijo. To je dejansko precej enostavno storiti z vašim najljubšim odjemalcem Perforce; preprosto preslikajte imenik //.git-fusion na strežniku Perforce v svoj delovni prostor. Struktura datotek je videti tako:

$ tree
.
├── objects
│   ├── repos
│   │   └── [...]
│   └── trees
│       └── [...]

├── p4gf_config
├── repos
│   └── Talkhouse
│       └── p4gf_config
└── users
    └── p4gf_usermap

498 directories, 287 files

Imenik objects se interno uporablja v Git Fusion za preslikovanje objektov Perforce v Git in obratno; tam vam ne bo treba ničesar spreminjati. V tem imeniku je globalna datoteka p4gf_config, pa tudi ena za vsak repozitorij — to so konfiguracijske datoteke, ki določajo, kako se obnaša Git Fusion. Poglejmo si datoteko v korenskem imeniku:

[repo-creation]
charset = utf8

[git-to-perforce]
change-owner = author
enable-git-branch-creation = yes
enable-swarm-reviews = yes
enable-git-merge-commits = yes
enable-git-submodules = yes
preflight-commit = none
ignore-author-permissions = no
read-permission-check = none
git-merge-avoidance-after-change-num = 12107

[perforce-to-git]
http-url = none
ssh-url = none

[@features]
imports = False
chunked-push = False
matrix2 = False
parallel-push = False

[authentication]
email-case-sensitivity = no

Tu ne bomo razlagali pomena teh zastavic, vendar bodite pozorni, saj gre za besedilno datoteko oblikovano v formatu INI, podobno kakršno Git uporablja za konfiguracijo. Ta datoteka določa globalne možnosti, ki jih lahko nato preglasijo konfiguracijske datoteke specifične za posamezen repozitorij, kot je repos/Talkhouse/p4gf_config. Če odprete to datoteko, boste videli odsek [@repo] z nekaterimi nastavitvami, ki se razlikujejo od globalnih privzetih. Videli boste tudi odseke, ki so videti takole:

[Talkhouse-master]
git-branch-name = master
view = //depot/Talkhouse/main-dev/... ...

To je preslikava med vejami Perforce in vejami Git. Odsek se lahko imenuje poljubno, dokler je ime edinstveno. git-branch-name omogoča pretvorbo poti depoja (angl. depot) v bolj prijazno ime, saj bi bilo pod Gitom nerodno. Nastavitev view nadzoruje, kako so datoteke iz Perforce preslikane v repozitorij Git, pri čemer se uporablja standardna sintaksa preslikave pogledov. Določite lahko več preslikav kot v tem primeru:

[multi-project-mapping]
git-branch-name = master
view = //depot/project1/main/... project1/...
       //depot/project2/mainline/... project2/...

Tako lahko, če običajna preslikava delovnega prostora vključuje spremembe v strukturi map, to replicirate z repozitorijem Git.

Zadnja datoteka, o kateri bomo razpravljali, je users/p4gf_usermap, ki preslika uporabnike Perforce v uporabnike Git, in ki je morda sploh ne boste potrebovali. Pri pretvorbi iz nabora sprememb Perforce v potrditev Git, je privzeto obnašanje Git Fusiona, da poišče uporabnika Perforce in uporabi tam shranjen e-poštni naslov in polno ime za polje avtorja/potrjevalca v Gitu. Pri pretvorbi v drugo smer pa privzeto poišče uporabnika Perforce z e-poštnim naslovom, shranjenim v polju avtorja potrditve Git, in pošlje nabor sprememb kot tega uporabnika (s primernimi dovoljenji). V večini primerov bo ta način obnašanja povsem dovolj, vendar upoštevajte naslednjo preslikovalno datoteko:

john [email protected] "John Doe"
john [email protected] "John Doe"
bob [email protected] "Anon X. Mouse"
joe [email protected] "Anon Y. Mouse"

Vsaka vrstica je oblike <uporabnik> <e-pošta> "<polno ime>" in ustvari eno preslikavo uporabnika. Prvi dve vrstici preslikata dva različna e-poštna naslova v isti uporabniški račun Perforce. To je uporabno, če ste ustvarili potrditve Git pod več različnimi e-poštnimi naslovi (ali spremenili e-poštni naslov), vendar jih želite preslikati v istega uporabnika Perforce. Pri ustvarjanju potrditve Git iz nabora sprememb Perforce se prva vrstica, ki ustreza uporabniku Perforce, uporabi za informacije Git o avtorju.

Zadnji dve vrstici prikrijeta prava imena in e-poštne naslove Boba in Joeja iz potrditev Git, ki so ustvarjeni. To je koristno, če želite narediti izvorno kodo internega projekta odprtokodno, vendar ne želite objaviti svojega imenika zaposlenih celotnemu svetu. Upoštevajte, da morajo biti e-poštni naslovi in polna imena edinstveni, razen če želite, da se vse potrditve Git pripisujejo enemu fiktivnemu avtorju.

Potek dela

Perforce Git Fusion je dvosmerna povezava med nadzorom različic Perforce in Git. Poglejmo, kako se počutimo pri delu s strani Gita. Predpostavimo, da smo preslikali projekt »Jam« z uporabo konfiguracijske datoteke, kot je prikazano zgoraj, in ga lahko kloniramo na naslednji način:

$ git clone https://10.0.1.254/Jam
Cloning into 'Jam'...
Username for 'https://10.0.1.254': john
Password for 'https://[email protected]':
remote: Counting objects: 2070, done.
remote: Compressing objects: 100% (1704/1704), done.
Receiving objects: 100% (2070/2070), 1.21 MiB | 0 bytes/s, done.
remote: Total 2070 (delta 1242), reused 0 (delta 0)
Resolving deltas: 100% (1242/1242), done.
Checking connectivity... done.
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/rel2.1
$ git log --oneline --decorate --graph --all
* 0a38c33 (origin/rel2.1) Create Jam 2.1 release branch.
| * d254865 (HEAD, origin/master, origin/HEAD, master) Upgrade to latest metrowerks on Beos -- the Intel one.
| * bd2f54a Put in fix for jam's NT handle leak.
| * c0f29e7 Fix URL in a jam doc
| * cc644ac Radstone's lynx port.
[...]

Prvič, ko to storite, lahko traja nekaj časa. Kar se dogaja, je, da Git Fusion pretvarja vse ustrezne spremembe v zgodovini Perforce v potrditve Git. To se dogaja lokalno na strežniku, zato je relativno hitro, vendar če imate veliko zgodovine, lahko še vedno traja nekaj časa. Nadaljnje pridobitve izvajajo postopno pretvorbo, zato bo občutek bolj kot domača hitrost Gita.

Kot vidite, naš repozitorij je videti enako kot kateri koli drugi repozitorij Git, s katerim lahko delate. Obstajajo tri veje in Git je prijazno ustvaril lokalno vejo master, ki sledi origin/master. Naredimo nekaj dela in ustvarimo nekaj novih potrditev:

# ...
$ git log --oneline --decorate --graph --all
* cfd46ab (HEAD, master) Add documentation for new feature
* a730d77 Whitespace
* d254865 (origin/master, origin/HEAD) Upgrade to latest metrowerks on Beos -- the Intel one.
* bd2f54a Put in fix for jam's NT handle leak.
[...]

Sedaj imamo dve novi potrditvi. Sedaj preverimo, ali je delal še kdo:

$ git fetch
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From https://10.0.1.254/Jam
   d254865..6afeb15  master     -> origin/master
$ git log --oneline --decorate --graph --all
* 6afeb15 (origin/master, origin/HEAD) Update copyright
| * cfd46ab (HEAD, master) Add documentation for new feature
| * a730d77 Whitespace
|/
* d254865 Upgrade to latest metrowerks on Beos -- the Intel one.
* bd2f54a Put in fix for jam's NT handle leak.
[...]

Videti je, da nekdo je! S te perspektive tega ne bi vedeli, vendar je bila potrditev 6afeb15 ustvarjena z uporabo odjemalca Perforce. Za Git pa zgleda kot katerakoli druga potrditev, kar je pravzaprav cilj. Poglejmo, kako se strežnik Perforce spopade s potrditvijo združitve:

$ git merge origin/master
Auto-merging README
Merge made by the 'recursive' strategy.
 README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 9, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 917 bytes | 0 bytes/s, done.
Total 9 (delta 6), reused 0 (delta 0)
remote: Perforce: 100% (3/3) Loading commit tree into memory...
remote: Perforce: 100% (5/5) Finding child commits...
remote: Perforce: Running git fast-export...
remote: Perforce: 100% (3/3) Checking commits...
remote: Processing will continue even if connection is closed.
remote: Perforce: 100% (3/3) Copying changelists...
remote: Perforce: Submitting new Git commit objects to Perforce: 4
To https://10.0.1.254/Jam
   6afeb15..89cba2b  master -> master

Git misli, da je to delovalo. Poglejmo zgodovino datoteke README iz zornega kota Perforca z uporabo lastnosti revizijskega grafa p4v:

Revizijski graf Perforce, ki izhaja iz potiskanja Git
Figure 2. Revizijski graf Perforce, ki izhaja iz potiskanja Git

Če tega pogleda še niste videli, se vam lahko zdi zmeden, toda prikazuje iste zasnove kot grafični prikazovalnik zgodovine Gita. Gledamo zgodovino datoteke README, zato nam drevesna struktura v zgornjem levem kotu prikazuje samo to datoteko, ki se pojavlja v različnih vejah. Na zgornjem desnem delu imamo vizualni graf, kako so povezane različne različice datoteke, in celostni pogled na ta graf je na spodnjem desnem delu. Preostanek prikaza je namenjen podrobnostim za izbrano revizijo (v tem primeru 2).

Ena stvar, ki jo je treba opaziti, je, da se graf zdi povsem enak kot v Gitovi zgodovini. Perforce ni imel imenovane veje, kjer bi shranil potrditvi 1 in 2, zato je ustvaril vejo »anonymous« v imeniku .git-fusion. To se bo zgodilo tudi za imenovane veje Git, ki se ne ujemajo z imenovano vejo Perforce (kasneje pa jih lahko preslikate na vejo Perforce z uporabo konfiguracijske datoteke).

Večina tega se zgodi za zavesami, vendar končni rezultat je, da lahko ena oseba v ekipi uporablja Git, druga pa lahko Perforce in nobena izmed njiju bo vedela o izbiri drug drugega.

Povzetek Git-Fusion

Če imate (ali lahko dobite) dostop do vašega strežnika Perforce, je Git Fusion odličen način, da Git in Perforce komunicirata med seboj. Vključeno je malo konfiguracije, vendar krivulja učenja ni zelo strma. To je eden od redkih delov tega poglavja, kjer opozorila o uporabi celotne zmogljivosti Gita ne bodo navedena. To ne pomeni, da bo Perforce vesel vsega, kar boste poslali vanj — če poskušate preoblikovati zgodovino, ki je že bila poslana, jo bo Git Fusion zavrnil — toda Git Fusion se trudi, da bi bil občutek naraven. Lahko celo uporabite podmodule Git (čeprav bodo za uporabnike Perforce videti čudno) in združite veje (to bo zabeleženo kot integracija na strani Perforce).

Če ne morete prepričati administratorja svojega strežnika, da nastavi Git Fusion, še vedno obstaja način, kako ta orodja uporabiti skupaj.

Git-p4

Git-p4 je most med Gitom in Perforceom v dveh smereh. Deluje v celoti znotraj vašega repozitorija Git, zato ne boste potrebovali nobene vrste dostopa do strežnika Perforce (razen seveda uporabniških poverilnic). Git-p4 ni tako prilagodljiva ali popolna rešitev tako kot Git Fusion, vendar vam omogoča, da večino tega, kar bi radi storili, izvedete brez poseganja v okolje strežnika.

Note

Da boste lahko delali z git-p4, boste potrebovali orodje p4 nekje v vaši poti PATH. V času tega pisanja je prosto dostopno na https://www.perforce.com/downloads/helix-command-line-client-p4.

Nastavitev

Za namene primerov bomo zagnali strežnik Perforce iz Git Fusion OVA, kot je prikazano zgoraj, vendar bomo zaobšli strežnik Git Fusion in neposredno dostopali do nadzora različic Perforce.

Da bi lahko uporabljali ukazno vrstico p4 (odvisna je od git-p4), boste morali nastaviti nekaj okoljskih spremenljivk:

$ export P4PORT=10.0.1.254:1666
$ export P4USER=john
Kako začeti

Kot z vsem v Gitu je prvi ukaz kloniranje:

$ git p4 clone //depot/www/live www-shallow
Importing from //depot/www/live into www-shallow
Initialized empty Git repository in /private/tmp/www-shallow/.git/
Doing initial import of //depot/www/live/ from revision #head into refs/remotes/p4/master

To ustvari »površinski« (angl. shallow) klon v izrazoslovju Git; v Git uvozimo samo najnovejšo revizijo Perforce; spomnimo se, da Perforce ni zasnovan tako, da bi vsakemu uporabniku zagotovil vsako revizijo. To je dovolj za uporabo Gita kot odjemalca Perforce, vendar za druge namene ni dovolj.

Ko je postopek končan, imamo popolnoma funkcionalni repozitorij Git:

$ cd myproject
$ git log --oneline --all --graph --decorate
* 70eaf78 (HEAD, p4/master, p4/HEAD, master) Initial import of //depot/www/live/ from the state at revision #head

Opazite, da obstaja »p4« oddaljeno mesto za strežnik Perforce, vendar vse drugo je videti kot običajen klon. V resnici pa je to nekoliko zavajajoče; tam v resnici ni oddaljenega mesta.

$ git remote -v

V tem repozitoriju sploh ni oddaljenih mest. Git-p4 je ustvaril nekaj referenc, ki predstavljajo stanje strežnika, in so videti kot oddaljene reference v git log, vendar jih Git sam ne upravlja in nanje ne morete potiskati.

Potek dela

V redu, opravimo nekaj dela. Predpostavimo, da ste naredili nekaj napredka pri zelo pomembni funkciji in ste pripravljeni, da jo pokažete drugim v svoji ekipi.

$ git log --oneline --all --graph --decorate
* 018467c (HEAD, master) Change page title
* c0fb617 Update link
* 70eaf78 (p4/master, p4/HEAD) Initial import of //depot/www/live/ from the state at revision #head

Naredili smo dve novi potrditvi, ki ju želimo poslati na strežnik Perforce. Preverimo, ali je še kdo drug danes delal:

$ git p4 sync
git p4 sync
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
Import destination: refs/remotes/p4/master
Importing revision 12142 (100%)
$ git log --oneline --all --graph --decorate
* 75cd059 (p4/master, p4/HEAD) Update copyright
| * 018467c (HEAD, master) Change page title
| * c0fb617 Update link
|/
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #head

Videti je, da sta se različna razvoja master in p4/master razšla. Perforceov sistem razvejanja ni nič podoben Gitovemu, zato predložitev potrditev združitev nima smisla. Git-p4 priporoča, da pred predložitvijo ponovno bazirate svoje potrditve, za to pa ima celo pripravljeno bližnjico:

$ git p4 rebase
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
No changes to import!
Rebasing the current branch onto remotes/p4/master
First, rewinding head to replay your work on top of it...
Applying: Update link
Applying: Change page title
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Iz izhodnih sporočil lahko že razberete, vendar git p4 rebase pomeni bližnjico za git p4 sync, ki ji sledi git rebase p4/master. Je nekoliko pametnejše kot to, zlasti pri delu z več vejami, vendar je to dober približek.

Sedaj je naša zgodovina spet linearna in pripravljeni smo prispevati svoje spremembe nazaj v Perforce. Ukaz git p4 submit bo poskušal ustvariti novo revizijo Perforce za vsako potrditev Git med p4/master in master. Zagon ukaza nas spusti v naš najljubši urejevalnik, vsebina datoteke pa je nekaj podobnega temu:

# A Perforce Change Specification.
#
#  Change:      The change number. 'new' on a new changelist.
#  Date:        The date this specification was last modified.
#  Client:      The client on which the changelist was created.  Read-only.
#  User:        The user who created the changelist.
#  Status:      Either 'pending' or 'submitted'. Read-only.
#  Type:        Either 'public' or 'restricted'. Default is 'public'.
#  Description: Comments about the changelist.  Required.
#  Jobs:        What opened jobs are to be closed by this changelist.
#               You may delete jobs from this list.  (New changelists only.)
#  Files:       What opened files from the default changelist are to be added
#               to this changelist.  You may delete files from this list.
#               (New changelists only.)

Change:  new

Client:  john_bens-mbp_8487

User: john

Status:  new

Description:
   Update link

Files:
   //depot/www/live/index.html   # edit


######## git author [email protected] does not match your p4 account.
######## Use option --preserve-user to modify authorship.
######## Variable git-p4.skipUserNameCheck hides this message.
######## everything below this line is just the diff #######
--- //depot/www/live/index.html  2014-08-31 18:26:05.000000000 0000
+++ /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/index.html   2014-08-31 18:26:05.000000000 0000
@@ -60,7 +60,7 @@
 </td>
 <td valign=top>
 Source and documentation for
-<a href="http://www.perforce.com/jam/jam.html">
+<a href="jam.html">
 Jam/MR</a>,
 a software build tool.
 </td>

To bi bilo večinoma enako, kot bi videli, če bi zagnali p4 submit, razen zadnjega dela, ki ga je git-p4 prijazno vključil. Git-p4 poskuša upoštevati vaše nastavitve za Git in Perforce ločeno, kadar mora zagotoviti ime za potrditev ali nabor sprememb, vendar v nekaterih primerih želite to preglasiti. Na primer, če je bila potrditev Git, ki jo uvažate, napisana s strani sodelavca, ki nima uporabniškega računa Perforce, želite morda, da je videti, kot da so ga napisali oni (in ne vi).

Git-p4 je prijazno uvozil sporočilo iz potrditve Git kot vsebino tega nabora spremembe Perforce, zato moramo le shraniti in zapustiti, dvakrat (enkrat za vsako potrditev). Rezultat izhoda lupine bo nekaj takega:

$ git p4 submit
Perforce checkout for depot path //depot/www/live/ located at /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Synchronizing p4 checkout...
... - file(s) up-to-date.
Applying dbac45b Update link
//depot/www/live/index.html#4 - opened for edit
Change 12143 created with 1 open file(s).
Submitting change 12143.
Locking 1 files ...
edit //depot/www/live/index.html#5
Change 12143 submitted.
Applying 905ec6a Change page title
//depot/www/live/index.html#5 - opened for edit
Change 12144 created with 1 open file(s).
Submitting change 12144.
Locking 1 files ...
edit //depot/www/live/index.html#6
Change 12144 submitted.
All commits applied!
Performing incremental import into refs/remotes/p4/master git branch
Depot paths: //depot/www/live/
Import destination: refs/remotes/p4/master
Importing revision 12144 (100%)
Rebasing the current branch onto remotes/p4/master
First, rewinding head to replay your work on top of it...
$ git log --oneline --all --graph --decorate
* 775a46f (HEAD, p4/master, p4/HEAD, master) Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #head

Rezultat je tak, kot da bi pravkar izvedli git push, kar je najbližja analogija temu, kar se je dejansko zgodilo.

Upoštevajte, da se med tem postopkom vsaka potrditev Git pretvori v nabor sprememb Perforce; če jih želite stisniti v en sam nabor sprememb, to lahko storite s pomočjo interaktivnega zaslona ponovnega baziranja pred zagonom git p4 submit. Poleg tega bodite pozorni na to, da se zgoščene vrednosti SHA-1 vseh potrditev, ki so bile predložene kot nabori sprememb, spremenijo; to je zato, ker git-p4 dodaja vrstico na konec vsake pretvorjene potrditve:

$ git log -1
commit 775a46f630d8b46535fc9983cf3ebe6b9aa53145
Author: John Doe <[email protected]>
Date:   Sun Aug 31 10:31:44 2014 -0800

    Change page title

    [git-p4: depot-paths = "//depot/www/live/": change = 12144]

Kaj se zgodi, če poskusite poslati potrditev združitve? Poskusimo. Tu je situacija, v katero smo se vpletli:

$ git log --oneline --all --graph --decorate
* 3be6fd8 (HEAD, master) Correct email address
*   1dcbf21 Merge remote-tracking branch 'p4/master'
|\
| * c4689fc (p4/master, p4/HEAD) Grammar fix
* | cbacd0a Table borders: yes please
* | b4959b6 Trademark
|/
* 775a46f Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #head

Zgodovina Git in Perforce se začneta razhajati po potrditvi 775a46f. Na Gitovi strani imamo dve potrditvi, nato potrditev združitve z glavo Perforca in še eno potrditev. Poskusimo jih zdaj predložiti (angl. submit) na stran Perforce na vrh enega samega nabora spremembe. Poglejmo, kaj bi se zgodilo, če bi poskusili predložiti zdaj:

$ git p4 submit -n
Perforce checkout for depot path //depot/www/live/ located at /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Would synchronize p4 checkout in /Users/ben/john_bens-mbp_8487/john_bens-mbp_8487/depot/www/live/
Would apply
  b4959b6 Trademark
  cbacd0a Table borders: yes please
  3be6fd8 Correct email address

Zastavica -n je kratka oblika za --dry-run, ki poskusi poročati, kaj bi se zgodilo, če bi ukaz za predložitev dejansko tekel. V tem primeru se zdi, da bi ustvarili tri spremembe Perforce, ki se ujemajo s tremi potrditvami nezdružitev, ki še ne obstajajo na strežniku Perforce. To se zdi točno tisto, kar želimo, torej poglejmo, kako se izkaže:

$ git p4 submit
[…]
$ git log --oneline --all --graph --decorate
* dadbd89 (HEAD, p4/master, p4/HEAD, master) Correct email address
* 1b79a80 Table borders: yes please
* 0097235 Trademark
* c4689fc Grammar fix
* 775a46f Change page title
* 05f1ade Update link
* 75cd059 Update copyright
* 70eaf78 Initial import of //depot/www/live/ from the state at revision #head

Naša zgodovina je postala linearna, tako kot bi bilo po ponovnem baziranju pred predložitvijo (kar je dejansko tudi res). To pomeni, da lahko ustvarjate, delate, zavržete in združujete veje na strani Git, ne da bi se bali, da bo vaša zgodovina na kakršenkoli način postala nezdružljiva s Perforceom. Če lahko ponovno bazirate, lahko prispevate k strežniku Perforce.

Veje

Če ima vaš projekt v Perforcu več vej, imate srečo; git-p4 lahko to obdela na način, ki se zdi kot Git. Recimo, da je vaš depo (angl. depot) Perforce urejen takole:

//depot
  └── project
      ├── main
      └── dev

In recimo, da imate vejo dev, ki ima specifikacijo pogleda, ki je videti takole:

//depot/project/main/... //depot/project/dev/...

Git-p4 lahko samodejno zazna to situacijo in naredi pravo stvar:

$ git p4 clone --detect-branches //depot/project@all
Importing from //depot/project@all into project
Initialized empty Git repository in /private/tmp/project/.git/
Importing revision 20 (50%)
    Importing new branch project/dev

    Resuming with change 20
Importing revision 22 (100%)
Updated branches: main dev
$ cd project; git log --oneline --all --graph --decorate
* eae77ae (HEAD, p4/master, p4/HEAD, master) main
| * 10d55fb (p4/project/dev) dev
| * a43cfae Populate //depot/project/main/... //depot/project/dev/....
|/
* 2b83451 Project init

Opazite določevalec »@all« v poti depoja; to pove git-p4, naj ne klonira samo najnovejšega nabora sprememb za to poddrevo, temveč celoten nabor sprememb, ki so se kdaj koli dotaknile teh poti. To je bližje zasnovi kloniranja v Gitu, vendar lahko pri delu na projektu z dolgo zgodovino to traja nekaj časa.

Zastavica --detect-branches pove git-p4, naj uporabi specifikacije vej Perforce za preslikavo vej na reference Git. Če te preslikave niso prisotne na strežniku Perforce (kar je povsem veljaven način uporabe Perforce), lahko git-p4 pove, kaj so preslikave vej in dosežete enak rezultat:

$ git init project
Initialized empty Git repository in /tmp/project/.git/
$ cd project
$ git config git-p4.branchList main:dev
$ git clone --detect-branches //depot/project@all .

Nastavljanje konfiguracijske spremenljivke git-p4.branchList na main:dev pove git-p4, da sta main in dev obe veji in da je druga veja potomec prve.

Če zdaj naredimo git checkout -b dev p4/project/dev in naredimo nekaj potrditev, bo git-p4 dovolj pameten, da bo pravilno ciljal na pravo vejo, ko bomo izvedli git p4 submit. Na žalost git-p4 ne more mešati površinskih klonov in več vej; če imate ogromen projekt in želite delati na več kot eni veji, boste morali git p4 clone izvesti enkrat za vsako vejo, v katero želite predložiti.

Za ustvarjanje ali integracijo vej boste morali uporabiti odjemalca Perforce. Git-p4 lahko samo sinhronizira in predloži obstoječe veje in to lahko stori samo po eno linearno spremembo hkrati. Če združite dve veji v Git in poskušate predložiti novo zbirko sprememb, bo zabeleženo samo nekaj sprememb datotek; izgubljeni bodo metapodatki o tem, katere veje so vključene v integracijo.

Povzetek Gita in Perforca

Git-p4 omogoča uporabo poteka dela Git s strežnikom Perforce in je pri tem zelo učinkovit. Vendar pa je pomembno vedeti, da je Perforce odgovoren za vir in da uporabljate Git le lokalno. Bodite previdni pri deljenju potrditev Git; če imate oddaljeni repozitorij, ki ga uporabljajo druge osebe, ne potiskajte nobenih potrditev, ki še niso bile predložene na strežnik Perforce.

Če želite prosto mešati uporabo Perforce in Git kot odjemalcev za nadzor izvorne kode, in če lahko prepričate upravitelja strežnika, da ga namesti, lahko uporabite Git Fusion, ki omogoča uporabo Git kot odjemalca za strežnik Perforce.