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>
残念ながら、これらの回答のほとんどのリンクは機能していないため、今後の参考のために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 と新しいリポジトリ URL をパラメーターとして指定しますsvn switch --relocate
。
このスクリプトは、コミット メッセージ内git filter-branch
の Subversion URL を置き換えるために呼び出し、 update を呼び出し、さらにを使用してメタデータを再作成することでメタデータを更新します。より堅牢なソリューションかもしれませんが、このアプローチは巨大なリポジトリに対してはるかに高速に機能します (数時間と数日)。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
、 、 Consult .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 の回答 (メイン ロジック用) と、リポジトリのあるインスタンスから別のインスタンスへのブランチのコピーに関する回答 (プッシュされていない変更を含むブランチのコピー用) の内容を使用します。
私はこれを使用して、仕事用に持っている一連の git-svn リポジトリを再配置してきましたが、このバージョンのスクリプト (私は数え切れないほどの反復を経験しました) がうまくいくようです。それは超高速ではありませんが、私が遭遇したすべてのケースを処理し、完全に再配置されたリポジトリをもたらすようです.
このスクリプトでは、変更を行う前にリポジトリのコピーを作成するオプションが提供されるため、このオプションを使用してバックアップを作成できます。ブランチに未プッシュの変更がある場合は、コピーを作成する必要があります。
このスクリプトは、通常の MRI Ruby インストールに含まれていない gem やその他のライブラリを使用しません。MRI に含まれている readline および fileutils ライブラリを使用します。
願わくば、私のスクリプトが他の誰かの役に立ちますように。スクリプトを自由に変更してください。
注:このスクリプトは、OS X 10.10 Yosemite 上の git 2.3.0/2.3.1 および Ruby 2.2.0 でのみテストしました (これが私が使用している環境であるため) が、他の環境でも動作することを期待しています。ただし、Windows に関する保証はありません。