29

SVN の 1 つのディレクトリに複数の共有プロジェクト、ソリューション ファイルなどを含むコードの大規模なベースがあります。Mercurial に移行しています。この機会に、コードをいくつかのリポジトリに再編成して、分岐用のクローン作成のオーバーヘッドを減らしたいと思います。履歴を保持しながら、リポジトリを SVN から Mercurial に変換することに成功しました。私の質問: 履歴を保持しながら、すべての異なるプロジェクトを別々のリポジトリに分割するにはどうすればよいですか?

これは、単一のリポジトリ (OurPlatform) が現在どのように見えるかの例です。

/OurPlatform
---- Core
---- Core.Tests
---- Database
---- Database.Tests
---- CMS
---- CMS.Tests
---- Product1.Domain
---- Product1.Stresstester
---- Product1.Web
---- Product1.Web.Tests
---- Product2.Domain
---- Product2.Stresstester
---- Product2.Web
---- Product2.Web.Tests
==== Product1.sln
==== Product2.sln

これらはすべて、ソリューション ファイルを除く VS プロジェクトを含むフォルダーです。Product1.sln と Product2.sln は両方とも、他のすべてのプロジェクトを参照します。理想的には、これらのフォルダーのそれぞれを取得して、それらを個別の Hg リポジトリーに変換し、プロジェクトごとに新しいリポジトリーを追加します (それらは親リポジトリーとして機能します)。次に、誰かが Product1 で作業する場合、Product1.sln と、ReferenceAssemblies、Core、Core.Tests、Database、Database.Tests、CMS、および CMS.Tests へのサブレポ参照を含む Product1 リポジトリを複製します。

そのため、プロジェクト ディレクトリで hg init を実行するだけで簡単に実行できます。しかし、歴史を保存しながらそれを行うことができますか? または、これを整理するより良い方法はありますか?

編集::::

Ry4an さんの回答のおかげで、目標を達成することができました。ここで他の人のためにどのようにそれを行ったかを共有したかった.

多くの個別のプロジェクトがあったため、ファイルマップの作成を自動化し、実際に変換を行うための最終的なバット スクリプトを作成する小さな bash スクリプトを作成しました。回答から完全には明らかではありませんでしたが、ファイルマップごとに convert コマンドを 1 回実行して、プロジェクトごとに個別のリポジトリを作成する必要があることです。このスクリプトは、以前に変換した svn 作業コピーの上のディレクトリに配置されます。作業コピーを使用したのは、そのファイル構造が、最終的な新しい hg リポジトリにしたいものに最もよく一致したためです。

#!/bin/bash

# this requires you to be in: /path/to/svn/working/copy/, and issue: ../filemaplister.sh ./

for filename in *
do
  extension=${filename##*.} #$filename|awk -F . '{print $NF}'
  if [ "$extension" == "sln" -o "$extension" == "suo" -o "$extension" == "vsmdi" ]; then
    base=${filename%.*}
    echo "#$base.filemap" >> "$base.filemap"
    echo "include $filename" >> "$base.filemap"
    echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $base.filemap ../hg-datesort-converted ../hg-separated/$base > $base.convert.output.txt" >> "MASTERGO.convert.bat"
  else
    echo "#$filename.filemap" >> "$filename.filemap"
    echo "include $filename" >> "$filename.filemap"
    echo "rename $filename ." >> "$filename.filemap"
    echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $filename.filemap ../hg-datesort-converted ../hg-separated/$filename > $filename.convert.output.txt" >> "MASTERGO.convert.bat"  
  fi  
done;

mv *.filemap ../hg-conversion-filemaps/
mv *.convert.bat ../hg-conversion-filemaps/

このスクリプトは、svn 作業コピー内のすべてのファイルを調べ、タイプに応じて、新しいファイルマップ ファイルを作成するか、既存のファイルに追加します。if は、実際にはその他のビジュアルスタジオファイルをキャッチし、それらを別のリポジトリに配置するだけです。これは bash (私の場合は cygwin) で実行することを意図していますが、実際の convert コマンドの実行は、Windows でのフォーク/プロセスの問題により、TortoiseHg に同梱されている hg のバージョンを介して実行されます (ああ、私は知っています...)。

そのため、変換された hg リポジトリを参照する MASTERGO.convert.bat ファイルを実行し、提供されたファイルマップを使用して別のリポジトリを作成します。完了すると、各プロジェクトのフォルダー/リポジトリと、各ソリューションのフォルダー/リポジトリを含む hg-separated というフォルダーがあります。次に、すべてのプロジェクトをソリューション リポジトリに手動で複製し、その複製を .hgsub ファイルに追加する必要があります。コミット後、.hgsubstate ファイルが作成され、準備完了です!

上記の例では、私の .hgsub ファイルは "Product1" に対して次のようになります。

Product1.Domain = /absolute/path/to/Product1.Domain
Product1.Stresstester = /absolute/path/to/Product1.Stresstester
Product1.Web = /absolute/path/to/Product1.Web
Product1.Web.Tests = /absolute/path/to/Product1.Web.Tests

これらのリポジトリを中央サーバーに転送したら、手動でパスを URL に変更します。

また、現在すべてが分離されているため、最初の OurPlatform svn リポジトリに類似するものはありません。

再度、感謝します!

4

1 に答える 1

28

これは絶対にできます。コマンドを使用する必要がありますhg convert。私が使用するプロセスは次のとおりです。

  1. hg convertsvn のソース タイプと hg の dest タイプを使用して、すべてを単一の hg リポジトリに変換します(この手順は既に完了しているようです)。
  2. のオプションfilemapで使用するファイルのコレクションを作成するhg convert--filemap
  3. hg convertソース タイプhgと宛先タイプで実行し、ソースhgはステップ 1 で作成した Mercurial リポジトリです。ステップ 2 で作成したファイルマップごとに実行します。

ファイルマップの構文はhg help convert出力に示されていますが、要点は次のとおりです。

The filemap is a file that allows filtering and remapping of files and
directories. Comment lines start with '#'. Each line can contain one of
the following directives:

  include path/to/file

  exclude path/to/file

  rename from/file to/file

したがって、あなたの例では、ファイルマップは次のようになります。

# this is Core.filemap
include Core
rename Core .

include がある場合、他のすべての除外が暗示されることに注意してください。また、その名前変更行はドットで終わり、すべてを 1 レベル上に移動します。

# this is Core.Tests
include Core.Tests
rename Core.Tests .

等々。

新しいリポジトリごとに分割リポジトリを作成したら、ステップ 1 で作成した has-everything 初期リポジトリを削除し、.hgsubファイルでサブリポジトリ構成のセットアップを開始できます。

于 2010-06-18T03:35:13.817 に答える