-
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
9.1 Git and Other Systems - Git as a Client
The world isn’t perfect. Usually, you can’t immediately switch every project you come in contact with to Git. Sometimes you’re stuck on a project using another VCS, and wish it was Git. We’ll spend the first part of this chapter learning about ways to use Git as a client when the project you’re working on is hosted in a different system.
At some point, you may want to convert your existing project to Git. The second part of this chapter covers how to migrate your project into Git from several specific systems, as well as a method that will work if no pre-built import tool exists.
Git as a Client
Git provides such a nice experience for developers that many people have figured out how to use it on their workstation, even if the rest of their team is using an entirely different VCS. There are a number of these adapters, called “bridges,” available. Here we’ll cover the ones you’re most likely to run into in the wild.
Git en Subversion (Git and Subversion)
'n Groot fraksie van oopbron-ontwikkelingsprojekte en 'n goeie aantal korporatiewe projekte gebruik Subversion om hul bronkode te bestuur. Dit bestaan reeds vir meer as 'n dekade, en was vir die grootste deel van daardie tyd die de facto VCS-keuse vir oopbronprojekte. Dit is ook in baie opsigte baie soortgelyk aan CVS, wat voorheen die groot naam in die bronbeheerwêreld was.
Een van Git se wonderlike kenmerke is 'n tweerigtingbrug na Subversion genaamd git svn.
Hierdie hulpmiddel laat jou toe om Git as 'n geldige kliënt vir 'n Subversion-bediener te gebruik, sodat jy al die plaaslike kenmerke van Git kan gebruik en dan na 'n Subversion-bediener kan push asof jy Subversion plaaslik gebruik.
Dit beteken jy kan plaaslike takking en saamsmelting (branching and merging) doen, die voorbereidingsarea (staging area) gebruik, herbasering (rebasing) en cherry-picking gebruik, ensovoorts, terwyl jou medewerkers in hul donker en antieke maniere voortgaan om te werk.
Dit is 'n goeie manier om Git in die korporatiewe omgewing in te smokkel en jou mede-ontwikkelaars te help om doeltreffender te word terwyl jy lobby om die infrastruktuur te laat verander om Git ten volle te ondersteun.
Die Subversion-brug is die hekdwelm (gateway drug) na die DVCS-wêreld.
git svn
Die basisopdrag in Git vir al die Subversion-brugopdragte is git svn.
Dit neem 'n hele paar opdragte, so ons sal die algemeenste wys terwyl ons deur 'n paar eenvoudige werkvloeie gaan.
Dit is belangrik om op te let dat wanneer jy git svn gebruik, jy met Subversion wisselwerking het, wat 'n stelsel is wat baie anders as Git werk.
Alhoewel jy plaaslike takking en saamsmelting kan doen, is dit oor die algemeen die beste om jou geskiedenis so lineair as moontlik te hou deur jou werk te rebasen, en te vermy om dinge te doen soos om gelyktydig met 'n Git-remote te wisselwerking.
Moenie jou geskiedenis herskryf en probeer om weer te push nie, en moenie na 'n parallelle Git-bewaarplek push om terselfdertyd met mede-Git-ontwikkelaars saam te werk nie. Subversion kan slegs 'n enkele lineêre geskiedenis hê, en dit is baie maklik om dit te verwar. As jy met 'n span werk, en sommige gebruik SVN en ander gebruik Git, maak seker almal gebruik die SVN-bediener om saam te werk – dit sal jou lewe makliker maak.
Opstelling (Setting Up)
Om hierdie funksionaliteit te demonstreer, benodig jy 'n tipiese SVN-bewaarplek waartoe jy skryftoegang het.
As jy hierdie voorbeelde wil kopieer, sal jy 'n skryfbare kopie van 'n SVN-toetsbewaarplek moet maak.
Om dit maklik te doen, kan jy 'n hulpmiddel genaamd svnsync gebruik wat saam met Subversion kom.
Om te volg, moet jy eers 'n nuwe plaaslike Subversion-bewaarplek skep:
$ mkdir /tmp/test-svn
$ svnadmin create /tmp/test-svn
Stel dan al gebruikers in staat om revprops te verander – die maklike manier is om 'n pre-revprop-change skrip by te voeg wat altyd 0 uitstaan:
$ cat /tmp/test-svn/hooks/pre-revprop-change
#!/bin/sh
exit 0;
$ chmod +x /tmp/test-svn/hooks/pre-revprop-change
Jy kan nou hierdie projek na jou plaaslike masjien sinchroniseer deur svnsync init te roep met die na- en van-bewaarplekke.
$ svnsync init file:///tmp/test-svn \
http://your-svn-server.example.org/svn/
Dit stel die eienskappe op om die sinchronisasie te laat loop. Jy kan dan die kode kloon deur dit uit te voer:
$ svnsync sync file:///tmp/test-svn
Committed revision 1.
Copied properties for revision 1.
Transmitting file data .............................[...]
Committed revision 2.
Copied properties for revision 2.
[…]
Alhoewel hierdie operasie säl 'n paar minute kan neem, as jy probeer om die oorspronklike bewaarplek na 'n ander afgeleë bewaarplek te kopieer in plaas van 'n plaaslike een, sal die proses amper 'n uur neem, al is daar minder as 100 vasleggings. Subversion moet een hersiening op 'n slag kloon en dit dan terugpush in 'n ander bewaarplek – dit is belaglik ondoeltreffend, maar dit is die enigste maklike manier om dit te doen.
Om te Begin (Getting Started)
Noudat jy 'n Subversion-bewaarplek het waartoe jy skryftoegang het, kan jy deur 'n tipiese werkvloei gaan.
Jy sal begin met die git svn clone opdrag, wat 'n hele Subversion-bewaarplek in 'n plaaslike Git-bewaarplek inporteer.
Onthoud dat as jy van 'n egte gehoste Subversion-bewaarplek inporteer, jy die file:///tmp/test-svn hier moet vervang met die URL van jou Subversion-bewaarplek:
$ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags
Initialized empty Git repository in /private/tmp/progit/test-svn/.git/
r1 = dcbfb5891860124cc2e8cc616cded42624897125 (refs/remotes/origin/trunk)
A m4/acx_pthread.m4
A m4/stl_hash.m4
A java/src/test/java/com/google/protobuf/UnknownFieldSetTest.java
A java/src/test/java/com/google/protobuf/WireFormatTest.java
…
r75 = 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae (refs/remotes/origin/trunk)
Found possible branch point: file:///tmp/test-svn/trunk => file:///tmp/test-svn/branches/my-calc-branch, 75
Found branch parent: (refs/remotes/origin/my-calc-branch) 556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae
Following parent with do_switch
Successfully followed parent
r76 = 0fb585761df569eaecd8146c71e58d70147460a2 (refs/remotes/origin/my-calc-branch)
Checked out HEAD:
file:///tmp/test-svn/trunk r75
Dit voer die ekwivalent van twee opdragte uit – git svn init gevolg deur git svn fetch – op die URL wat jy verskaf.
Dit kan 'n rukkie neem.
As die toetsprojek byvoorbeeld net sowat 75 vasleggings het en die kodebasis nie so groot is nie, moet Git nog steeds elke weergawe uittrek, een op 'n slag, en dit individueel vaslê.
Vir 'n projek met honderde of duisende vasleggings kan dit letterlik ure of selfs dae neem om te voltooi.
Die -T trunk -b branches -t tags gedeelte sê vir Git dat hierdie Subversion-bewaarplek die basiese takking- en merkerkonvensies volg.
As jy jou trunk, branches of tags anders noem, kan jy hierdie opsies verander.
Omdat dit so algemeen is, kan jy hierdie hele gedeelte vervang met -s, wat standaarduitleg beteken en al daardie opsies impliseer.
Die volgende opdrag is ekwivalent:
$ git svn clone file:///tmp/test-svn -s
Op hierdie punt behoort jy 'n geldige Git-bewaarplek te hê wat jou takke en merkers geïmporteer het:
$ git branch -a
* master
remotes/origin/my-calc-branch
remotes/origin/tags/2.0.2
remotes/origin/tags/release-2.0.1
remotes/origin/tags/release-2.0.2
remotes/origin/tags/release-2.0.2rc1
remotes/origin/trunk
Let op hoe hierdie hulpmiddel Subversion-merkers as afgeleë verwysings (remote refs) bestuur.
Kom ons kyk van naderby met die Git-loodgietersopdrag show-ref:
$ git show-ref
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae refs/heads/master
0fb585761df569eaecd8146c71e58d70147460a2 refs/remotes/origin/my-calc-branch
bfd2d79303166789fc73af4046651a4b35c12f0b refs/remotes/origin/tags/2.0.2
285c2b2e36e467dd4d91c8e3c0c0e1750b3fe8ca refs/remotes/origin/tags/release-2.0.1
cbda99cb45d9abcb9793db1d4f70ae562a969f1e refs/remotes/origin/tags/release-2.0.2
a9f074aa89e826d6f9d30808ce5ae3ffe711feda refs/remotes/origin/tags/release-2.0.2rc1
556a3e1e7ad1fde0a32823fc7e4d046bcfd86dae refs/remotes/origin/trunk
Git doen dit nie wanneer dit van 'n Git-bediener kloon nie; hier is hoe 'n bewaarplek met merkers lyk na 'n vars kloon:
$ git show-ref
c3dcbe8488c6240392e8a5d7553bbffcb0f94ef0 refs/remotes/origin/master
32ef1d1c7cc8c603ab78416262cc421b80a8c2df refs/remotes/origin/branch-1
75f703a3580a9b81ead89fe1138e6da858c5ba18 refs/remotes/origin/branch-2
23f8588dde934e8f33c263c6d8359b2ae095f863 refs/tags/v0.1.0
7064938bd5e7ef47bfd79a685a62c1e2649e2ce7 refs/tags/v0.2.0
6dcb09b5b57875f334f61aebed695e2e4193db5e refs/tags/v1.0.0
Git fetch die merkers direk in refs/tags, eerder as om hulle as afgeleë takke te hanteer.
Vaslegging Terug na Subversion (Committing Back to Subversion)
Noudat jy 'n werkgids het, kan jy 'n bietjie werk aan die projek doen en jou vasleggings terug stroomop push, deur Git effektief as 'n SVN-kliënt te gebruik. As jy een van die lêers redigeer en dit vaslê, het jy 'n vaslegging wat plaaslik in Git bestaan wat nie op die Subversion-bediener bestaan nie:
$ git commit -am 'Adding git-svn instructions to the README'
[master 4af61fd] Adding git-svn instructions to the README
1 file changed, 5 insertions(+)
Volgende moet jy jou verandering stroomop push.
Merk op hoe dit die manier verander waarop jy met Subversion werk – jy kan verskeie vasleggings vanlyn doen en dit dan alles gelyktydig na die Subversion-bediener push.
Om na 'n Subversion-bediener te push, voer jy die git svn dcommit opdrag uit:
$ git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
M README.txt
Committed r77
M README.txt
r77 = 95e0222ba6399739834380eb10afcd73e0670bc5 (refs/remotes/origin/trunk)
No changes between 4af61fd05045e07598c553167e0f31c84fd6ffe1 and refs/remotes/origin/trunk
Resetting to the latest refs/remotes/origin/trunk
Dit neem al die vasleggings wat jy gemaak het bo-op die Subversion-bedienerkode, doen 'n Subversion-vaslegging vir elkeen, en herskryf dan jou plaaslike Git-vaslegging om 'n unieke identifiseerder in te sluit.
Dit is belangrik omdat dit beteken dat al die SHA-1 kontrolesomme vir jou vasleggings verander.
Gedeeltelik om hierdie rede is dit nie 'n goeie idee om gelyktydig met 'n Subversion-bediener aan Git-gebaseerde afgeleë weergawes van jou projekte te werk nie.
As jy na die laaste vaslegging kyk, kan jy die nuwe git-svn-id sien wat bygevoeg is:
$ git log -1
commit 95e0222ba6399739834380eb10afcd73e0670bc5
Author: ben <ben@0b684db3-b064-4277-89d1-21af03df0a68>
Date: Thu Jul 24 03:08:36 2014 +0000
Adding git-svn instructions to the README
git-svn-id: file:///tmp/test-svn/trunk@77 0b684db3-b064-4277-89d1-21af03df0a68
Let op dat die SHA-1 kontrolesom wat oorspronklik met 4af61fd begin het toe jy vasgelê het, nou met 95e0222 begin.
As jy na beide 'n Git-bediener en 'n Subversion-bediener wil push, moet jy eers na die Subversion-bediener push (dcommit), omdat daardie aksie jou vasleggingsdata verander.
Intrek van Nuwe Veranderings (Pulling in New Changes)
As jy saam met ander ontwikkelaars werk, sal een van julle op 'n stadium push, en dan sal die ander een probeer om 'n verandering te push wat konstrasteer (konflik).
Daardie verandering sal geweiger word tensy jy hul werk insmelt.
In git svn lyk dit soos dit:
$ git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
ERROR from SVN:
Transaction is out of date: File '/trunk/README.txt' is out of date
W: d5837c4b461b7c0e018b49d12398769d2bfc240a and refs/remotes/origin/trunk differ, using rebase:
:100644 100644 f414c433af0fd6734428cf9d2a9fd8ba00ada145 c80b6127dd04f5fcda218730ddf3a2da4eb39138 M README.txt
Current branch master is up to date.
ERROR: Not all changes have been committed into SVN, however the committed
ones (if any) seem to be successfully integrated into the working tree.
Please see the above messages for details.
Om hierdie situasie op te los, kan jy git svn rebase uitvoer, wat enige veranderings op die bediener aftrek wat jy nog nie het nie en enige werk wat jy het rebase bo-op dit wat op die bediener is:
$ git svn rebase
Committing to file:///tmp/test-svn/trunk ...
ERROR from SVN:
Transaction is out of date: File '/trunk/README.txt' is out of date
W: eaa029d99f87c5c822c5c29039d19111ff32ef46 and refs/remotes/origin/trunk differ, using rebase:
:100644 100644 65536c6e30d263495c17d781962cfff12422693a b34372b25ccf4945fe5658fa381b075045e7702a M README.txt
First, rewinding head to replay your work on top of it...
Applying: update foo
Using index info to reconstruct a base tree...
M README.txt
Falling back to patching base and 3-way merge...
Auto-merging README.txt
ERROR: Not all changes have been committed into SVN, however the committed
ones (if any) seem to be successfully integrated into the working tree.
Please see the above messages for details.
Nou is al jou werk bo-op dit wat op die Subversion-bediener is, sodat jy suksesvol dcommit kan doen:
$ git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
M README.txt
Committed r85
M README.txt
r85 = 9c29704cc0bbbed7bd58160cfb66cb9191835cd8 (refs/remotes/origin/trunk)
No changes between 5762f56732a958d6cfda681b661d2a239cc53ef5 and refs/remotes/origin/trunk
Resetting to the latest refs/remotes/origin/trunk
Let daarop dat in teenstelling met Git, wat vereis dat jy stroomopwaartse werk wat jy nog nie plaaslik het nie, moet insmelt voordat jy kan push, dwing git svn jou om dit slegs te doen as die veranderings konflik (baie soos hoe Subversion werk).
As iemand anders 'n verandering aan een lêer push en jy dan 'n verandering aan 'n ander lêer push, sal jou git svn dcommit goed werk:
$ git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
M configure.ac
Committed r87
M autogen.sh
r86 = d8450bab8a77228a644b7dc0e95977ffc61adff7 (refs/remotes/origin/trunk)
M configure.ac
r87 = f3653ea40cb4e26b6281cec102e35dcba1fe17c4 (refs/remotes/origin/trunk)
W: a0253d06732169107aa020390d9fefd2b1d92806 and refs/remotes/origin/trunk differ, using rebase:
:100755 100755 efa5a59965fbbb5b2b0a12890f1b351bb5493c18 e757b59a9439312d80d5d43bb65d4a7d0389ed6d M autogen.sh
First, rewinding head to replay your work on top of it...
Dit is belangrik om te onthou, aangesien die uitkoms 'n projektoestand is wat nie op enige van julle rekenaars bestaan het toe julle gepush het nie. As die veranderings onversoenbaar is maar nie konflik maak nie, kan jy kwessies kry wat moeilik is om te gagnostiseer. Dit verskil van die gebruik van 'n Git-bediener – in Git kan jy die toestand op jou kliëntstelsel ten volle toets voordat jy dit publiseer, terwyl jy in SVN nooit seker kan wees dat die toestande onmiddellik voor vaslegging en na vaslegging identies is nie.
Jy moet ook hierdie opdrag uitvoer om veranderings van die Subversion-bediener in te trek, selfs al is jy nie gereed om self vas te lê nie.
Jy kan git svn fetch uitvoer om die nuwe data te gryp, maar git svn rebase doen die fetch en werk dan jou plaaslike vasleggings op.
$ git svn rebase
M autogen.sh
r88 = c9c5f83c64bd755368784b444bc7a0216cc1e17b (refs/remotes/origin/trunk)
First, rewinding head to replay your work on top of it...
Fast-forwarded master to refs/remotes/origin/trunk.
Om git svn rebase kort-kort uit te voer, maak seker dat jou kode altyd op datum is.
Jy moet egter seker wees dat jou werkgids skoon is wanneer jy dit uitvoer.
As jy plaaslike veranderings het, moet jy óf jou werk bêre (stash) óf dit tydelik vaslê voordat jy git svn rebase uitvoer – anders sal die opdrag stop as dit sien dat die rebase in 'n saamsmeltingskonflik sal aanhits.
Git-Takkingkwessies (Git Branching Issues)
Wanneer jy gemaklik geraak het met 'n Git-werkvloei, sal jy waarskynlik onderwerptakke (topic branches) skep, werk daaraan doen, en dit dan insmelt.
As jy na 'n Subversion-bediener push via git svn, wil jy dalk eerder jou werk op 'n enkele tak rebase elke keer in plaas daarvan om takke saam te smelt.
Die rede om herbasering (rebasing) te verkies, is dat Subversion 'n lineêre geskiedenis het en nie met saamsmeltings omgaan soos Git dit doen nie, so git svn volg slegs die eerste ouer wanneer die momentopnames in Subversion-vasleggings omgeskakel word.
Veronderstel jou geskiedenis lyk soos die volgende: jy het 'n experiment tak geskep, twee vasleggings gedoen, en dit toe terug in master gesmelt.
Wanneer jy dcommit, sien jy afvoer soos dit:
$ git svn dcommit
Committing to file:///tmp/test-svn/trunk ...
M CHANGES.txt
Committed r89
M CHANGES.txt
r89 = 89d492c884ea7c834353563d5d913c6adf933981 (refs/remotes/origin/trunk)
M COPYING.txt
M INSTALL.txt
Committed r90
M INSTALL.txt
M COPYING.txt
r90 = cb522197870e61467473391799148f6721bcf9a0 (refs/remotes/origin/trunk)
No changes between 71af502c214ba13123992338569f4669877f55fd and refs/remotes/origin/trunk
Resetting to the latest refs/remotes/origin/trunk
Die uitvoering van dcommit op 'n tak met gesmelte geskiedenis werk goed, behalwe dat wanneer jy na jou Git-projekgeskiedenis kyk, dit geen van die vasleggings wat jy op die experiment tak gemaak het, herskryf het nie – in plaas daarvan verskyn al daardie veranderings in die SVN-weergawe van die enkele saamsmeltingsvaslegging.
Wanneer iemand anders daardie werk kloon, sien al wat hulle sien die saamsmeltingsvaslegging met al die werk daarin saamgepers (squashed), asof jy git_merge --squash uitgevoer het; hulle sien nie die vasleggingsdata oor waar dit vandaan kom of wanneer dit vasgelê is nie.
Subversion-Takking (Subversion Branching)
Takking in Subversion is nie dieselfde as takking in Git nie; as jy kan vermy om dit veel te gebruik, is dit waarskynlik die beste.
Jy kan egter takke in Subversion skep en daaraan vaslê met git svn.
Skep van 'n Nuwe SVN-tak (Creating a New SVN Branch)
Om 'n nuwe tak in Subversion te skep, voer jy git svn branch [new-branch] uit:
$ git svn branch opera
Copying file:///tmp/test-svn/trunk at r90 to file:///tmp/test-svn/branches/opera...
Found possible branch point: file:///tmp/test-svn/trunk => file:///tmp/test-svn/branches/opera, 90
Found branch parent: (refs/remotes/origin/opera) cb522197870e61467473391799148f6721bcf9a0
Following parent with do_switch
Successfully followed parent
r91 = f1b64a3855d3c8dd84ee0ef10fa89d27f1584302 (refs/remotes/origin/opera)
Dit doen die ekwivalent van die svn copy trunk branches/opera opdrag in Subversion en werk op die Subversion-bediener.
Dit is belangrik om op te let dat dit jou nie uittrek in daardie tak nie; as jy op hierdie punt vaslê, sal daardie vaslegging na trunk op die bediener gaan, nie opera nie.
Wisseling van Aktiewe Takke (Switching Active Branches)
Git vind uit na watter tak jou dcommits gaan deur te soek na die punt van enige van jou Subversion-takke in jou geskiedenis – jy behoort slegs een te hê, en dit behoort die laaste een te wees met 'n git-svn-id in jou huidige takgeskiedenis.
As jy aan meer as een tak gelyktydig wil werk, kan jy plaaslike takke opstel om na spesifieke Subversion-takke te dcommit deur hulle te begin by die geïmporteerde Subversion-vaslegging vir daardie tak.
As jy 'n opera tak wil hê waarop jy afsonderlik kan werk, kan jy uitvoer:
$ git branch opera remotes/origin/opera
Nou, as jy jou opera tak in trunk (jou master tak) wil insmelt, kan jy dit doen met 'n normale git merge.
Maar jy moet 'n beskrywende vasleggingsboodskap verskaf (via -m), anders sal die saamsmelting sê “Merge branch opera” in plaas van iets nuttigs.
Onthoud dat al gebruik jy git merge om hierdie bewerking te doen, en die saamsmelting sal waarskynlik baie makliker wees as wat dit in Subversion sou wees (omdat Git outomaties die gepaste saamsmeltingsbasis vir jou sal detekteer), is dit nie 'n normale Git-saamsmeltingsvaslegging nie.
Jy moet hierdie data terugpush na 'n Subversion-bediener wat nie 'n vaslegging kan hanteer wat meer as een ouer naspoor nie; dus, nadat jy dit opgestoot het, sal dit lyk soos 'n enkele vaslegging wat al die werk van 'n ander tak onder 'n enkele vaslegging saamgepers het.
Nadat jy een tak in 'n ander gesmelt het, kan jy nie maklik teruggaan en aan daardie tak voortgaan te werk soos jy normaalweg in Git kan nie.
Die dcommit opdrag wat jy uitvoer, vee enige inligting uit wat sê watter tak ingesmelt is, so daaropvolgende saamsmeltingsbasis-berekeninge sal verkeerd wees – die dcommit laat jou git merge resultaat lyk asof jy git merge --squash uitgevoer het.
Ongelukkig is daar geen goeie manier om hierdie situasie te vermy nie – Subversion kan nie hierdie inligting stoor nie, so jy sal altyd gekortwiek word deur sy beperkings terwyl jy dit as jou bediener gebruik.
Om kwessies te vermy, moet jy die plaaslike tak (in hierdie geval, opera) verwyder nadat jy dit in trunk ingesmelt het.
Subversion-opdragte (Subversion Commands)
Die git svn hulpmiddelset bied 'n aantal opdragte om die oorgang na Git te vergemaklik deur sekere funksionaliteit te verskaf wat soortgelyk is aan wat jy in Subversion gehad het.
Hier is 'n paar opdragte wat jou gee wat Subversion gewoond was om te verskaf.
SVN-styl Geskiedenis (SVN Style History)
As jy gewoond is aan Subversion en jou geskiedenis in SVN-afvoerstyl wil sien, kan jy git svn log uitvoer om jou vasleggingsgeskiedenis in SVN-formatering te besigtig:
$ git svn log
------------------------------------------------------------------------
r87 | schacon | 2014-05-02 16:07:37 -0700 (Sat, 02 May 2014) | 2 lines
autogen change
------------------------------------------------------------------------
r86 | schacon | 2014-05-02 16:00:21 -0700 (Sat, 02 May 2014) | 2 lines
Merge branch 'experiment'
------------------------------------------------------------------------
r85 | schacon | 2014-05-02 16:00:09 -0700 (Sat, 02 May 2014) | 2 lines
updated the changelog
Jy moet twee belangrike dinge weet oor git svn log.
Eerstens werk dit vanlyn, in teenstelling met die egte svn log opdrag, wat die Subversion-bediener vir die data vra.
Tweedens wys dit jou slegs vasleggings wat tot op die Subversion-bediener vasgelê is.
Plaaslike Git-vasleggings wat jy nie gedcommit het nie, wys nie op nie; ook nie vasleggings wat mense intussen op die Subversion-bediener gemaak het nie.
Dit lyk meer soos die laaste bekende toestand van die vasleggings op die Subversion-bediener.
SVN-annotasie (SVN Annotation)
Net soos die git svn log opdrag die svn log opdrag vanlyn simuleer, kan jy die ekwivalent van svn annotate kry deur git svn blame [FILE] uit te voer.
Die afvoer lyk soos dit:
$ git svn blame README.txt
2 temporal Protocol Buffers - Google's data interchange format
2 temporal Copyright 2008 Google Inc.
2 temporal http://code.google.com/apis/protocolbuffers/
2 temporal
22 temporal C++ Installation - Unix
22 temporal =======================
2 temporal
79 schacon Committing in git-svn.
78 schacon
2 temporal To build and install the C++ Protocol Buffer runtime and the Protocol
2 temporal Buffer compiler (protoc) execute the following:
2 temporal
Weereens wys dit nie vasleggings wat jy plaaslik in Git gedoen het of wat intussen na Subversion gepush is nie.
SVN-bedienerinligting (SVN Server Information)
Jy kan ook dieselfde tipe inligting kry wat svn info vir jou gee deur git svn info uit te voer:
$ git svn info
Path: .
URL: https://schacon-test.googlecode.com/svn/trunk
Repository Root: https://schacon-test.googlecode.com/svn
Repository UUID: 4c93b258-373f-11de-be05-5f7a86268029
Revision: 87
Node Kind: directory
Schedule: normal
Last Changed Author: schacon
Last Changed Rev: 87
Last Changed Date: 2009-05-02 16:07:37 -0700 (Sat, 02 May 2009)
Dit is soos blame en log in dié opsig dat dit vanlyn loop en slegs op datum is sedert die laaste keer dat jy met die Subversion-bediener gekommunikeer het.
Negeer Wat Subversion Negeer (Ignoring What Subversion Ignores)
As jy 'n Subversion-bewaarplek kloon wat svn:ignore eienskappe iewers gestel het, sal jy waarskynlik ooreenstemmende .gitignore lêers wil stel sodat jy nie per ongeluk lêers vaslê wat jy nie moet nie.
git svn het twee opdragte om met hierdie kwessie te help.
Die eerste is git svn create-ignore, wat outomaties ooreenstemmende .gitignore lêers vir jou skep sodat jou volgende vaslegging dit kan insluit.
Die tweede opdrag is git svn show-ignore, wat die reëls wat jy in 'n .gitignore lêer moet plaas na stdout druk sodat jy die afvoer in jou projek se uitsluitingslêer (exclude file) kan herlei:
$ git svn show-ignore > .git/info/exclude
Op daardie manier bemors jy nie die projek met .gitignore lêers nie.
Dit is 'n goeie opsie as jy die enigste Git-gebruiker op 'n Subversion-span is, en jou spanmaats nie .gitignore lêers in die projek wil hê nie.
Git-Svn Opsomming (Git-Svn Summary)
Die git svn hulpmiddels is nuttig as jy vas sit met 'n Subversion-bediener, of andersins in 'n ontwikkelingsomgewing is wat die uitvoering van 'n Subversion-bediener noodsaak.
Jy moet dit egter as 'n gekortwiekte Git beskou, anders sal jy kwessies in vertaling teëkom wat jou en jou medewerkers kan verwar.
Om uit die moeilikheid te bly, probeer om hierdie riglyne te volg:
-
Hou 'n lineêre Git-geskiedenis aan wat nie saamsmeltingsvasleggings (merge commits) bevat wat deur
git mergegemaak is nie. Rebase enige werk wat jy buite jou hooflyn-tak doen, terug daarop; moenie dit insmelt nie. -
Moenie 'n aparte Git-bediener opstel en daaraan saamwerk nie. Hê moontlik een om klone vir nuwe ontwikkelaars te versnel, maar moenie enigiets daarna push wat nie 'n
git-svn-idinskrywing het nie. Jy wil dalk selfs 'npre-receivehaak byvoeg wat elke vasleggingsboodskap kontroleer vir 'ngit-svn-iden pushes verwerp wat vasleggings sonder dit bevat.
As jy daardie riglyne volg, kan die werk met 'n Subversion-bediener meer draaglik wees. As dit egter moontlik is om na 'n egte Git-bediener te skuif, kan dit jou span veel meer besorg.
Git en Mercurial (Git and Mercurial)
Die DVCS-heelal is groter as net Git. Om die waarheid te sê, daar is baie ander stelsels in hierdie ruimte, elk met hul eie hoek benadering oor hoe om gedistribueerde weergawebeheer korrek te doen. Buiten Git is Mercurial die gewildste, en die twee is in baie opsigte baie soortgelyk.
Die goeie nuus, as jy Git se kliëntkant-gedrag verkies maar met 'n projek werk waarvan die bronkode met Mercurial beheer word, is dat daar 'n manier is om Git as 'n kliënt te gebruik vir 'n bewaarplek wat deur Mercurial gehuisves word.
Aangesien die manier waarop Git met bedienerbewaarplekke praat deur remotes is, behoort dit geen verrassing te wees nie dat hierdie brug as 'n afgeleë helper (remote helper) geïmplementeer word.
Die projek se naam is git-remote-hg, en dit kan gevind word by https://github.com/felipec/git-remote-hg.
git-remote-hg
Eerstens moet jy git-remote-hg installeer.
Dit behels basies om sy lêer iewers in jou pad te plaas, soos dit:
$ curl -o ~/bin/git-remote-hg \
https://raw.githubusercontent.com/felipec/git-remote-hg/master/git-remote-hg
$ chmod +x ~/bin/git-remote-hg
…aannemende dat ~/bin in jou $PATH is.
git-remote-hg het een ander afhanklikheid: die mercurial biblioteek vir Python.
As jy Python geïnstalleer het, is dit so eenvoudig as:
$ pip install mercurial
As jy nie Python geïnstalleer het nie, besoek https://www.python.org/ en kry dit eers.
Die laaste ding wat jy nodig het, is die Mercurial-kliënt. Gaan na https://www.mercurial-scm.org/ en installeer dit as jy dit nie reeds gedoen het nie.
Nou is jy gereed om te begin. Al wat jy nodig het, is 'n Mercurial-bewaarplek waarna jy kan push. Gelukkig kan elke Mercurial-bewaarplek op hierdie manier optree, so ons sal net die "hello world" bewaarplek gebruik wat almal gebruik om Mercurial te leer:
$ hg clone http://selenic.com/repo/hello /tmp/hello
Om te Begin (Getting Started)
Noudat ons 'n geskikte “bedienerkant”-bewaarplek het, kan ons deur 'n tipiese werkvloei gaan. Soos jy sal sien, is hierdie twee stelsels soortgelyk genoeg dat daar nie baie wrywing is nie.
Soos altyd met Git, kloon ons eerste:
$ git clone hg::/tmp/hello /tmp/hello-git
$ cd /tmp/hello-git
$ git log --oneline --graph --decorate
* ac7955c (HEAD, origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master, master) Create a makefile
* 65bb417 Create a standard 'hello, world' program
Jy sal opmerk dat die werk met 'n Mercurial-bewaarplek die standaard git clone opdrag gebruik.
Dit is omdat git-remote-hg op 'n taamlik lae vlak werk, deur gebruik te maak van 'n meganisme wat soortgelyk is aan hoe Git se HTTP/S-protokol geïmplementeer word (remote helpers).
Aangesien Git en Mercurial beide ontwerp is sodat elke kliënt 'n volledige kopie van die bewaarplekgeskiedenis het, maak hierdie opdrag 'n volledige kloon, insluitend al die projek se geskiedenis, en doen dit redelik vinnig.
Die log opdrag wys twee vasleggings, waarvan die laaste aangewys word deur 'n hele tros verwysings (refs).
Dit blyk dat sommige van hierdie nie werklik daar is nie.
Kom ons kyk na wat eintlik in die .git gids is:
$ tree .git/refs
.git/refs
├── heads
│ └── master
├── hg
│ └── origin
│ ├── bookmarks
│ │ └── master
│ └── branches
│ └── default
├── notes
│ └── hg
├── remotes
│ └── origin
│ └── HEAD
└── tags
9 directories, 5 files
git-remote-hg probeer dinge meer idiomaties Git-agtig maak, maar onder die enjinkap bestuur dit die konseptuele kartering tussen twee effens verskillende stelsels.
Die refs/hg gids is waar die werklike afgeleë verwysings gestoor word.
Byvoorbeeld, die refs/hg/origin/branches/default is 'n Git-verwysingslêer wat die SHA-1 bevat wat begin met “ac7955c”, wat die vaslegging is waarna master wys.
Dus is die refs/hg gids 'n bietjie soos 'n vals refs/remotes/origin, maar dit het die bykomende onderskeid tussen boekmerke (bookmarks) en takke (branches).
Die notes/hg lêer is die beginpunt vir hoe git-remote-hg Git-vasleggingshuts (commit hashes) aan Mercurial-wysigingstel-ID’s (changeset IDs) karteer.
Kom ons verken 'n bietjie:
$ cat notes/hg
d4c10386...
$ git cat-file -p d4c10386...
tree 1781c96...
author remote-hg <> 1408066400 -0800
committer remote-hg <> 1408066400 -0800
Notes for master
$ git ls-tree 1781c96...
100644 blob ac9117f... 65bb417...
100644 blob 485e178... ac7955c...
$ git cat-file -p ac9117f
0a04b987be5ae354b710cefeba0e2d9de7ad41a9
Dus wys refs/notes/hg na 'n boom (tree), wat in die Git-objekdatabasis 'n lys is van ander objekte met name.
git ls-tree voer die modus, tipe, objekhuts en lêernaam uit vir items binne 'n boom.
Sodra ons afgrawe na een van die boomitems, vind ons dat binne-in dit 'n blob is genaamd “ac9117f” (die SHA-1 huts van die vaslegging waarna master wys), met inhoud “0a04b98” (wat die ID is van die Mercurial-wysigingstel aan die punt van die default tak).
Die goeie nuus is dat ons meestal nie hoef te bekommer oor al hierdie dinge nie. Die tipiese werkvloei sal nie baie verskil van die werk met 'n Git-remote nie.
Daar is een ding waaraan ons aandag moet gee voordat ons voortgaan: ignores.
Mercurial en Git gebruik 'n baie soortgelyke meganisme hiervoor, maar dit is waarskynlik dat jy nie werklik 'n .gitignore lêer in 'n Mercurial-bewaarplek wil vaslê nie.
Gelukkig het Git 'n manier om lêers te ignoreer wat plaaslik is vir 'n bewaarplek op die skyf, en die Mercurial-formaat is versoenbaar met Git, so jy hoef dit net oór te kopieer:
$ cp .hgignore .git/info/exclude
Die .git/info/exclude lêer tree presies soos 'n .gitignore op, maar word nie in vasleggings ingesluit nie.
Werkvloei (Workflow)
Kom ons aanvaar dat ons 'n bietjie werk gedoen het en 'n paar vasleggings op die master tak gemaak het, en jy is gereed om dit na die afgeleë bewaarplek te push.
Hier is hoe ons bewaarplek op die oomblik lyk:
$ git log --oneline --graph --decorate
* ba04a2a (HEAD, master) Update makefile
* d25d16f Goodbye
* ac7955c (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Create a makefile
* 65bb417 Create a standard 'hello, world' program
Ons master tak is twee vasleggings voor op origin/master, maar daardie twee vasleggings bestaan slegs op ons plaaslike masjien.
Kom ons kyk of iemand anders terselfdertyd belangrike werk gedoen het:
$ git fetch
From hg::/tmp/hello
ac7955c..df85e87 master -> origin/master
ac7955c..df85e87 branches/default -> origin/branches/default
$ git log --oneline --graph --decorate --all
* 7b07969 (refs/notes/hg) Notes for default
* d4c1038 Notes for master
* df85e87 (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Add some documentation
| * ba04a2a (HEAD, master) Update makefile
| * d25d16f Goodbye
|/
* ac7955c Create a makefile
* 65bb417 Create a standard 'hello, world' program
Aangesien ons die --all vlag gebruik het, sien ons die “notes” verwysings wat intern deur git-remote-hg gebruik word, maar ons kan hulle ignoreer.
Die res is wat ons verwag het; origin/master het met een vaslegging gevorder, en ons geskiedenis het nou uiteengegaan.
In teenstelling met die ander stelsels waarmee ons in hierdie hoofstuk werk, is Mercurial in staat om saamsmeltings (merges) te hanteer, so ons gaan niks fancy doen nie.
$ git merge origin/master
Auto-merging hello.c
Merge made by the 'recursive' strategy.
hello.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline --graph --decorate
* 0c64627 (HEAD, master) Merge remote-tracking branch 'origin/master'
|\
| * df85e87 (origin/master, origin/branches/default, origin/HEAD, refs/hg/origin/branches/default, refs/hg/origin/bookmarks/master) Add some documentation
* | ba04a2a Update makefile
* | d25d16f Goodbye
|/
* ac7955c Create a makefile
* 65bb417 Create a standard 'hello, world' program
Perfek. Ons laat die toetse loop en alles slaag, so ons is gereed om ons werk met die res van die span te deel:
$ git push
To hg::/tmp/hello
df85e87..0c64627 master -> master
Dis dit! As jy 'n kykie neem na die Mercurial-bewaarplek, sal jy sien dat dit gedoen het wat ons sou verwag:
$ hg log -G --style compact
o 5[tip]:4,2 dc8fa4f932b8 2014-08-14 19:33 -0700 ben
|\ Merge remote-tracking branch 'origin/master'
| |
| o 4 64f27bcefc35 2014-08-14 19:27 -0700 ben
| | Update makefile
| |
| o 3:1 4256fc29598f 2014-08-14 19:27 -0700 ben
| | Goodbye
| |
@ | 2 7db0b4848b3c 2014-08-14 19:30 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard 'hello, world' program
Die wysigingstel genommer 2 is deur Mercurial gemaak, en die wysigingstelle genommer 3 en 4 is deur git-remote-hg gemaak deur vasleggings te push wat met Git gemaak is.
Takke en Boekmerke (Branches and Bookmarks)
Git het slegs een tipe tak: 'n verwysing wat skuif wanneer vasleggings gemaak word. In Mercurial word hierdie tipe verwysing 'n “boekmerke” ("bookmark") genoem, en dit tree op baie dieselfde manier op as 'n Git-tak.
Mercurial se konsep van 'n “tak” ("branch") is swaarder.
Die tak waarop 'n wysigingstel gemaak word, word met die wysigingstel opgeteken, wat beteken dit sal altyd in die bewaarplekgeskiedenis wees.
Hier is 'n voorbeeld van 'n vaslegging wat op die develop tak gemaak is:
$ hg log -l 1
changeset: 6:8f65e5e02793
branch: develop
tag: tip
user: Ben Straub <ben@straub.cc>
date: Thu Aug 14 20:06:38 2014 -0700
summary: More documentation
Let op die reël wat begin met “branch”.
Git kan dit nie regtig repliseer nie (en hoef dit ook nie; beide tipes takke kan as 'n Git-verwysing voorgestel word), maar git-remote-hg moet die verskil verstaan, omdat Mercurial daaroor gee.
Die skep van Mercurial-boekmerke is net so maklik as die skep van Git-takke. Aan die Git-kant:
$ git checkout -b featureA
Switched to a new branch 'featureA'
$ git push origin featureA
To hg::/tmp/hello
* [new branch] featureA -> featureA
Dis al wat daar is. Aan die Mercurial-kant lyk dit soos dit:
$ hg bookmarks
featureA 5:bd5ac26f11f9
$ hg log --style compact -G
@ 6[tip] 8f65e5e02793 2014-08-14 20:06 -0700 ben
| More documentation
|
o 5[featureA]:4,2 bd5ac26f11f9 2014-08-14 20:02 -0700 ben
|\ Merge remote-tracking branch 'origin/master'
| |
| o 4 0434aaa6b91f 2014-08-14 20:01 -0700 ben
| | update makefile
| |
| o 3:1 318914536c86 2014-08-14 20:00 -0700 ben
| | goodbye
| |
o | 2 f098c7f45c4f 2014-08-14 20:01 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard "hello, world" program
Let op die nuwe [featureA] merker op hersiening 5.
Hierdie tree presies soos Git-takke aan die Git-kant op, met een uitsondering: jy kan nie 'n boekmerk van die Git-kant af verwyder nie (dit is 'n beperking van afgeleë helpers).
Jy kan ook aan 'n “swaargewig” Mercurial-tak werk: plaas net 'n tak in die branches naamruimte (namespace):
$ git checkout -b branches/permanent
Switched to a new branch 'branches/permanent'
$ vi Makefile
$ git commit -am 'A permanent change'
$ git push origin branches/permanent
To hg::/tmp/hello
* [new branch] branches/permanent -> branches/permanent
Hier is hoe dit aan die Mercurial-kant lyk:
$ hg branches
permanent 7:a4529d07aad4
develop 6:8f65e5e02793
default 5:bd5ac26f11f9 (inactive)
$ hg log -G
o changeset: 7:a4529d07aad4
| branch: permanent
| tag: tip
| parent: 5:bd5ac26f11f9
| user: Ben Straub <ben@straub.cc>
| date: Thu Aug 14 20:21:09 2014 -0700
| summary: A permanent change
|
| @ changeset: 6:8f65e5e02793
|/ branch: develop
| user: Ben Straub <ben@straub.cc>
| date: Thu Aug 14 20:06:38 2014 -0700
| summary: More documentation
|
o changeset: 5:bd5ac26f11f9
|\ bookmark: featureA
| | parent: 4:0434aaa6b91f
| | parent: 2:f098c7f45c4f
| | user: Ben Straub <ben@straub.cc>
| | date: Thu Aug 14 20:02:21 2014 -0700
| | summary: Merge remote-tracking branch 'origin/master'
[...]
Die taknaam “permanent” is opgeteken met die wysigingstel gemerk 7.
Van die Git-kant af is die werk met enige van hierdie takstyle dieselfde: trek net uit (checkout), lê vas (commit), haal af (fetch), smelt saam (merge), trek in (pull), en push soos jy normaalweg sou doen. Een ding wat jy moet weet, is dat Mercurial nie die herskrywing van geskiedenis ondersteun nie, slegs die byvoeging daarby. Hier is hoe ons Mercurial-bewaarplek lyk na 'n interaktiewe herbasering (rebase) en 'n geforceerde push:
$ hg log --style compact -G
o 10[tip] 99611176cbc9 2014-08-14 20:21 -0700 ben
| A permanent change
|
o 9 f23e12f939c3 2014-08-14 20:01 -0700 ben
| Add some documentation
|
o 8:1 c16971d33922 2014-08-14 20:00 -0700 ben
| goodbye
|
| o 7:5 a4529d07aad4 2014-08-14 20:21 -0700 ben
| | A permanent change
| |
| | @ 6 8f65e5e02793 2014-08-14 20:06 -0700 ben
| |/ More documentation
| |
| o 5[featureA]:4,2 bd5ac26f11f9 2014-08-14 20:02 -0700 ben
| |\ Merge remote-tracking branch 'origin/master'
| | |
| | o 4 0434aaa6b91f 2014-08-14 20:01 -0700 ben
| | | update makefile
| | |
+---o 3:1 318914536c86 2014-08-14 20:00 -0700 ben
| | goodbye
| |
| o 2 f098c7f45c4f 2014-08-14 20:01 -0700 ben
|/ Add some documentation
|
o 1 82e55d328c8c 2005-08-26 01:21 -0700 mpm
| Create a makefile
|
o 0 0a04b987be5a 2005-08-26 01:20 -0700 mpm
Create a standard "hello, world" program
Wysigingstelle 8, 9 en 10 is geskep en behoort aan die permanent tak, maar die ou wysigingstelle is steeds daar.
Dit kan baie verwarrend wees vir jou spanmaats wat Mercurial gebruik, so probeer om dit te vermy.
Mercurial-opsomming (Mercurial Summary)
Git en Mercurial is soortgelyk genoeg dat die werk oor die grens heen redelik pynloos is. As jy vermy om geskiedenis te verander wat jou masjien verlaat het (soos algemeen aanbeveel word), is jy dalk nie eens bewus daarvan dat die ander kant Mercurial is nie.
Git en Perforce (Git and Perforce)
Perforce is 'n baie gewilde weergawebeheerstelsel in korporatiewe omgewings. Dit bestaan reeds sedert 1995, wat dit die oudste stelsel maak wat in hierdie hoofstuk gedek word. As sodanig is dit ontwerp met die beperkings van sy dag in gedagte; dit neem aan dat jy altyd aan 'n enkele sentrale bediener gekoppel is, en slegs een weergawe word op die plaaslike skyf gehou. Om seker te maak, sy kenmerke en beperkings is goed geskik vir verskeie spesifieke probleme, maar daar is baie projekte wat Perforce gebruik waar Git eintlijk beter sou werk.
Daar is twee opsies as jy jou gebruik van Perforce en Git wil meng.
Die eerste een wat ons sal dek, is die “Git Fusion” brug van die makers van Perforce, wat jou toelaat om subbome van jou Perforce-depot as lees-skryf Git-bewaarplekke bloot te stel.
Die tweede is git-p4, 'n kliëntkant-brug wat jou toelaat om Git as 'n Perforce-kliënt te gebruik, sonder om enige herkonfigurasie van die Perforce-bediener te vereis.
Git Fusion
Perforce verskaf 'n produk genaamd Git Fusion (beskikbaar by https://www.perforce.com/manuals/git-fusion/), wat 'n Perforce-bediener aan die bedienerkant met Git-bewaarplekke sinchroniseer.
Opstelling (Setting Up)
Vir ons voorbeelde sal ons die maklikste installasiemetode vir Git Fusion gebruik, wat die aflaai van 'n virtuele masjien is wat die Perforce-demoon (daemon) en Git Fusion laat loop. Jy kan die virtuele masjien-beeld van https://www.perforce.com/downloads kry, en sodra dit klaar afgelaai is, importeer dit in jou gunsteling virtualisasiesagteware (ons sal VirtualBox gebruik).
Met die eerste aanskakeling van die masjien vra dit jou om die wagwoord vir drie Linux-gebruikers (root, perforce en git) te pasmaak, en 'n instansienaam te verskaf, wat gebruik kan word om hierdie installasie te onderskei van ander op dieselfde netwerk.
Wanneer dit alles voltooi is, sal jy dit sien:
Jy moet kennis neem van die IP-adres wat hier gewys word, ons sal dit later gebruik.
Volgens sal ons 'n Perforce-gebruiker skep.
Kies die “Login” opsie onder aan en druk enter (of SSH na die masjien), en meld aan as root.
Gebruik dan hierdie opdragte om 'n gebruiker te skep:
$ p4 -p localhost:1666 -u super user -f john
$ p4 -p localhost:1666 -u john passwd
$ exit
Die eerste een sal 'n VI-redigeerder oopmaak om die gebruiker te pasmaak, maar jy kan die verstekwaardes aanvaar deur :wq te tik en enter te druk.
Die tweede een sal jou vra om 'n wagwoord twee keer in te tik.
Dis al wat ons met 'n dop-aanwysing (shell prompt) hoef te doen, so sluit die sessie af.
Die volgende ding wat jy moet doen om te volg, is om vir Git te sê om nie SSL-sertifikate te verifieer nie. Die Git Fusion-beeld kom met 'n sertifikaat, maar dit is vir 'n domein wat nie by jou virtuele masjien se IP-adres sal pas nie, so Git sal die HTTPS-verbinding weier. As dit 'n permanente installasie gaan wees, raadpleeg die Perforce Git Fusion-handleiding om 'n ander sertifikaat te installeer; vir ons voorbeelddoeleindes sal dit voldoende wees:
$ export GIT_SSL_NO_VERIFY=true
Nou kan ons toets dat alles werk.
$ git clone https://10.0.1.254/Talkhouse
Cloning into 'Talkhouse'...
Username for 'https://10.0.1.254': john
Password for 'https://john@10.0.1.254':
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.
Die virtuele masjien-beeld kom toegerus met 'n voorbeeldprojek wat jy kan kloon.
Hier kloon ons oor HTTPS, met die john gebruiker wat ons hierbo geskep het; Git vra vir aanmeldbewyse vir hierdie verbinding, maar die aanmeldbewyskas (credential cache) sal ons toelaat om hierdie stap vir enige opeenvolgende versoeke te omseil.
Fusion-konfigurasie (Fusion Configuration)
Sodra jy Git Fusion geïnstalleer het, sal jy die konfigurasie wil verfyn.
Dit is eintlik redelik maklik om te doen met jou gunsteling Perforce-kliënt; kaart (map) eenvoudig die //.git-fusion gids op die Perforce-bediener in jou werkruimte.
Die lêerstruktuur lyk soos dit:
$ tree
.
├── objects
│ ├── repos
│ │ └── [...]
│ └── trees
│ └── [...]
│
├── p4gf_config
├── repos
│ └── Talkhouse
│ └── p4gf_config
└── users
└── p4gf_usermap
498 directories, 287 files
Die objects gids word intern deur Git Fusion gebruik om Perforce-objekte na Git te kaart en omgekeerd; jy hoef nie met enigiets daarin te mors nie.
Daar is 'n globale p4gf_config lêer in hierdie gids, sowel as een vir elke bewaarplek – dit is die konfigurasielêers wat bepaal hoe Git Fusion optree.
Kom ons kyk na die lêer in die wortel:
[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
Ons sal nie ingaan op die betekenisse van hierdie vlagges hier nie, maar let op dat dit net 'n INI-geformatteerde tekslêer is, baie soos Git vir konfigurasie gebruik.
Hierdie lêer spesifiseer die globale opsies, wat dan oorskryf kan word deur bewaarplek-spesifieke konfigurasielêers, soos repos/Talkhouse/p4gf_config.
As jy hierdie lêer oopmaak, sal jy 'n [@repo] afdeling sien met sommige instellings wat verskil van die globale verstekwaardes.
Jy sal ook afdelings sien wat so lyk:
[Talkhouse-master]
git-branch-name = master
view = //depot/Talkhouse/main-dev/... ...
Hierdie is 'n kartering tussen 'n Perforce-tak en 'n Git-tak.
Die afdeling kan genoem word wat jy wil, solank die naam uniek is.
git-branch-name laat jou toe om 'n depotpad wat omslagtig onder Git sou wees, na 'n vriendeliker naam om te skakel.
Die view instelling beheer hoe Perforce-lêers in die Git-bewaarplek gekarteer word, met behulp van die standaard uitsig-karteringsyntaksis (view mapping syntax).
Meer as een kartering kan gespesifiseer word, soos in hierdie voorbeeld:
[multi-project-mapping]
git-branch-name = master
view = //depot/project1/main/... project1/...
//depot/project2/mainline/... project2/...
Op hierdie manier, as jou normale werkruimte-kartering veranderings in die struktuur van die gidse insluit, kan jy dit met 'n Git-bewaarplek repliseer.
Die laaste lêer wat ons sal bespreek is users/p4gf_usermap, wat Perforce-gebruikers na Git-gebruikers karteer, en wat jy dalk nie eens nodig het nie.
Wanneer van 'n Perforce-wysigingstel na 'n Git-vaslegging omgeskakel word, is Git Fusion se verstekgedrag om die Perforce-gebruiker op te soek, en die e-posadres en volle naam wat daar gestoor is vir die outeur/vaslêer (author/committer) veld in Git te gebruik.
Wanneer die ander kant toe omgeskakel word, is die verstek om die Perforce-gebruiker op te soek met die e-posadres wat in die Git-vaslegging se outeurveld gestoor is, en die wysigingstel as daardie gebruiker in te dien (met permissies wat van toepassing is).
In die meeste gevalle sal hierdie gedrag goed genoeg vaar, maar oorweeg die volgende karteringslêer:
john john@example.com "John Doe"
john johnny@appleseed.net "John Doe"
bob employeeX@example.com "Anon X. Mouse"
joe employeeY@example.com "Anon Y. Mouse"
Elke reël is van die formaat <user> <email> "<full name>", en skep 'n enkele gebruikerskartering.
Die eerste twee reëls karteer twee duidelike e-posadresse na dieselfde Perforce-gebruikersrekening.
Dit is nuttig as jy Git-vasleggings onder verskillende e-posadresse geskep het (of e-posadresse verander het), maar wil hê hulle moet na dieselfde Perforce-gebruiker gekarteer word.
Wanneer 'n Git-vaslegging van 'n Perforce-wysigingstel geskep word, word die eerste reël wat by die Perforce-gebruiker pas, vir Git-outeurskapinligting gebruik.
Die laaste twee reëls maskeer Bob en Joe se werklike name en e-posadresse van die Git-vasleggings wat geskep word. Dit is oulik as jy 'n interne projek oopbron wil maak, maar nie jou personeelgids aan die hele wêreld wil publiseer nie. Let daarop dat die e-posadresse en volle name uniek moet wees, tensy jy wil hê dat alle Git-vasleggings aan 'n enkele fiktiewe outeur toegeskryf moet word.
Werkvloei (Workflow)
Perforce Git Fusion is 'n tweerigtingbrug tussen Perforce en Git-weergawebeheer. Kom ons kyk hoe dit voel om vanaf die Git-kant te werk. Ons sal aanvaar dat ons die “Jam” projek ingekaart het met 'n konfigurasielêer soos hierbo getoon, wat ons so kan kloon:
$ git clone https://10.0.1.254/Jam
Cloning into 'Jam'...
Username for 'https://10.0.1.254': john
Password for 'https://john@10.0.1.254':
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.
[...]
Die eerste keer dat jy dit doen, kan dit 'n tydjie neem. Wat gebeur, is dat Git Fusion alle toepaslike wysigingstelle in die Perforce-geskiedenis na Git-vasleggings omskakel. Dit gebeur plaaslik op die bediener, so dit is relatief vinnig, maar as jy baie geskiedenis het, kan dit steeds 'n tydjie neem. Opeenvolgende fetch-operasies doen inkrementele omskakeling, so dit sal meer soos Git se eie spoed voel.
Soos jy kan sien, lyk ons bewaarplek presies soos enige ander Git-bewaarplek waarmee jy dalk mag werk.
Daar is drie takke, en Git het behulpsaam 'n plaaslike master tak geskep wat origin/master naspoor.
Kom ons doen 'n bietjie werk en skep 'n paar nuwe vasleggings:
# ...
$ 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.
[...]
Ons het twee nuwe vasleggings. Kom ons kyk nou of iemand anders gewerk het:
$ 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.
[...]
Dit lyk of iemand was!
Jy sou dit nie uit hierdie aansig geweet het nie, maar die 6afeb15 vaslegging is eintlik geskep deur 'n Perforce-kliënt te gebruik.
Dit lyk net soos 'n ander vaslegging vanuit Git se oogpunt, wat presies die punt is.
Kom ons kyk hoe die Perforce-bediener 'n saamsmeltingsvaslegging hanteer:
$ 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 dink dit het gewerk.
Kom ons kyk na die geskiedenis van die README lêer vanuit Perforce se oogpunt, met behulp van die hersieningsgraafkenmerk (revision graph feature) van p4v:
As jy nog nooit hierdie aansig voorheen gesien het nie, mag dit verwarrend lyk, maar dit wys dieselfde konsepte as 'n grafiese kyker vir Git-geskiedenis.
Ons kyk na die geskiedenis van die README lêer, sodat die gidsboom links bo slegs daardie lêer wys soos dit opduik in verskeie takke.
Regs bo het ons 'n visuele graaf van hoe verskillende hersienings van die lêer verwant is, and die groot-prentjie-aansig van hierdie graaf is regs onder.
Die res van die aansig word gegee aan die besonderhedenaansig vir die geselekteerde hersiening (2 in hierdie geval).
Een ding om op te let is dat die graaf presies lyk soos die een in Git se geskiedenis.
Perforce het nie 'n benoemde tak gehad om die 1 en 2 vasleggings te stoor nie, so dit het 'n “anonieme” tak in die .git-fusion gids gemaak om dit te hou.
Dit sal ook gebeur vir benoemde Git-takke wat nie ooreenstem met 'n benoemde Perforce-tak nie (en jy kan hulle later na 'n Perforce-tak kaart deur die konfigurasielêer te gebruik).
Die meeste hiervan gebeur agter die skerms, maar die eindresultaat is dat een persoon in 'n span Git kan gebruik, 'n ander kan Perforce gebruik, en nie een van hulle sal van die ander se keuse weet nie.
Git-Fusion Opsomming (Git-Fusion Summary)
As jy toegang het (of kan kry) tot jou Perforce-bediener, is Git Fusion 'n wonderlike manier om Git en Perforce met mekaar te laat praat. Daar is 'n bietjie konfigurasie betrokke, maar die leerkurwe is nie baie steil nie. Hier is een van die min afdelings in hierdie hoofstuk waar waarskuwingstekens oor die gebruik van Git se volle krag nie sal verskyn nie. Dit is nie om te sê dat Perforce gelukkig sal wees met alles wat jy daarna toe gooi nie – as jy probeer om geskiedenis te herskryf wat reeds gepush is, sal Git Fusion dit weier – maar Git Fusion probeer baie hard om eie (native) te voel. Jy kan selfs Git-submodules gebruik (al sal dit vreemd lyk vir Perforce-gebruikers), en takke saamsmelt (dit sal aan die Perforce-kant as 'n integrasie opgeteken word).
As jy nie die administrateur van jou bediener kan oortuig om Git Fusion op te stel nie, is daar steeds 'n manier om hierdie gereedskap saam te gebruik.
Git-p4
git-p4 is 'n tweerigtingbrug tussen Git en Perforce.
Dit loop geheel en al binne jou Git-bewaarplek, so jy sal geen vorm van toegang tot die Perforce-bediener benodig nie (behalwe gebruikersbewyse, natuurlik).
git-p4 is nie so 'n buigsame of volledige oplossing as Git Fusion nie, maar dit laat jou wel toe om die meeste te doen van wat jy wil doen sonder om indringend vir die bedieneromgewing te wees.
|
Note
|
Jy sal die |
Opstelling (Setting Up)
Vir voorbeelddoeleindes sal ons die Perforce-bediener vanaf die Git Fusion OVA laat loop soos hierbo getoon, maar ons sal die Git Fusion-bediener omseil en direk na die Perforce-weergawebeheer gaan.
Ten einde die p4 opdragreëlkliënt te gebruik (waarop git-p4 afhanklik is), sal jy 'n paar omgewingsveranderlikes moet stel:
$ export P4PORT=10.0.1.254:1666
$ export P4USER=john
Om te Begin (Getting Started)
Soos met enigiets in Git, is die eerste opdrag om te kloon:
$ 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
Dit skep wat in Git-terme 'n “vlakkige” (shallow) kloon is; slegs die allernuutste Perforce-hersiening word in Git geïmporteer; onthoud, Perforce is nie ontwerp om elke hersiening aan elke gebruiker te gee nie. Dit is genoeg om Git as 'n Perforce-kliënt te gebruik, maar vir ander doeleindes is dit nie genoeg nie.
Sodra dit klaar is, het ons 'n ten volle funksionele Git-bewaarplek:
$ 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
Let op hoe daar 'n “p4” remote vir die Perforce-bediener is, maar alles anders lyk soos 'n standaard kloon. Om die waarheid te sê, dit is 'n bietjie misleidend; daar is eintlik nie 'n remote daar nie.
$ git remote -v
Geen remotes bestaan heeltemal in hierdie bewaarplek nie.
git-p4 het 'n paar verwysings (refs) geskep om die toestand van die bediener te verteenwoordig, en hulle lyk soos afgeleë verwysings vir git log, maar hulle word nie deur Git self bestuur nie, en jy kan nie daarna push nie.
Werkvloei (Workflow)
Goed, kom ons doen 'n bietjie werk. Kom ons aanvaar jy het 'n bietjie vordering gemaak met 'n baie belangrike kenmerk, en jy is gereed om dit aan die res van jou span te wys.
$ 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
Ons het twee nuwe vasleggings gemaak wat ons gereed is om na die Perforce-bediener in te dien. Kom ons kyk of iemand anders vandag gewerk het:
$ 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
Dit lyk of hulle het, en master en p4/master het uiteengegaan.
Perforce se takstelsel lyk geensins soos Git s’n nie, so die indiening van saamsmeltingsvasleggings maak geen sin nie.
git-p4 beveel aan dat jy jou vasleggings rebase, en kom selfs met 'n kortpad om dit te doen:
$ 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(-)
Jy kan waarskynlik uit die afvoer vertel, maar git p4 rebase is 'n kortpad vir git p4 sync gevolg deur git rebase p4/master.
Dit is 'n bietjie slimner as dit, veral wanneer daar met veelvuldige takke gewerk word, maar dit is 'n goeie benadering.
Nou is ons geskiedenis weer lineair, en ons is gereed om ons veranderings terug te beman na Perforce.
Die git p4 submit opdrag sal probeer om 'n nuwe Perforce-hersiening te skep vir elke Git-vaslegging tussen p4/master en master.
Om dit uit te voer, gooi dit ons in ons gunsteling redigeerder, en die inhoud van die lêer lyk soos iets soos dit:
# 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 ben@straub.cc 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>
Dit is meestal dieselfde inhoud as wat jy sou sien deur p4 submit uit te voer, behalwe vir die goed aan die einde wat git-p4 behulpsaam ingesluit het.
git-p4 probeer jou Git- en Perforce-instellings individueel eerbiedig wanneer dit 'n naam vir 'n vaslegging of wysigingstel moet verskaf, maar in somige gevalle wil jy dit oorskryf.
Byvoorbeeld, as die Git-vaslegging wat jy invoer geskryf is deur 'n bydraer wat nie 'n Perforce-gebruikersrekening het nie, wil jy dalk steeds hê dat die resulterende wysigingstel moet lyk of hulle dit geskryf het (en nie jy nie).
git-p4 het die boodskap vanaf die Git-vaslegging behulpsaam ingevoer as die inhoud vir hierdie Perforce-wysigingstel, so al wat ons hoef te doen is om te stoor en toe te maak, twee keer (een keer vir elke vaslegging).
Die resulterende dop-afvoer sal so iets lyk:
$ 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
Die resultaat is as ware as ons net 'n git push gedoen het, wat die nouste analogie is vir wat eintlik gebeur het.
Let daarop dat tydens hierdie proses elke Git-vaslegging in 'n Perforce-wysigingstel omskep word; as jy hulle wil saampers tot 'n enkele wysigingstel, kan jy dit met 'n interaktiewe rebase doen voor die uitvoering van git p4 submit.
Let ook op dat die SHA-1 huts van al die vasleggings wat as wysigingstelle ingedien is, verander het; dit is omdat git-p4 'n reël byvoeg aan die einde van elke vaslegging wat dit omskep:
$ git log -1
commit 775a46f630d8b46535fc9983cf3ebe6b9aa53145
Author: John Doe <john@example.com>
Date: Sun Aug 31 10:31:44 2014 -0800
Change page title
[git-p4: depot-paths = "//depot/www/live/": change = 12144]
Wat gebeur as jy probeer om 'n saamsmeltingsvaslegging (merge commit) in te dien? Kom ons gee dit 'n kans. Hier is die situasie waarin ons ourselves bevind het:
$ 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
Die Git- en Perforce-geskiedenis loop uiteen na 775a46f.
Die Git-kant het twee vasleggings, dan 'n saamsmeltingsvaslegging met die Perforce-kop (head), dan nog 'n vaslegging.
Ons gaan probeer om hierdie in te dien bo-op 'n enkele wysigingstel aan die Perforce-kant.
Kom ons kyk wat sou gebeur as ons nou probeer indien:
$ 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
Die -n vlag is kort vir --dry-run, wat probeer rapporteer wat sou gebeur as die submit-opdrag vir eggo’s uitgevoer sou word.
In hierdie geval lyk dit of ons drie Perforce-wysigingstelle sou skep, wat ooreenstem met die drie nie-saamsmeltingsvasleggings wat nog nie op die Perforce-bediener bestaan nie.
Dit klink presies na wat ons wil hê, kom ons kyk hoe dit uitdraai:
$ 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
Ons geskiedenis het lineair geword, presies asof ons gerebase het voor indiening (wat in werklikheid presies is wat gebeur het). Dit beteken dat jy vry kan wees om takke aan die Git-kant te skep, daaraan te werk, weg te gooi en saamsmelt sonder vrees dat jou geskiedenis op een of ander manier onversoenbaar met Perforce sal word. As jy dit kan rebase, kan jy dit by 'n Perforce-bediener bydra.
Takking (Branching)
As jou Perforce-projek veelvuldige takke het, is jy nie sonder geluk nie; git-p4 kan dit hanteer op 'n manier wat dit laat voel soos Git.
Sê nou jou Perforce-depot is so ingedeel:
//depot
└── project
├── main
└── dev
En sê nou jy het 'n dev tak, wat 'n uitsigspesifikasie (view spec) het wat so lyk:
//depot/project/main/... //depot/project/dev/...
git-p4 kan daardie situasie outomaties detekteer en die regte ding doen:
$ 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
Let op die “@all” spesifiseerder in die depotpad; dit sê vir git-p4 om nie net die nuutste wysigingstel vir daardie subboom te kloon nie, maar alle wysigingstelle wat ooit daardie paaie aangeraak het.
Dit is nader aan Git se konsep van 'n kloon, maar as jy aan 'n projek met 'n lang geskiedenis werk, kan dit 'n rukkie neem.
Die --detect-branches vlag sê vir git-p4 om Perforce se takspesifikasies te gebruik om die takke na Git-verwysings te kaart.
As hierdie karterings nie op die Perforce-bediener teenwoordig is nie (wat 'n volkome geldige manier is om Perforce te gebruik), kan jy vir git-p4 sê wat die takkarterings is, en jy kry dieselfde resultaat:
$ 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 .
Deur die git-p4.branchList konfigurasieveranderlike op main:dev te stel, sê dit vir git-p4 dat “main” en “dev” beide takke is, en die tweede een is 'n kind van die eerste een.
As ons nou git checkout -b dev p4/project/dev uitvoer en 'n paar vasleggings maak, is git-p4 slim genoeg om die regte tak te teiken wanneer ons git p4 submit doen.
Ongelukkig kan git-p4 nie vlakkige klone (shallow clones) en veelvuldige takke meng nie; as jy 'n enorme projek het en aan meer as een tak wil werk, sal jy git p4 clone een keer moet uitvoer vir elke tak waarna jy wil indien.
Vir die skep of integrering van takke sal jy 'n Perforce-kliënt moet gebruik.
git-p4 kan slegs met bestaande takke sinchroniseer en daarheen indien, en dit kan dit slegs een lineare wysigingstel op 'n slag doen.
As jy twee takke in Git saamsmelt en probeer om die nuwe wysigingstel in te dien, is al wat opgeteken sal word 'n trop léeerveranderings; die metadata oor watter takke betrokke is by die integrasie sal verlore gaan.
Git en Perforce Opsomming (Git and Perforce Summary)
git-p4 maak dit moontlik om 'n Git-werkvloei met 'n Perforce-bediener te gebruik, en dit is nogal goed daarin.
Dit is egter belangrik om te onthou dat Perforce in beheer van die bron is, en jy gebruik slegs Git om plaaslik te werk.
Wees net baie versigtig oor die deel van Git-vasleggings; as jy 'n remote het wat ander mense gebruik, moenie enige vasleggings push wat nie reeds by die Perforce-bediener ingedien is nie.
As jy vryelik die gebruik van Perforce en Git as kliënte vir bronbeheer wil meng, en jy kan die bedieneradministrateur oortuig om dit te installeer, maak Git Fusion die gebruik van Git 'n eersteklas weergawebeheerkliënt vir 'n Perforce-bediener.