it-swarm.com.de

Ein vorhandenes Git-Repository an SVN übertragen

Ich habe meine ganze Arbeit in Git gemacht und zu GitHub gepusht. Ich war sowohl mit der Software als auch mit der Website sehr zufrieden und möchte an dieser Stelle nicht meine Arbeitsmethoden ändern.

Mein Doktorandenberater bittet alle Studenten, ihre Arbeit in einem SVN-Repository zu behalten, das an der Universität gehostet wird. Ich habe unzählige Dokumentationen und Tutorials über das Herunterfahren eines vorhandenen SVN-Repositorys in Git gefunden, aber nichts darüber, ein Git-Repository in ein neues SVN-Repository zu verschieben. Ich denke, es muss einen Weg geben, dies mit einer Kombination aus git-svn und einem frischen Zweig und Rebasing und all den wunderbaren Begriffen zu tun, aber ich bin ein Git-Neuling und fühle mich bei keinem von ihnen sicher.

Ich möchte dann nur ein paar Befehle ausführen, um Commits in das SVN-Repository zu verschieben, wenn ich dies auswähle. Ich möchte Git weiterhin verwenden und habe einfach das SVN-Repository gespiegelt, was in Git ist.

Ich bin die einzige Person, die sich jemals für SVN engagiert, wenn dies einen Unterschied macht.

375
cflewis

Ich brauchte das auch, und mit Hilfe von Bombes Antwort + ein bisschen Herumspielen habe ich es geschafft. Hier ist das Rezept:

Importieren Sie Git -> Subversion

1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase Origin/trunk
5.1.  git status
5.2.  git add (conflicted-files)
5.3.  git rebase --continue
5.4.  (repeat 5.1.)
6. git svn dcommit

Nach # 3 erhalten Sie eine kryptische Nachricht wie diese:

Verwendung einer höheren URL-Ebene: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo

Ignoriere das einfach.

Wenn Sie # 5 ausführen, erhalten Sie möglicherweise Konflikte. Lösen Sie diese auf, indem Sie Dateien mit dem Status "nicht zusammengeführt" hinzufügen und die Rebase fortsetzen. Irgendwann wirst du fertig sein; dann mit dcommit wieder zum SVN-Repository synchronisieren. Das ist alles.

Repositories synchron halten

Sie können jetzt mit den folgenden Befehlen von SVN nach Git synchronisieren:

git svn fetch
git rebase trunk

Um von Git zu SVN zu synchronisieren, verwenden Sie:

git svn dcommit

Schlussnote

Möglicherweise möchten Sie dies auf einer lokalen Kopie ausprobieren, bevor Sie sich für ein Live-Repository bewerben. Sie können eine Kopie Ihres Git-Repository an einen temporären Ort erstellen. Verwenden Sie einfach cp -r, da sich alle Daten im Repository selbst befinden. Sie können dann ein dateibasiertes Test-Repository einrichten.

svnadmin create /home/name/tmp/test-repo

Und checke eine Arbeitskopie aus mit:

svn co file:///home/name/tmp/test-repo svn-working-copy

So können Sie mit Dingen herumspielen, bevor Sie dauerhafte Änderungen vornehmen.

Nachtrag: Wenn Sie versauen git svn init

Wenn Sie git svn init versehentlich mit der falschen URL ausgeführt haben und nicht intelligent genug waren, um ein Backup Ihrer Arbeit zu erstellen (fragen Sie nicht nach ...), können Sie denselben Befehl nicht noch einmal ausführen. Sie können die Änderungen jedoch rückgängig machen, indem Sie Folgendes ausgeben:

rm -rf .git/svn
edit .git/config

Entfernen Sie den Abschnitt [svn-remote "svn"].

Sie können dann git svn init erneut ausführen.

395
troelskn

So haben wir es geschafft:

Klonen Sie Ihr Git-Repository irgendwo auf Ihrem Rechner.

