Een groot deel van open source ontwikkel projecten en een groot aantal van bedrijfsprojecten gebruiken Subversion om hun broncode te beheren. Het bestaat meer dan 10 jaar en voor een groot gedeelte van die tijd was het de de facto VCS keuze voor open source projecten. Het lijkt in vele aspecten ook erg op CVS, die daarvoor een grote naam was in de source-control wereld.
Een van de mooie functies van Git is de bidirectionele brug naar Subversion genaamd git svn
.
Dit instrument staat je toe om Git te gebruiken als een volwaardig client naar een Subversion server, zodat je alle lokale mogelijkheden van Git kunt gebruiken en dan naar een Subversion server kunt pushen alsof je lokaal Subversion gebruikt.
Dit houdt in dat je lokaal kunt branch en mergen, de staging area kunt gebruiken, rebasing en cherry-picking kunt gebruiken, enzovoorts, terwijl de mensen waarmee je samenwerkt blijven werken met hun middelen uit de stenen tijdperk.
Het is een goede manier om Git in de bedrijfsomgeving te smokkelen en je mede-ontwikkelaars te helpen om effectiever te worden terwijl jij een lobby voert om de infrastructuur zover te krijgen dat Git volledig wordt ondersteund.
De Subversion bridge is de manier om naar de DVCS wereld te groeien.
Het basis commando in Git voor alle Subversion bridging commando’s is git svn
.
Het accepteert best wel veel commando’s, dus we laten de meest gebruikte zien terwijl we een aantal eenvoudige workflows behandelen.
Het is belangrijk om op te merken dat wanneer je git svn
gebruikt, je interacteert met Subversion, wat een systeem is dat behoorlijk anders werkt dan Git.
Alhoewel je lokaal kunt branchen en mergen, is het over het algemeen het beste om je historie zo lineair als mogelijk te houden door je werk te rebasen, en te vermijden dat je zaken doet als het tegelijkertijd interacteren met een remote repository in Git.
Ga niet je historie overschrijven en dan weer proberen te pushen, en push niet tegelijk naar een parallelle Git repository om samen te werken met andere Git ontwikkelaars. Subversion kan alleen maar een lineaire historie aan, en het is eenvoudig om het in de war te brengen. Als je met een team samenwerkt, en sommigen gebruiken SVN en anderen gebruiken Git, zorg er dan voor dat iedereen de SVN server gebruikt om samen te werken - als je dit doet wordt je leven een stuk aangenamer.
Om deze functionaliteit te laten zien, heb je een typische SVN repository nodig waar je schrijfrechten op hebt.
Als je deze voorbeelden wilt kopiëren, moet je een schrijfbare kopie maken van een SVN test repository.
Om dat eenvoudig te doen, kan je een tool svnsync
genaamd gebruiken die bij Subversion wordt geleverd.
Om het te volgen, moet je eerst een nieuwe lokale Subversion repository maken:
$ mkdir /tmp/test-svn
$ svnadmin create /tmp/test-svn
Daarna moet je alle gebruikers toestaan om revprops te wijzigen - een makkelijke manier is om een pre-revprop-change
toe te voegen die altijd met 0 afsluit:
$ cat /tmp/test-svn/hooks/pre-revprop-change
#!/bin/sh
exit 0;
$ chmod +x /tmp/test-svn/hooks/pre-revprop-change
Je kunt dit project nu synchroniseren naar je lokale machine door svnsync init
aan te roepen met de naar en van repositories.
$ svnsync init file:///tmp/test-svn \
http://your-svn-server.example.org/svn/
Dit richt de properties in om de synchronisatie te laten lopen. Je kunt dan de code clonen door het volgende te doen
$ 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 deze handeling maar enkele minuten in beslag neemt, zal het proces, als je de orginele repository naar een andere remote repository probeert te kopiëren, bijna een uur in beslag nemen, zelfs als er minder dan 100 commits zijn. Subversion moet een revisie per keer kopiëren en deze dan naar de andere repository pushen - het is belachelijk inefficiënt, maar het is de enige makkelijke manier om dit te doen.
Nu je een Subversion repository hebt waar je schrijfrechten op hebt, kan je een typische workflow gaan volgen.
Je begint met het git svn clone
commando, die een hele Subversion repository importeert naar een lokale Git repository.
Onthoud dat als je van een echte gehoste Subversion repository importeert, je de file:///tmp/test-svn
moet vervangen met de URL van je Subversion repository:
$ 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 roept het equivalent van twee commando’s aan - git svn init
gevolgd door git svn fetch
- op de URL die je opgeeft.
Dit kan even duren.
Bijvoorbeeld, als het project maar ongeveer 75 commits heeft en de codebase is niet zo groot, maar Git moet elke versie uitchecken, een voor een, en deze allemaal individueel committen.
Voor een project met honderden of duizenden commits, kan dit letterlijk uren of zelfs dagen in beslag nemen voor het klaar is.
Het -T trunk -b branches -t tags
gedeelte vertelt Git dat deze Subversion repository de normale branch en tag conventies volgt.
Als je jouw trunk, branches of tags andere namen geeft, kan je deze opties veranderen.
Omdat dit zo gewoonlijk is, kan je dit gehele gedeelte vervangen met -s
, wat standaard indeling betekent en al die opties impliceert.
Het volgende commando doet hetzelfde:
$ git svn clone file:///tmp/test-svn -s
Op dit punt zou je een valide Git repository moeten hebben die jouw branches en tags heeft geïmporteerd.
$ 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
Merk op hoe dit instrument Subversion tags als remote refs beheert.
Laten we het Git binnenwerk commando show-ref
gebruiken om het iets nauwkeuriger te bekijken:
$ 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 doet dit niet als het van een Git server kloont; zo ziet een repository met tags eruit na een verse clone:
$ 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 fetched de tags direct naar refs/tags
, in plaats van ze te behandelen als remote branches.
Nu je een werkende repository hebt, kan je wat werk doen op het project en je commits terug stroomopwaarts pushen, waarbij je Git feitelijk als een SVN client gebruikt. Als je een van de bestanden hebt gewijzigd en deze commit, heb je een commit die lokaal in Git bestaat, maar die niet op de Subversion server bestaat:
$ git commit -am 'Adding git-svn instructions to the README'
[master 4af61fd] Adding git-svn instructions to the README
1 file changed, 5 insertions(+)
Nu moet je jouw wijziging stroomopwaarts pushen.
Merk op dat dit de manier waarop je met Subversion werkt wijzigt - je kunt verschillende commits offline doen en ze dan allemaal in een keer naar de Subversion server pushen.
Om naar een Subversion server te pushen, roep je het git svn dcommit
commando aan:
$ 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 pakt alle commits die je hebt gemaakt bovenop de Subversion server code, maakt een Subversion commit voor elk van deze, en herschrijft je lokale Git commit om een unieke referentienummer in te voegen.
Dit is belangrijk omdat dit betekent dat al de SHA-1 checksums voor je lokale commits zal wijzigen.
Deels om deze reden, is het werken met Git-gebaseerde remote versies van je project tegelijk met een Subversion server geen goed idee.
Als je naar de laatste commit kijkt, kan je het nieuwe git-svn-id
zien die was toegevoegd:
$ 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
Merk op dat de SHA-1 checksum die oorspronkelijk begon met 4af61fd
toen je ging committen nu begint met 95e0222
.
Als je zowel naar een Git server als een Subversion server wilt pushen, moet je eerst anar de Subversion server pushen (dcommit
), omdat deze actie je commit gegevens wijzigt.
Als je met andere ontwikkelaars werkt, dan zal op een gegeven moment iemand van jullie gaan pushen, en dan zal de ander een wijziging proberen te pushen die conflicteert.
Die wijziging zal afgewezen worden totdat je hun werk merget.
In git svn
ziet dit er zo uit:
$ 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 deze situatie op te lossen, kan je git svn rebase
uitvoeren, die alle wijzigingen op de server pullt die je nog niet hebt, en rebaset al het werk dat je hebt bovenop hetgeen op de server 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.
Nu is al jouw werk uitgevoerd bovenop hetgeen wat op de Subversion server staat, dus je kunt met goed gevolg dcommit
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
Merk op dat, in tegenstelling tot Git die vereist dat je werk van stroomopwaarts dat je lokaal nog niet hebt merget voordat je kunt pushen, git svn
je dat alleen verplicht te doen als de wijzigingen conflicteren (vergelijkbaar met hoe Subversion werkt).
Als iemand een wijziging op een bestand pushed en jij pushed een wijziging op een ander bestand, zal je dcommit
prima werken:
$ 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 belangrijk om te onthouden, omdat de uitkomst een project status is die niet eerder bestond op een van jullie computers toen jij pushde. Als de wijzigingen niet compatible zijn, maar geen conflict veroorzaken, kan je problemen krijgen die moeilijk te diagnostiseren zijn. Dit verschilt met de manier van werken met een Git server - in Git kan je de situatie op je lokale werkstation testen voordat je het publiceert, terwijl in SVN, je er nooit zeker van kunt zijn dat de situatie direct voor en na een commit gelijk zijn.
Je kunt ook dit commando aanroepen om wijzigingen binnen te halen van de Subversion server, zelfs als je zelf nog niet klaar bent om te committen.
Je kunt git svn fetch
aanroepen om de nieuwe gegevens te pakken, maar git svn rebase
doet de fetch en werkt daarna je lokale commits bij.
$ 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.
Regelmatig git svn rebase
aanroepen verzekert je ervan dat je code altijd is bijgewerkt.
Je moet er echter zeker van zijn dat je werk directory schoon is als je dit aanroept.
Als je lokale wijzigingen hebt, moet je je werk stashen of tijdelijk committen voordat je git svn rebase
aanroept - anders zal het commando stoppen als het ziet dat de rebase in een merge conflict zal resulteren.
Als je je op je gemak voelt met een Git workflow, zal je waarschijnlijk topic branches maken, daar werk op doen en ze dan weer in mergen.
Als je anar een Subversion server pushed met git svn
, dan is het waarschijnlijk verstandig om je werk elke keer op een enkele branch te rebasen in plaats van branches samen te mergen.
De achterliggende reden om rebasen te gebruiken is dat Subversion een lineaire historie kent en niet met merges omgaat zoals Git dit doet, dus git svn
volgt alleen de eerste ouder als het de snapshots naar Subversion commits converteert.
Stel dat je historie er als volgt uitziet: je hebt een experiment
-branch gemaakt, heb daar twee commits gedaan, en deze daarna terug in master
gemerged.
Als je dcommit
doet, zie je uitvoer als 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
Het aanroepen van dcommit
op een branch met gemergde historie werkt prima, behalve als je naar je Git project historie kijkt, heeft het geen van beide commits die je op de experiment
-branch gemaakt hebt herschreven - in plaats daarvan komen al deze wijzigingen als een enkele merge commit in de SVN versie.
Als iemand anders dat werk kloont, is alles wat ze zien de merge commit met al het werk erin gepropt, alsof je git merge --squash
aangeroepen hebt; ze zien niet de commit gegevens over waar het vandaan kwam of wanneer het was gecommit.
Branches maken in Subversion is niet hetzelfde als branches maken in Git; als je kunt voorkomen dat je het vaak doet, is dat eigenlijk wel het beste.
Echter, je kunt in Subversion branches maken en ernaar committen met git svn
.
Om een nieuwe branch in Subversion te maken, roep je git svn branch [branchnaam]
aan:
$ 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 is het equivalent van het svn copy trunk branches/opera
commando in Subversion en wordt uitgevoerd op de Subversion server.
Het is belangrijk op te merken dat dit je niet uitcheckt in die branch; als je op dat moment gaat committen, dan zal die commit naar trunk
gaan op de server, niet opera
.
Git probeert uit te vinden naar welke branch je dcommits gaan door te kijken naar de punt van al je Subversion branches in je historie - je zou er maar een moeten hebben, en het zou de laatste moeten zijn met een git-svn-id
in je huidige branch historie.
Als je op meer dan een branch tegelijk wilt werken, kan je lokale branches inrichten om te dcommit
-ten naar specifieke Subversion branches door ze te beginnen op de geïmporteerde Subversion commit voor die branch.
Als je een opera
-branch wilt waar je apart op kunt werken, kan je het volgende aanroepen:
$ git branch opera remotes/origin/opera
Vervolgens, als je je opera
-branch wilt mergen naar trunk
(je master
-branch), kan je dat doen met een gewone git merge
.
Maar als je een beschrijvende commit bericht (via -m
) moeten meegeven, anders zal de merge ``Merge branch opera'' vermelden in plaats van iets nuttigs.
Onthoud dat hoewel je git merge
gebruikt om deze handeling uit te voeren, en de merge waarschijnlijk veel makkelijker zal zijn dan het in Subversion zou zijn (omdat Git automatisch de juiste merge basis voor je zal uitzoeken), dit geen normale Git merge commit is.
Je zult deze gegevens naar een Subversion server terug moeten pushen die niet in staat is een commit te verwerken die naar meer dan een ouder terug te herleiden is; dus, nadat je het gepusht hebt, zal het eruit zien als een enkele commit waarin al het werk van een andere branch is gepropt onder een enkele commit.
Nadat je een branch in de een andere hebt gemerged, kan je niet simpelweg doorgaan met werken op die branch, zoals je in Git zou doen.
Het dcommit
commando dat je hebt aangeroepen verwijdert alle informatie die aangeeft welke branch erin was gemerged, dus daarop volgende merge-basis berekeningen zullen fout gaan - de dcommit maakt dat je git merge
resultaat eruit ziet alsof je git merge --squash
had aangeroepen.
Jammergenoeg is er geen goede manier om deze situatie te vermijden - Subversion kan deze informatie niet opslaan, dus je zult altijd gehinderd worden door de beperkingen zolang je het gebruikt als je server.
Om problemen te voorkomen, moet je de lokale branch verwijderen (in dit geval, opera
) nadat je het in de trunk hebt gemerged.
De git svn
toolset biedt een aantal commando’s om de overgang naar Git te vergemakkelijken door wat functionaliteit te leveren die vergelijkbaar is met wat je in Subversion had.
Hie zijn een paar commando’s die je geven wat Subversion normaalgesproken deed.
Als je Subversion gewend bent en je wilt je historie zien op de uitvoermanier van SVN, kan je git svn log
aanroepen om je commit historie in SVN formaat te zien.
$ 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
Je moet twee belangrijke dingen weten over git svn log
.
Ten eerste, het werkt offline, in tegenstelling tot het echte svn log
commando, die de Subversion server om de gegevens vraagt.
Ten tweede, het laat je alleen commits zien die gecommit zijn naar de Subversion server.
Lokale Git commits die je niet ge-dcommit hebt worden niet getoond; noch de commits die mensen in de tussentijd naar de Subversion server hebben gemaakt.
Je moet het meer zien als de laatst bekende stand van commits op de Subversion server.
Net zoals het git svn log
commando het svn log
commando offline simuleert, kan je het equivalent van svn annotate
krijgen door git svn blame [FILE]
aan te roepen.
De uitvoer ziet er als volgt uit:
$ 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
Nogmaals, het laat je niet de commits zien die je lokaal in Git gemaakt hebt of die in de tussentijd naar Subversion zijn gepusht.
Je kunt ook de zelfde soort informatie krijgen die svn info
je geeft door git svn info
aan te roepen:
$ 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 gelijk aan blame
en log
in die zin dat het offline loopt en dat het alleen is bijgewerkt tot de laatste keer dat je met de Subversion server contact had.
Als je een Subversion repository cloont die een svn:ignore
property ergens heeft, zal je waarschijnlijk vergelijkbare .gitignore
bestanden willen krijgen zodat je niet per ongeluk bestanden commit die je niet had moeten doen.
git svn
heeft twee commando’s die je helpen met dit scenario.
De eerste is git svn create-ignore
, die automatisch vergelijkbare .gitignore
bestanden voor je maakt zodat je volgende commit deze kan bevatten.
Het tweede commando is git svn show-ignore
, die de regels die je in een .gitignore
bestand moet zetten naar stdout uitvoert, zodat je deze uitvoer naar je het exclusie bestand in je project kunt leiden:
$ git svn show-ignore > .git/info/exclude
Op deze manier, vervuil je het project niet met .gitignore
bestanden.
Dit is een goed alternatief als je de enige Git gebruiker in een Subversion team bent, en je teamgenoten geen .gitignore
bestanden in het project willen hebben.
De git svn
instrumenten zijn nuttig als je vastzit aan een Subversion server, of op een andere manier in een ontwikkelteam zit waar het gebruik van een Subversion server noodzakelijk is.
Je moet het echter als een gemankeerde Git beschouwen, of je loopt al snel tegen terminologie-verschillen aan die jou en je medewerkers zullen verwarren.
Probeer, om niet in de problemen te komen, de volgende richtlijnen te volgen:
-
Houd een lineaire Git historie aan die geen merge commits bevat die door
git merge
zijn aangemaakt. Rebase al het werk die je buiten je hoofd-branch doet hierop terug; merge het niet in. -
Richt niets in voor het samenwerken op een aparte Git server, en werk niet samen met zo’n server. Je kunt er misschien een bijhouden om clones voor nieuwe ontwikkelaars te versnellen, maar ga er niets naar pushen dat geen
git-svn-id
regel heeft. Je zou zelfs eenpre-receive
hook kunnen aanmaken die controleert dat elke commit bericht op eengit-svn-id
controleert en pushes afwijst die commits bevatten die dit niet hebben.
Als je deze richtlijnen volgt, wordt het werken met een Subversion server misschien iets dragelijker. Echter, als het ook maar enigszins mogelijk is om naar een echte Git server te gaan, zal dit je team veel meer opleveren.