Ich habe ein zentrales SVN-Repository, zu dem ich mich verpflichten muss, aber ich habe eine Leidenschaft für git (wie jeder andere Entwickler, den ich kenne). Der Fall ist bekannt.
Dann las ich über git-svn und probierte es aus. Da ich nicht die ganze Geschichte brauche, nur ab zwei Monaten, habe ich Folgendes getan:
git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject
Das Unterprojekt hatte wie üblich die Unterverzeichnisse trunk
, tags
und branches
. Großartig.
Dann, um die letzte Revision zu bekommen, tat ich es
git svn rebase
Einige Downloads später, großartig. Letzte Revision, Protokolle usw. Ok, jetzt wechsle ich zu meinem Funktionszweig.
$ git branch
* master
$ git branch -r
trunk
$ git branch -a
* master
remotes/trunk
Die Fragen lauten: Wo sind meine Filialen? Habe ich etwas falsch gemacht? Wie soll ich tun, um meine Filialen in das neue Git Repo zu bekommen?
git-svn hat, wo immer ich darüber gelesen habe, mit Zweigen und Tags klug verhandelt, aber das Verhalten ist nicht das, was ich erwartet hatte. Vielen Dank!
EDIT: Ich habe gerade herausgefunden, dass git svn fetch
es tun wird. Aber es wird alle Revisionen bekommen, was mir nicht gefallen würde.
Sie benötigen mehrere Schritte.
geben Sie die richtigen Ordnernamen für Trunk, Branches und Tags an und rufen Sie svn repo ab:
git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
git svn fetch
Da Tags in SVN echte Zweige sind, erstellen Sie Git-Tags aus Tag-Zweigen:
git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags | cut -d / -f 3- |
while read ref
do
echo git tag -a $ref -m 'import tag from svn'
done
Tag-Zweige löschen
git for-each-ref --format="%(refname:short)" refs/remotes/tags | cut -d / -f 2- |
while read ref
do
echo git branch -rd $ref
done
Da im vorigen Schritt markierte Tags auf ein Commit "create tag" verweisen, müssen "echte" Tags abgeleitet werden, d. H. Eltern von "create tag" -Commits.
git for-each-ref --format="%(refname:short)" refs/tags |
while read ref
do
tag=`echo $ref | sed 's/_/./g'` # give tags a new name
echo $ref -\> $tag
git tag -a $tag `git rev-list -2 $ref | tail -1` -m "proper svn tag"
done
Jetzt müssen wir nur noch alte Tags entfernen.
Dies basiert auf Vanuans Antwort oben, behält jedoch die message des ursprünglichen svn
-Tags im neuen git
-Tag bei.
$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/tags \
| while read BRANCH REF
do
TAG_NAME=${BRANCH#*/}
BODY="$(git log -1 --format=format:%B $REF)"
echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2
git tag -a -m "$BODY" $TAG_NAME $REF^ &&\
git branch -r -d $BRANCH
done
Dies ist dasselbe wie bei der Antwort von nicolai.rostov, aber ich ändere nur den Refs-Pfad Ich ersetzte refs/remotes/tags
durch refs/remotes/Origin/tags
____. Ich verwende git Version 2.1.1
in cygwin
-Terminal.
$ git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/Origin/tags \
| while read BRANCH REF
do
TAG_NAME=${BRANCH#*/}
BODY="$(git log -1 --format=format:%B $REF)"
echo "ref=$REF parent=$(git rev-parse $REF^) tagname=$TAG_NAME body=$BODY" >&2
git tag -a -m "$BODY" $TAG_NAME $REF^ &&\
git branch -r -d $BRANCH
done
Sie sagen, Sie hätten Ihre Filialen nicht in der Kasse erhalten.
Dies ist wahrscheinlich ein Problem mit dem Layout Ihres SVN-Repos.
Das "Standardlayout" lautet:
branches/
tags/
trunk/
Wenn Sie Ihr Layout so haben:
branches/user1/
branches/user2/
Dann verlieren Sie Ihre Äste, wenn Sie git svn fetch/clone ausführen.
Um dies zu beheben, sollten Sie das Argument angeben
--branches=branches/*/*
zum Klonen von Git.
Wenn Sie Ihre Verzweigungen sehen möchten, wenn Sie einen Git-Zweig nach einem Import aus svn ausführen, sollten Sie das Ruby-Skript svn2git (und git2svn) verwenden.
Es ist besser als git svn clone, denn wenn Sie diesen Code in svn haben:
trunk
...
branches
1.x
2.x
tags
1.0.0
1.0.1
1.0.2
1.1.0
2.0.0
git-svn
durchläuft die Commit-Historie, um ein neues Git-Repo zu erstellen.
Es werden alle Verzweigungen und Tags als entfernte SVN-Verzweigungen importiert. Was Sie wirklich wollen, sind git-native lokale Verzweigungen und git-Tag-Objekte . Nach dem Import dieses Projekts würden Sie also Folgendes erhalten:
$ git branch
* master
$ git branch -a
* master
1.x
2.x
tags/1.0.0
tags/1.0.1
tags/1.0.2
tags/1.1.0
tags/2.0.0
trunk
$ git tag -l
[ empty ]
Nachdem svn2git
mit Ihrem Projekt fertig ist, erhalten Sie Folgendes:
$ git branch
* master
1.x
2.x
$ git tag -l
1.0.0
1.0.1
1.0.2
1.1.0
2.0.0
Ich habe ein Skript geschrieben, mit dem Sie nach Belieben migrieren können. Das Skript ist nicht perfekt, aber ich hoffe, das könnte Ihnen helfen:
Weitere Informationen finden Sie unter: https://github.com/MPDFT/svn-to-git
#!/bin/bash
####### Project name
PROJECT_NAME="myproject"
EMAIL="mycompany.com"
###########################
####### SVN
# SVN repository to be migrated
BASE_SVN="http://svn.mycompany.com/svn/repo/sistemas/myproject"
# Organization inside BASE_SVN
BRANCHES="branches"
TAGS="tags"
TRUNK="trunk"
###########################
####### GIT
# Git repository to migrate
GIT_URL="https://git.mycompany.com/git/repo/sistemas/myproject.git"
###########################
#### Don't need to change from here
###########################
# Geral Configuration
ABSOLUTE_PATH=$(pwd)
TMP=$ABSOLUTE_PATH/"migration-"$PROJECT_NAME
# Branchs Configuration
SVN_BRANCHES=$BASE_SVN/$BRANCHES
SVN_TAGS=$BASE_SVN/$TAGS
SVN_TRUNK=$BASE_SVN/$TRUNK
AUTHORS=$PROJECT_NAME"-authors.txt"
echo '[LOG] Starting migration of '$SVN_TRUNK
echo '[LOG] Using: '$(git --version)
echo '[LOG] Using: '$(svn --version | grep svn,)
mkdir $TMP
cd $TMP
echo
echo '[LOG] Getting authors'
svn log -q $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2"@"$EMAIL">"}' | sort -u >> $AUTHORS
echo
echo '[RUN] git svn clone --authors-file='$AUTHORS' --trunk='$TRUNK' --branches='$BRANCHES' --tags='$TAGS $BASE_SVN $TMP
git svn clone --authors-file=$AUTHORS --trunk=$TRUNK --branches=$BRANCHES --tags=$TAGS $BASE_SVN $TMP
echo
echo '[LOG] Getting first revision'
FIRST_REVISION=$( svn log -r 1:HEAD --limit 1 $BASE_SVN | awk -F '|' '/^r/ {sub("^ ", "", $1); sub(" $", "", $1); print $1}' )
echo
echo '[RUN] git svn fetch -'$FIRST_REVISION':HEAD'
git svn fetch -$FIRST_REVISION:HEAD
echo
echo '[RUN] git remote add Origin '$GIT_URL
git remote add Origin $GIT_URL
echo
echo '[RUN] svn ls '$SVN_BRANCHES
for BRANCH in $(svn ls $SVN_BRANCHES); do
echo git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
git branch ${BRANCH%/} remotes/svn/${BRANCH%/}
done
git for-each-ref --format="%(refname:short) %(objectname)" refs/remotes/Origin/tags | grep -v "@" | cut -d / -f 3- |
while read ref
do
echo git tag -a $ref -m 'import tag from svn'
git tag -a $ref -m 'import tag from svn'
done
git for-each-ref --format="%(refname:short)" refs/remotes/Origin/tags | cut -d / -f 1- |
while read ref
do
git branch -rd $ref
done
echo
echo '[RUN] git Push'
git Push Origin --all --force
git Push Origin --tags
echo 'Sucessufull.'
Für diejenigen, die am Arbeitsplatz unter Windows arbeiten müssen, finden Sie hier eine aktuelle Version der git-Version 2.17.0 (und funktioniert theoretisch auch bei früheren Versionen).
git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
git svn fetch
for /f "tokens=1-2 delims= " %a in ('git for-each-ref --format="%(refname:lstrip=-1) %(objectname)" refs/remotes/Origin/tags') do git tag -a %a %b -m "import tag from svn"
Ich hatte das gleiche Problem - Tags und Verzweigungen fehlten, als ich die Revision spezifizierte:
$ git svn clone -r 34000 -s https://...
Das Update bestand darin, eine Reihe von Revisionen anzugeben, -r 34000:HEAD
:
$ git svn clone -r 34000:HEAD -s https://...