Öffnen Sie .git/config und fügen Sie Folgendes hinzu (aus Nur-Lese-SVN-Spiegel eines Git-Repositorys pflegen):

[svn-remote "svn"]
    url = https://your.svn.repo
    fetch = :refs/remotes/git-svn

Geben Sie nun in einem Konsolenfenster Folgendes ein:

git svn fetch svn
git checkout -b svn git-svn
git merge master

Wenn es aus irgendeinem Grund hier bricht, geben Sie diese drei Zeilen ein:

git checkout --theirs .
git add .
git commit -m "some message"

Und schließlich können Sie sich an SVN festlegen:

git svn dcommit

Hinweis: Ich verschrotte diesen Ordner immer danach.

29
Alex Rouillard

Die direkte Verwendung von git rebase verliert den ersten Commit. Git behandelt es anders und kann es nicht widerlegen.

Es gibt ein Verfahren, das die vollständige Historie aufrechterhält: http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

Ich werde die Lösung hier transkribieren, aber Credits sind für Björn.

Git-svn initialisieren:

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

Der --prefix gibt Ihnen Remote-Tracking-Zweige wie "svn/trunk", was "Nice" ist, weil Sie keine mehrdeutigen Namen erhalten, wenn Sie Ihren lokalen Zweig nur "trunk" nennen. Und -s ist eine Abkürzung für das Standardlayout für Stamm/Tags/Zweige.

Holen Sie sich die ersten Sachen von SVN:

git svn fetch

Schauen Sie sich nun den Hash Ihres Root-Commits an (sollte einen einzigen Commit anzeigen):

git rev-list --parents master | grep '^.\{40\}$'

Dann holen Sie den Hash des leeren Trunk Commits:

git rev-parse svn/trunk

Erstellen Sie das Transplantat:

echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts

"Gitk" sollte jetzt svn/trunk als ersten Commit anzeigen, auf dem Ihr Hauptzweig basiert.

Machen Sie das Transplantat dauerhaft:

git filter-branch -- ^svn/trunk --all

Lass das Transplantat fallen:

rm .git/info/grafts

gitk sollte noch svn/trunk in der Abstammung von master anzeigen.

Linearisieren Sie Ihre Geschichte auf dem Rumpf:

git svn rebase

Und jetzt sollte "git svn dcommit -n" Ihnen sagen, dass es sich um einen Trunk handelt.

git svn dcommit
27
Dardo Sordi

Erstellen Sie im Subversion-Repository ein neues Verzeichnis für Ihr Projekt.

# svn mkdir --parents svn://ip/path/project/trunk

Wechseln Sie zu Ihrem von Git verwalteten Projekt und initialisieren Sie git-svn.

# git svn init svn://ip/path/project -s
# git svn fetch

Dadurch wird ein einzelner Commit erstellt, da Ihr SVN-Projektverzeichnis noch leer ist. Jetzt überdenken Sie alles in diesem Commit git svn dcommit und Sie sollten fertig sein. Es wird jedoch Ihre Commit-Daten ernsthaft durcheinander bringen.

8
Bombe

Git -> SVN mit vollständiger Commit-Historie

Ich hatte ein Git-Projekt und musste es in SVN verschieben. So habe ich es geschafft und die ganze Commit-Geschichte behalten. Das einzige, was verloren geht, ist die ursprüngliche Commit-Zeit, da libSVN die Ortszeit festlegt, wenn git svn dcommit ausgeführt wird.

