web-dev-qa-db-ja.com

SVNブランチとタグをgit-svnにインポートするにはどうすればよいですか?

私はコミットしなければならない中央SVNリポジトリを持っていますが、git(私が知っている他の開発者と同じように)に情熱を持っています。ケースはよく知られています。

それからgit-svnについて読み、試してみました。私は完全な履歴を必要としないので、ちょうど2か月かそこらから、私はこれが好きでした:

git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject

SubProjectには、通常どおり、サブディレクトリtrunktags、およびbranchesがありました。すばらしいです。

次に、最後のリビジョンを取得するために、私はやった

git svn rebase

後でいくつかのダウンロード、素晴らしい。最後のリビジョン、ログなど。OK、機能ブランチに切り替えます。

$ git branch 
* master
$ git branch -r  
  trunk
$ git branch -a  
* master
  remotes/trunk

質問は次のとおりです。私の支店はどこですか?私は何か間違ったことをした?新しいgitリポジトリでブランチを取得するにはどうすればよいですか?

git-svnは、私がそれについて読んだところはどこでも、ブランチとタグを賢く扱っていましたが、その振る舞いは私が期待したものではありませんでした。ありがとう!

[〜#〜] edit [〜#〜]git svn fetchはそれを行います。しかし、それはすべてのリビジョンを取得します。これは私が好まないものです。

65
Luís Guilherme

いくつかの手順が必要です。

  1. 適切なトランク、ブランチ、タグのフォルダー名を指定し、svnリポジトリを取得します。

    git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
    git svn fetch
    
  2. Svnのタグは実際のブランチであるため、タグブランチからgitタグを作成します。

    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. タグブランチを削除する

    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. 前の手順でマークされたタグは「タグの作成」コミットを指すため、「実際の」タグ、つまり「タグの作成」コミットの親を導出する必要があります。

    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. あとは、古いタグを削除するだけです。

74
Vanuan

これは、上記のVanuanの回答に基づいていますが、元のsvnタグのmessageを新しいgitタグに保存します。

$ 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.

これは上記のnicolai.rostovの答えと同じですが、置き換えた参照パスを変更するだけですrefs/remotes/tags by refs/remotes/Origin/tags gitバージョンを使用しています2.1.1 into cygwinターミナル。

$ 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
12

あなたはあなたのチェックアウトであなたの枝を得ていないと言います。

これは、svnリポジトリのレイアウトに問題がある可能性があります。

「標準レイアウト」は次のとおりです。

branches/

tags/

trunk/

このようなレイアウトがある場合:

branches/user1/

branches/user2/

その後、git svn fetch/cloneを実行するとブランチが失われます。

これを修正するには、引数を与える必要があります

--branches=branches/*/*からgit cloneへ。

8
rmk

Svnからインポートした後にgitブランチを実行するときにブランチを表示するには、Ruby script svn2git(and git2svn )

Svnに次のコードがある場合、git svn cloneよりも優れています。

  trunk
    ...
  branches
    1.x
    2.x
  tags
    1.0.0
    1.0.1
    1.0.2
    1.1.0
    2.0.0

git-svnはコミット履歴を調べて新しいgitリポジトリを作成します。
すべてのブランチとタグをリモートSVNブランチとしてインポートしますが、実際に必要なのはgitネイティブのローカルブランチとgitタグオブジェクトです。したがって、このプロジェクトをインポートすると、次のようになります。

  $ 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 ]

プロジェクトでsvn2gitが完了すると、代わりに次のようになります。

  $ 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

必要に応じて移行できるスクリプトを作成しました。スクリプトは完璧ではありませんが、これがあなたの助けになることを願っています。

詳細については、以下をご覧ください。 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

職場でWindowsを使用しなければならない人のために、gitバージョン2.17.0で最新のソリューションを示します(理論的には以前のバージョンでも動作します)

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

私は同じ問題を抱えていました-リビジョンを指定したときにタグとブランチが欠落していました:

$ git svn clone -r 34000 -s https://...

修正は、リビジョンの範囲を指定することでした、-r 34000:HEAD

$ git svn clone -r 34000:HEAD -s https://...

gitメーリングリストがヒントをくれました

0
cweiske