Letztens musste ich mir Gedanken machen, wie man SVN-Repositorys zu Git konvertiert. Bei SVN handelt es sich um ein inzwischen veraltetes Versionsverwaltungssystem – es kann noch genutzt werden, aber Git hat einfach viel zu viele Vorteile.
Doch wie bekommt man die Daten von einem SVN-Repo in ein Git-Repo – natürlich mit allen Commits, die man auch im Git so nutzen kann, wie unter SVN? Hier die passende Anleitung.
SVN zu Git konvertieren
Als Erstes müssen wir das komplette SVN-Repo auf einen Rechner auschecken, der die Konvertierung übernehmen soll. Je nach Größe des Repos kann dieser über Minuten bis auch zu Tagen damit beschäftigt sein.
In meinem Beispiel nennt sich das Repo svn.at/Linux/ – wir checken erst einmal wie gewohnt aus:
svn co https://svn.at/Linux/
Jetzt benötigen wir noch die passende Software, die die Konvertierung übernimmt. Unter auf Debian basierenden Linux-Distributionen installieren wir diese wie gewohnt über die Paket-Verwaltung durch das Paket „git-svn“ – am schnellsten gelingt dies als root auf dem Terminal mit dem Befehl:
apt update
apt install git-svn
Die Konvertierung läuft am Terminal ab, das SVN-Repo muss online weiter erreichbar sein. Zu Beginn wechseln wir in das ausgecheckte Repo-Verzeichnis (nach obigem Beispiel):
cd Linux/
Mit dem ersten Befehl ermitteln wir die Namen der Beteiligten, also den Personen, die selbst Commits im Repo angelegt haben:
svn log --xml --quiet | grep author | sort -u | perl -pe 's/.>(.?)<.*/$1 = /'
Als Ausgabe erhalten wir eine Liste mit den Namen, diese könnte etwa so aussehen:
pinguin =
tux =
debian =
Wir markieren diese Ausgabe und fügen diese genau so in eine Textdatei ein – ich nenne diese beispielsweise „authors.txt„, die Datei liegt außerhalb des ausgecheckten Repo-Verzeichnisses. Diese wird jetzt mit einem beliebigen Texteditor bearbeitet – Sie fügen dahinter die Namen und die E-Mail-Adresse ein:
pinguin = Pinguin Linux <adresse@dada.com>
tux = Tux <adresse@tux.com>
debian = <adresse@debian.org>
Jetzt beginnt die eigentliche Arbeit – wir gehen aus dem Verzeichnis heraus:
cd ..
Und wir starten den Befehl zur Konvertierung – zuletzt geben Sie die erstellte Textdatei und das Repo-Verzeichnis an:
git svn clone https://svn.knapp.at/ITSM --preserve-empty-dirs --prefix=svn/ --include-paths="^project1/trunk|^project2/trunk|^some_root/trunk/project3|^archive/project2/trunk|^archive/some_root/trunk/project3" --authors-file authors.txt Linux
Je nach Größe des Repos, kann dies schon etwas dauern. In meinem Beispiel hat das Repo an die 175 GB – dauert locker 10 Stunden. Brechen Sie den Vorgang nicht ab – Sie müssen wieder komplett von vorne beginnen (Verzeichnis löschen und wieder komplett auschecken). Nachdem der Vorgang abgeschlossen ist, können Sie ins Verzeichnis wechseln und sich die einzelnen Commits ansehen:
cd Linux/
git log
Jetzt gehen wir an die ignorierten Dateien – dies ist der längste Vorgang (im Repo-Verzeichnis):
git svn show-ignore > .gitignore
Auch hier – nicht abbrechen, bei meiner oben angegebenen Repo-Größe dauerte dies vier Tage. Die restlichen Befehle runden den Vorgang ab und konvertieren alles perfekt für das Git:
git lfs install
git add -A
git commit -m 'Add .gitignore.'
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
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
for p in $(git for-each-ref --format='%(refname:short)' | grep @); do git branch -D $p; done
git branch -d trunk
Das war die Konvertierung, jetzt können wir das komplette Paket in das gewünschte Git-Repo hochladen, Beispiel:
git remote add origin git@my-git-server:myrepo.git
git push origin --all
git push origin --tags
Bei großen Repos kann der Vorgang schon etwas dauern – aber, es lohnt sich.
Noch keine Reaktion