it-swarm.com.de

Wie importiere ich svn-Zweige und -Tags in git-svn?

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.

64
Luís Guilherme

Sie benötigen mehrere Schritte.

  1. 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
    
  2. 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
    
  3. 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
    
  4. 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
    
  5. Jetzt müssen wir nur noch alte Tags entfernen.

72
Vanuan

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
22
n.r.

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
11

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.

7
rmk

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
5
VonC

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.'
4
carolnogueira

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"
1
Qianlong

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://...

Die git-Mailingliste gab mir den Hinweis.

0
cweiske