git-svnを介してミラーリングしているsvnリポジトリのURLが変更されました。
バニラsvnではあなたはただするでしょうsvn switch --relocate old_url_base new_url_base
。
git-svnを使用してこれを行うにはどうすればよいですか?
設定ファイルのsvnurlを変更するだけでは失敗します。
git-svnを介してミラーリングしているsvnリポジトリのURLが変更されました。
バニラsvnではあなたはただするでしょうsvn switch --relocate old_url_base new_url_base
。
git-svnを使用してこれを行うにはどうすればよいですか?
設定ファイルのsvnurlを変更するだけでは失敗します。
回答:
これは私の状況をかなりうまく処理します:
https://git.wiki.kernel.org/index.php/GitSvnSwitch
file://
プロトコルを使用してクローンを作成し、プロトコルに切り替えたいと思いましたhttp://
。
url
の[svn-remote "svn"]
セクションで設定を編集したくなります.git/config
が、それだけでは機能しません。一般に、次の手順に従う必要があります。
url
設定を新しい名前に切り替えます。git svn fetch
。これはsvnから少なくとも1つの新しいリビジョンをフェッチする必要があります!url
設定を元のURLに戻します。git svn rebase -l
ローカルリベースを実行するために実行します(最後のフェッチ操作で発生した変更を使用)。url
設定を新しいURLに戻します。git svn rebase
再び動作するはずです。冒険心のある人は試してみたいかもしれません--rewrite-root
。
以下が正常に機能するかどうかを確認できます。
svn-remote.svn.rewriteRoot
設定ファイルに存在しない場合(.git/config
):
git config svn-remote.svn.rewriteRoot <currentRepositoryURL>
svn-remote.svn.rewriteUUID
設定ファイルに存在しない場合:
git config svn-remote.svn.rewriteUUID <currentRepositoryUUID>
currentRepositoryUUID
から入手することができます.git/svn/.metadata
。
git config svn-remote.svn.url <newRepositoryURL>
file://
で複製、に切り替えsvn+ssh
); この手順では、「svnから少なくとも1つの新しいリビジョンをフェッチする」必要はありません。また、./.git/svn/.metadata
後の最初のsvn rebase
含まれている<newRepository>
としてreposRoot
-しかし、これは除去するのに十分ではないrewrite*
から鍵を.git/config
、したがって、私が理解している限り、これらのキーは永続的にそこに保持する必要があります。
svn+ssh://
しているのですが、svn-serverがドメインをから.se
に変更し.com
て内部の名前をサニタイズしました。
残念ながら、これらの回答のほとんどのリンクは機能していないため、今後の参考のためにgitwikiから少し情報を複製します。
この解決策は私のために働いた:
svn-remote
url
(またはfetch
パス)を編集し.git/config
て、新しいドメイン/ URL /パスを指すようにします
gitを実行しますgit svn fetch
。これはsvnから少なくとも1つの新しいリビジョンをフェッチする必要があります!
git svn rebase
今すぐ試行すると、次のようなエラーメッセージが表示されます。
Unable to determine upstream SVN information from working tree history
これはgit svn
、フェッチ前の最新のコミットが、でgit-svn-id
見つかったパスと一致しない古いパスを指しているという事実によって混乱しているためだと思います.git/config
。
回避策として、元のドメイン/ URL /パスに変更svn-remote
url
(またはfetch
パス)してください
ここでgit svn rebase -l
再度実行して、最後のフェッチ操作で発生した変更を使用してローカルリベースを実行します。今回は、新しいヘッドのがで見つかったものと一致しないという事実によって混乱しないため、これは機能します。git svn
git-svn-id
.git/config
最後に、svn-remote
url
(またはfetch
パスを)新しいドメイン/ URL /パスに戻します
この時点git svn rebase
で再び機能するはずです!
GitsvnはsvnURLに大きく依存しています。svnからインポートされるすべてのコミットにgit-svn-id
は、svnURLを含むがあります。
有効な再配置戦略はgit-svn clone
、新しいリポジトリを呼び出し、変更をその新しいクローズにマージすることです。より詳細な手順については、次の記事を参照してください。
http://www.sanityinc.com/articles/relocating-git-svn-repositories
git filter-branch
ブログエントリから取られたこのスクリプトは、私のために機能しました。の場合と同様に、新旧のリポジトリURLをパラメータとして指定しますsvn switch --relocate
。
スクリプトは、コミットメッセージ内のgit filter-branch
Subversion URLを置き換えるために呼び出しgit-svn-id
、を更新し.git/config
、をgit-svn
使用してメタデータを再作成することによってメタデータを更新しますgit svn rebase
。一方でgit svn clone
、より堅牢なソリューションかもしれないが、filter-branch
アプローチは巨大なリポジトリ(日対時間)のためにはるかに高速に動作します。
#!/bin/sh
# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]
then
echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
exit $E_NO_ARGS
fi
# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`
filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all
sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config
rm -rf .git/svn
git svn rebase
git_fast_filter
それでもgit-filter-branch
(つまり、数時間ではなく数分)より高速ですが、精神的には似ていますが、を使用することgit_fast_filter
です。ただし、これにはもう少しコーディングが必要であり、きちんとした既製のソリューションは存在しません。とは対照的にgit-filter-branch
、これは古いリポジトリから新しいリポジトリを作成します。最後のSVNコミットを指していると想定されます。master
git_fast_filter
Gitoriousレポからクローンを作成します。git_fast_filter
基づいてクローンを作成したのと同じディレクトリにPythonスクリプトを作成し、を使用して実行可能ビットを設定します。古いリポジトリパスと新しいリポジトリパスを適応させます。(スクリプトの内容も下に貼り付けられています。)chmod +x
git init
作業ディレクトリをこの新しいリポジトリに変更します。次のパイプを実行します。
(cd path/to/old/repo && git-fast-export --branches --tags --progress=100) | \
path/to/git_fast_filter/commit_filter.py | git-fast-import
.git/config
、およびおそらく他の関連ファイルを.git/info
古いリポジトリから新しいリポジトリにコピーします。
.git/svn
ます。git-svn
新しいリビジョン番号のマッピングに注意してください
実行する git branch refs/remotes/git-svn master
refs/remotes/git-svn
場合が.git/config
ありsvn-remote
ます。実行しgit svn info
ます。このコマンドがフリーズする場合は、何か問題があります。リビジョン番号のマッピングを再構築する必要があります。
偽のブランチを削除すると、refs/remotes/git-svn
によって再作成されますgit-svn
git svn rebase
ます。下記の内容ですcommit_filter.py
の値置き換え、IN_REPO
そしてOUT_REPO
適切には:
#!/usr/bin/python
from git_fast_filter import Commit, FastExportFilter
import re
import sys
IN_REPO = "https://svn.code.sf.net/p/matsim/code"
OUT_REPO = "https://svn.code.sf.net/p/matsim/source"
IN_REPO_RE = re.compile("^git-svn-id: %s" % re.escape(IN_REPO), re.M)
OUT_REPO_RE = "git-svn-id: %s" % OUT_REPO
def my_commit_callback(commit):
commit.message = IN_REPO_RE.sub(OUT_REPO_RE, commit.message)
sys.stderr.write(".")
filter = FastExportFilter(commit_callback = my_commit_callback)
filter.run()
上記のgit svn rebase -l
解決策は私にはうまくいきませんでした。私はそれについて別の方法で取り組むことにしました:
old
、新しいSVNをgitリポジトリに複製しますnew
old
にnew
cd new
git fetch ../old
git tag old FETCH_HEAD
new
しますold
(の根元new
と先端の木old
が同じであるため、成功するはずです)
git checkout master
(master
ブランチがSVNヘッドを指していると想定します。これは、クリーンクローンの場合です。それ以外の場合は、開始する前にdcommitします。)git rebase --root --onto old
new
リベースを説明するためにのgit-svnメタデータを再構築します
git update-ref --no-deref refs/remotes/git-svn master
(クローンの方法に応じてリモート参照を調整します。たとえば、次のようになりますrefs/remotes/svn/trunk
)rm -r .git/svn
git svn info
この質問に対する他のいくつかの回答に基づいて、git-svnの再配置を処理するRubyスクリプトを考え出しました。https://gist.github.com/henderea/6e779b66be3580c9a584で見つけることができます。
別のコピーをチェックアウトせずに再配置を処理し、1つ以上のブランチにプッシュされていない変更がある場合も処理します(通常のロジックが壊れているため)。git filter-branch回答(メインロジック用)と、リポジトリの1つのインスタンスから別のインスタンスへのブランチのコピー(プッシュされていない変更を含むブランチのコピー用)に関する回答を使用します。
私はこれを使用して、仕事用に持っているgit-svnリポジトリの束を再配置してきましたが、このバージョンのスクリプト(数え切れないほどの反復を経てきました)は私にとってはうまくいくようです。超高速ではありませんが、私が遭遇したすべてのケースを処理し、完全に再配置されたリポジトリをもたらすようです。
スクリプトには、変更を加える前にリポジトリのコピーを作成するオプションが用意されているため、このオプションを使用してバックアップを作成できます。ブランチにプッシュされていない変更がある場合は、コピーを作成する必要があります。
スクリプトは、通常のMRIRubyインストールに含まれていないgemやその他のライブラリを使用しません。MRIに含まれているreadlineおよびfileutilsライブラリを使用します。
うまくいけば、私のスクリプトが他の誰かに役立つことがわかるでしょう。スクリプトに自由に変更を加えてください。
注:このスクリプトは、OS X 10.10Yosemiteでgit2.3.0 /2.3.1とRuby2.2.0でのみテストしましたが(これは私が使用している環境であるため)、他の環境でも機能することを期待しています。ただし、Windowsについての保証はありません。