Wie man:

  1. Besitze ein SVN-Repository, in das wir unsere Sachen importieren und mit git-svn klonen wollen:

    git svn clone https://path.to/svn/repository repo.git-svn`
    
  2. Geh dorthin:

    cd repo.git-svn
    
  3. Fügen Sie das Remote des Git-Repository hinzu (in diesem Beispiel verwende ich C: /Projects/repo.git). Sie möchten auf SVN drücken und ihm den Namen old-git geben:

    git remote add old-git file:///C/Projects/repo.git/
    
  4. Rufen Sie die Informationen vom Hauptzweig aus dem alten Repository in das aktuelle Repository ab:

    git fetch old-git master
    
  5. Kassen Sie den Master-Zweig der Old-Git-Fernbedienung in einen neuen Zweig mit dem Namen Old im aktuellen Repository ein:

    git checkout -b old old-git/master`
    
  6. Bauen Sie den HEAD auf Old-git/master auf. Dadurch werden alle Ihre Commits beibehalten. Im Grunde nehmen Sie Ihre gesamte Arbeit in Git und fügen Sie sie der Arbeit hinzu, auf die Sie von SVN aus zugreifen.

    git rebase master
    
  7. Gehen Sie jetzt zurück zu Ihrem Hauptzweig:

    git checkout master
    

    Und Sie können sehen, dass Sie eine reine Commit-Historie haben. Dies ist, was Sie zu SVN schieben möchten.

  8. Schieben Sie Ihre Arbeit an SVN:

    git svn dcommit
    

Das ist alles. Es ist sehr sauber, kein Hacking, und alles funktioniert perfekt. Genießen.

7
codingdave

Ich würde in 4 Befehlen eine sehr kurze Anweisung mit SubGit vorschlagen. Siehe post für Details.

4
Dmitry Pavlenko

Ich musste mein vorhandenes Git-Repository an ein leeres SVN-Repository übergeben.

So habe ich es geschafft:

$ git checkout master
$ git branch svn
$ git svn init -s --prefix=svn/ --username <user> https://path.to.repo.com/svn/project/
$ git checkout svn
$ git svn fetch
$ git reset --hard remotes/svn/trunk
$ git merge master
$ git svn dcommit

Es hat ohne Probleme geklappt. Ich hoffe das hilft jemandem.

Da ich mich mit einem anderen Benutzernamen im SVN-Repository autorisieren musste (meine Origin verwendet private/öffentliche Schlüsselauthentifizierung), musste ich die --username-Eigenschaft verwenden.

3
Jay Linski

Wenn Sie weiterhin mit Git als Haupt-Repository arbeiten möchten und die Revisionen nur von Zeit zu Zeit in SVN "exportieren" müssen, können Sie das SVN-Repository mit Tailor synchronisieren. Es kann Revisionen zwischen verschiedenen Quellcodeverwaltungssystemen kopieren und würde die SVN mit den Änderungen aktualisieren, die Sie in Git vornehmen.

Ich habe keine Git-zu-SVN-Konvertierung versucht, aber für ein SVN -> SVN-Beispiel siehe diese Antwort .

2
sth

Wenn Sie keine bestimmte SVN verwenden müssen und GitHub verwenden, können Sie deren SVN-Connector verwenden.

Weitere Informationen finden Sie hier: Zusammenarbeit mit Subversion auf GitHub

1
elMarioFredo

Ich möchte ein tolles Werkzeug mit dem Namen Scatter teilen, das in der WordPress-Community verwendet wird

Git WordPress Plugins und ein bisschen Vernunftstreuung 

Auf diese Weise können Benutzer ihr Git-Repository automatisch an SVN WordPress.org senden. Theoretisch kann dieser Code auf jedes SVN-Repository angewendet werden.

1
r109

Ich musste vor kurzem mehrere Git-Repositories zu SVN migrieren, und nachdem ich alle Lösungen ausprobiert hatte, die ich finden konnte, funktionierte schließlich Mercurial (ja, unter Verwendung eines dritten VCS). Mit diesem Leitfaden habe ich den folgenden Prozess entwickelt (unter Linux, aber die Grundidee sollte auch unter Windows funktionieren).

  1. Die notwendigen Pakete:

    $ Sudo apt-get install git Subversion Mercurial python-Subversion
    
  2. Mercurial muss konfiguriert werden, indem Folgendes zu ~/.hgrc hinzugefügt wird:

    [extensions]
    hgext.convert=
    
  3. Erstellen Sie temporäre Arbeitsverzeichnisse (ich hatte mehrere Repositorys zum Migrieren, also habe ich Verzeichnisse für die SVN- und Git-Versionen erstellt, um sie voneinander zu trennen):

    $ mkdir svn
    $ mkdir git
    
  4. Erstellen Sie ein leeres lokales SVN-Repository:

    $ svnadmin create svn/project
    
  5. Klonen Sie das vorhandene Git-Repository:

    $ git clone server/path/project.git git/project
    
  6. Lassen Sie Mercurial sein Ding tun:

    $ hg convert --dest-type svn git/project svn/project
    
  7. Nun sollte das SVN-Repository den vollständigen Commit-Verlauf enthalten, jedoch nicht mit den ursprünglichen Zeitstempeln. Wenn dies kein Problem ist, überspringen Sie den nächsten Teil zu Schritt 11.

  8. Mit etwas Arbeit können Datum und Uhrzeit jedes Commits geändert werden . Da meine Repositories relativ klein sind, war es für mich machbar, dies manuell durchzuführen. Erstellen Sie zunächst einen pre-revprop-change-Hook mit folgenden Inhalten im SVN-Repository, damit die erforderliche Eigenschaft geändert werden kann:

    #!/bin/bash
    exit 0;
    

    Dieses Skript muss ausführbar gemacht werden:

    $ chmod +x svn/project/hooks/pre-revprop-change
    
  9. Mercurial hat eine Arbeitskopie des SVN-Repositorys mit dem Namen project -wc erstellt. Wechseln Sie dazu und bearbeiten Sie die Commit-Zeiten:

    $ cd project-wc
    $ svn propedit svn:date --revprop -r 1
    

    Geben Sie Datum und Uhrzeit korrekt ein (achten Sie auf die Zeitzonen!) Und speichern Sie. Sie sollten eine Meldung erhalten, die besagt, dass "Neuer Wert für die Eigenschaft svn: date in Version 1 festgelegt wird".
    Nun spülen und wiederholen Sie für jede andere Revision.

  10. Überprüfen Sie optional den Commit-Verlauf, um sicherzustellen, dass alles in Ordnung ist:

    $ svn log -r 1:HEAD
    

    Dann geh eine Ebene zurück:

    $ cd ..
    
  11. Das Depot ausgeben:

    $ svnadmin dump svn/project > project.dump
    
  12. Laden Sie den Dump auf Ihren Subversion-Server. Erledigt!

Dieser Prozess würde wahrscheinlich auch direkt zwischen entfernten Repositorys funktionieren, aber es fiel mir leichter, mit lokalen Repositorys zu arbeiten. Das Festschreiben der Commit-Zeiten war eine Menge Arbeit, aber insgesamt war der Prozess viel einfacher als jede andere Methode, die ich gefunden habe.

0
Indrek

Eine weitere Sequenz, die funktioniert hat (mit einigen Kommentaren zu jedem Schritt):

  1. Installieren Sie git-svn- und Subversion-Toolkits:

    Sudo apt-get install git-svn Subversion
    
  2. Wechseln Sie im PROJECT_FOLDER

    cd PROJECT_FOLDER
    
  3. Erstellen Sie den Projektpfad auf dem Subversion-Server (leider ist das aktuelle git-svn-Plugin im Vergleich zu TortoiseSVN defekt). Es ist nicht möglich, Quellcode direkt in PROJECT_FOLDER zu speichern. Stattdessen wird standardmäßig der gesamte Code in PROJECT_FOLDER/trunk hochgeladen.

    svn mkdir --parents protocol: /// pfad/to/repo/PROJECT_FOLDER/trunk -m "git repo platzhalter erstellen"

Dies ist der Ort, an dem trunk am Ende des Pfads required ist.

  1. Initialisieren Sie den git-svn-Plugin-Kontext im Ordner .git

    git svn init -s protocol:///path/to/repo/PROJECT_FOLDER
    

    Dies ist der Ort, an dem trunk am Ende des Pfads unnötig ist.

  2. Rufen Sie eine leere Subversion-Repository-Information ab

    git svn fetch
    

    Dieser Schritt hilft beim Synchronisieren des Subversion-Servers mit dem git-svn-Plugin. Dies ist der Moment, wenn git-svn plugin den remotes/Origin-Pfad einrichtet und ihn dem trunk-Unterordner auf der Serverseite zuordnet.

  3. Die alten Git-Commits wurden zurückgesetzt, bevor das git-svn-Plugin in den Prozess einbezogen wurde (dieser Schritt ist optional).

    git rebase Origin/trunk
    
  4. Neue/modifizierte Dateien zum Festschreiben hinzufügen (dieser Schritt ist für Git-Aktivitäten regelmäßig und ist optional).

    git add .
    
  5. Übertragen Sie neu hinzugefügte Dateien in das lokale Git-Repository (dieser Schritt ist optional und gilt nur, wenn Schritt 7 verwendet wurde):

    git commit -m "Importing Git repository"
    
  6. Den gesamten Verlauf der Projektänderungen auf den Subversion-Server übertragen:

    git svn dcommit
    
0
Oleg Kokorin

Sie können ein neues SVN-Repository erstellen. Exportieren Sie Ihr Git-Projekt (verfeinern Sie die .git-Dateien). Fügen Sie es dem SVN-Repository hinzu (initialisieren Sie das Repository mit dem, was Sie bisher in Git hatten) und verwenden Sie die Anweisungen zum Importieren von SVN-Repositorys in einem neuen Git-Projekt.

Dies verliert jedoch Ihre bisherige Git-Historie. 

0
Vasil

es gibt drei Methoden:

  1. rebase: wie die anderen Antworten

  2. festschreibungs-ID: svn zuerst finden Festschreibungs-ID und git zuerst festschreibungs-ID, deren Echo in .git/info/grafts: echo "git_id svn_id}" > .git/info/grafts dann git svn dcommit

  3. checkout every git commit, kopiere die Dateien nach svn_repo, svn commit

bash-Demo: Github-Demo

v1.x: Verwenden Sie rebase und übergeben Sie die ID

v2.x: Kopierdateien verwenden, dann svn commit

0
张耀文

Ich möchte nur einige meiner Erfahrungen mit der akzeptierten Antwort teilen. Ich habe alle Schritte gemacht und alles war gut, bevor ich den letzten Schritt ausgeführt habe:

git svn dcommit

$ git svn dcommit

Verwendung des nicht initialisierten Werts $ u in der Ersetzung (s ///) in der Zeile /usr/lib/Perl5/vendor_Perl/5.22/Git/SVN.pm.

Verwendung des nicht initialisierten Wertes $ u in Verkettung (.) Oder Zeichenfolge in der Zeile /usr/lib/Perl5/vendor_Perl/5.22/Git/SVN.pm Zeile 101 . refs/remotes/Origin/HEAD: ' https://192.168.2.101/svn/PROJECT_NAME ' nicht gefunden in ''

Ich habe den Thread https://github.com/nirvdrum/svn2git/issues/50 gefunden und schließlich die Lösung, die ich in der folgenden Datei in Zeile 101 angewendet habe: usr/lib/Perl5/vendor_Perl /5.22/Git/SVN.pm

Ich ersetzte

$u =~ s!^\Q$url\E(/|$)!! or die

mit

if (!$u) {
    $u = $pathname;
} 
else {
       $u =~ s!^\Q$url\E(/|$)!! or die
      "$refname: '$url' not found in '$u'\n";
}

Dies hat mein Problem behoben.

0

In meinem Fall musste ich ein sauberes Projekt von SVN initiieren

$ Project> git svn init protocol://path/to/repo -s
$ Project> git svn fetch

fügen Sie alle Ihre Projektquellen hinzu ...

$ Project> git add .
$ Project> git commit -m "Importing project sources"
$ Project> git svn dcommit
0
dangt85