Skip to content

Latest commit

 

History

History
132 lines (100 loc) · 5.57 KB

import-svn.asc

File metadata and controls

132 lines (100 loc) · 5.57 KB

Subversion

Als je de vorige paragraaf leest over het gebruik van`git svn`, kan je eenvoudigweg deze instructies gebruiken om met git svn clone een repository te maken en daarna te stoppen met de Subversion server, naar een nieuwe Git server te pushen en die beginnen te gebruiken. Als je de historie wilt, kan je dat zo snel voor elkaar krijgen als je de gegevens uit de Subversion server kunt krijgen (en dat kan even duren).

Deze import is echter niet perfect, en omdat het zo lang duurt, kan je eigenlijk ook meteen maar goed doen. Het eerste probleem is de auteur-informatie. In Subversion, heeft elke persoon die commit heeft gedaan een gebruikersnaam op het systeem die wordt opgenomen in de commit-informatie. De voorbeelden in de vorige paragraaf tonen schacon in bepaalde plaatsen, zoals de blame uitvoer en de git svn log. Als je dit beter op Git auteur-gegevens wilt mappen, moet je een relatie leggen van de Subversion gebruikers naar de Git auteurs. Maak een bestand genaamd users.txt die deze mapping-informatie heeft in een formaat als deze:

schacon = Scott Chacon <[email protected]>
selse = Someo Nelse <[email protected]>

Om een lijst van auteur-namen te krijgen die SVN gebruikt, kan je dit aanroepen:

$ svn log --xml --quiet | grep author | sort -u | \
  perl -pe 's/.*>(.*?)<.*/$1 = /'

Dat maakt de loguitvoer in XML formaat aan, en behoudt vervolgens alleen de regels met auteur-informatie, verwijdert duplicaten en haalt de XML tags weg. (Dit werkt duidelijk alleen op een machine met grep, sort, en perl erop geïnstalleerd). Stuur daarna de uitvoer naar je users.txt bestand zodat je de overeenkomstige Git gebruiker gegevens naast elke regel kunt zetten.

Je kunt dit bestand aan git svn geven om het te helpen de auteur gegevens beter te mappen. Je kunt git svn ook vertellen de meta-data die Subversion normaalgesproken importeert niet mee te nemen, door --no-metadata mee te geven aan de clone of init commando’s. Hierdoor ziet je import commando er ongeveer zo uit:

$ git svn clone http://my-project.googlecode.com/svn/ \
      --authors-file=users.txt --no-metadata --prefix "" -s my_project
$ cd my_project

Nu zou je een mooiere Subversion import moeten hebben in je my_project directory. In plaats van commits die er uit zien als dit

commit 37efa680e8473b615de980fa935944215428a35a
Author: schacon <schacon@4c93b258-373f-11de-be05-5f7a86268029>
Date:   Sun May 3 00:12:22 2009 +0000

    fixed install - go to trunk

    git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de-
    be05-5f7a86268029

zien ze er zo uit:

commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2
Author: Scott Chacon <[email protected]>
Date:   Sun May 3 00:12:22 2009 +0000

    fixed install - go to trunk

Niet alleen ziet het Author veld er veel beter uit, maar de git-svn-id is er ook niet meer.

Je moet ook nog wat opschonen na de import. Onder andere moet je de vreemde referenties opschonen die git svn heeft gemaakt. Allereerst ga je de tags verplaatsen zodat ze echte tags zijn, in plaats van vreemde remote branches, en daarna verplaats je de overige branches zodat ze lokaal zijn.

Om de tags te verplaatsen zodat ze echte Git tags worden, roep je dit aan

$ for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do git tag ${t/tags\//} $t && git branch -D -r $t; done

Dit neemt de referenties die remote branches waren en begonnen met refs/remotes/tags/ en maakt er echte (lichtgewicht) tags van.

Daarna verplaatsen we de overige referenties onder refs/remotes om er lokale branches van te maken:

$ for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do git branch $b refs/remotes/$b && git branch -D -r $b; done

Het kan gebeuren dat je een aantal extra branches ziet die vooraf worden gegaan door @xxx (waar xxx een getal is), terwijl je in Subversion aleen maar een branch ziet. Dit is eigenlijk een Subversion kenmerk genaamd `peg-revisions'', wat iets is waar Git gewoonweg geen syntactische tegenhanger voor heeft. Vandaar dat `git svn eenvoudigweg het svn versienummer aan de branchnaam toevoegt op dezelfde manier als jij dit zou hebben gedaan in svn om het peg-revisie van die branch te adresseren. Als je niet meer om de peg-revisies geeft, kan je ze simpelweg verwijderen:

$ for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done

Nu zijn alle oude branches echte Git branches en alle oude tags echte Git tags.

Er is nog een laatste ding om op te schonen: Helaas maakt git svn een extra branch aan met de naam trunk, wat overeenkomt met de standaard branch in Subversion, maar de trunk-referentie wijst naar dezelfde plek als master. Omdat master idiomatisch meer Git is, is hier de manier om die extra branch te verwijderen:

$ git branch -d trunk

Het laatste om te doen is om je nieuwe Git server als een remote toe te voegen en er naar te pushen. Hier is een voorbeeld van een server als een remote toe te voegen:

$ git remote add origin git@my-git-server:myrepository.git

Omdat al je branches en tags ernaar wilt sturen, kan je nu dit aanroepen:

$ git push origin --all
$ git push origin --tags

Al je branches en tags zouden nu op je nieuwe Git server moeten staan in een mooie, schone import.