私はコミットしなければならない中央SVNリポジトリを持っていますが、git(私が知っている他の開発者と同じように)に情熱を持っています。ケースはよく知られています。
それからgit-svnについて読み、試してみました。私は完全な履歴を必要としないので、ちょうど2か月かそこらから、私はこれが好きでした:
git svn clone -r 34000 -s https://svn.ourdomain.com/svn/repos/Project/SubProject
SubProjectには、通常どおり、サブディレクトリtrunk
、tags
、および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
はそれを行います。しかし、それはすべてのリビジョンを取得します。これは私が好まないものです。
いくつかの手順が必要です。
適切なトランク、ブランチ、タグのフォルダー名を指定し、svnリポジトリを取得します。
git svn init -t tags -b branches -T trunk https://mysvn.com/svnrepo
git svn fetch
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
タグブランチを削除する
git for-each-ref --format="%(refname:short)" refs/remotes/tags | cut -d / -f 2- |
while read ref
do
echo git branch -rd $ref
done
前の手順でマークされたタグは「タグの作成」コミットを指すため、「実際の」タグ、つまり「タグの作成」コミットの親を導出する必要があります。
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
あとは、古いタグを削除するだけです。
これは、上記の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
これは上記の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
あなたはあなたのチェックアウトであなたの枝を得ていないと言います。
これは、svnリポジトリのレイアウトに問題がある可能性があります。
「標準レイアウト」は次のとおりです。
branches/
tags/
trunk/
このようなレイアウトがある場合:
branches/user1/
branches/user2/
その後、git svn fetch/cloneを実行するとブランチが失われます。
これを修正するには、引数を与える必要があります
--branches=branches/*/*
からgit cloneへ。
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
必要に応じて移行できるスクリプトを作成しました。スクリプトは完璧ではありませんが、これがあなたの助けになることを願っています。
詳細については、以下をご覧ください。 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.'
職場で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"
私は同じ問題を抱えていました-リビジョンを指定したときにタグとブランチが欠落していました:
$ git svn clone -r 34000 -s https://...
修正は、リビジョンの範囲を指定することでした、-r 34000:HEAD
:
$ git svn clone -r 34000:HEAD -s https://...