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.
Ich brauchte das auch, und mit Hilfe von Bombes Antwort + ein bisschen Herumspielen habe ich es geschafft. Hier ist das Rezept:
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.
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
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.
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.
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.
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
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.
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:
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`
Geh dorthin:
cd repo.git-svn
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/
Rufen Sie die Informationen vom Hauptzweig aus dem alten Repository in das aktuelle Repository ab:
git fetch old-git master
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`
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
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.
Schieben Sie Ihre Arbeit an SVN:
git svn dcommit
Das ist alles. Es ist sehr sauber, kein Hacking, und alles funktioniert perfekt. Genießen.
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.
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 .
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
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.
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).
Die notwendigen Pakete:
$ Sudo apt-get install git Subversion Mercurial python-Subversion
Mercurial muss konfiguriert werden, indem Folgendes zu ~/.hgrc
hinzugefügt wird:
[extensions]
hgext.convert=
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
Erstellen Sie ein leeres lokales SVN-Repository:
$ svnadmin create svn/project
Klonen Sie das vorhandene Git-Repository:
$ git clone server/path/project.git git/project
Lassen Sie Mercurial sein Ding tun:
$ hg convert --dest-type svn git/project svn/project
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.
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
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.
Ü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 ..
Das Depot ausgeben:
$ svnadmin dump svn/project > project.dump
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.
Eine weitere Sequenz, die funktioniert hat (mit einigen Kommentaren zu jedem Schritt):
Installieren Sie git-svn
- und Subversion
-Toolkits:
Sudo apt-get install git-svn Subversion
Wechseln Sie im PROJECT_FOLDER
cd PROJECT_FOLDER
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.
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.
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.
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
Neue/modifizierte Dateien zum Festschreiben hinzufügen (dieser Schritt ist für Git-Aktivitäten regelmäßig und ist optional).
git add .
Ü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"
Den gesamten Verlauf der Projektänderungen auf den Subversion-Server übertragen:
git svn dcommit
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.
es gibt drei Methoden:
rebase: wie die anderen Antworten
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
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
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.
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