web-dev-qa-db-ja.com

変更履歴をMercurialまたはgitからcvsにエクスポートする方法は?

私は、cvsを使用するプロジェクトのコードで他の人々と協力するつもりです。分散vcsを使用して作業を行い、終了時またはたまにコードとすべての改訂履歴をcvsにコミットしたい場合があります。プロジェクトのcvsリポジトリへの書き込みアクセス権がないため、あまり頻繁にコミットできません。リビジョン履歴をcvsにエクスポートするにはどのツールを使用できますか?現在、gitまたはMercurialを使用することを考えていましたが、エクスポートを簡単にできる場合は別の分散vcを使用できます。

100
tatsuhirosatou

まだCVSの使用を余儀なくされている私たちにとって幸いなことに、gitはあなたがやりたいことを正確に行うための非常に優れたツールを提供します。私の提案(およびここ$ workで行うこと):

初期クローンの作成

git cvsimportを使用して、CVSリビジョン履歴をgitリポジトリにクローンします。次の呼び出しを使用します。

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout

-Aオプションはオプションですが、CVSからインポートされたリビジョン履歴をよりgit風に見せるのに役立ちます(設定方法の詳細については man git-cvsimport を参照してください) 。

CVSリポジトリのサイズと履歴に応じて、この最初のインポートには非常に長い時間がかかります。何かが実際に発生しているという安心感が必要な場合は、上記のコマンドに-vを追加できます。

このプロセスが完了すると、CVSのHEADを反映する必要があるmasterブランチがあります(例外として、git cvsimportはデフォルトで最後の10分間のその後、git logと友人を使用して、リポジトリの履歴全体を、あたかも最初からgitを使用しているかのように調べることができます。

構成の調整

将来的にCVSからの増分インポート(およびエクスポート)を容易にするいくつかの構成の調整があります。これらはgit cvsimport manページに文書化されていないため、予告なく変更される可能性があると考えていますが、FWIW:

% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT

これらのオプションはすべてコマンドラインで指定できるため、この手順を安全にスキップできます。

増分インポート

後続のgit cvsimportは、最初の呼び出しよりもはるかに高速である必要があります。ただし、すべてのディレクトリでcvs rlogを実行するので(Atticにファイルのみがあるディレクトリも)、数分かかる場合があります。上記の推奨構成を指定した場合、実行する必要があるのは次の実行のみです。

% git cvsimport

デフォルトを指定するために設定をセットアップしていない場合、コマンドラインでそれらを指定する必要があります:

% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout

いずれにせよ、留意すべき2つのこと:

  1. Gitリポジトリのルートディレクトリにいることを確認してください。他の場所にいる場合は、新しいcvsimportを実行しようとします。
  2. masterブランチにいることを確認して、変更をローカル/トピックブランチにマージ(またはリベース)できるようにします。

ローカル変更を行う

実際には、ブランチに常に変更を加え、それらの変更をCVSリポジトリにエクスポートする準備ができたときにのみmasterにマージすることをお勧めします。ブランチで好きなワークフロー(マージ、リベース、スカッシュなど)を使用できますが、もちろん標準のリベースルールが適用されます。他の誰かがブランチに変更を加えている場合はリベースしないでください。

CVSへの変更のエクスポート

git cvsexportcommitコマンドを使用すると、単一のコミットをCVSサーバーにエクスポートできます。単一のコミットID(または man git-rev-parse で定義された特定のコミットを説明するもの)を指定できます。次に、diffが生成され、CVSチェックアウトに適用され、(オプションで)実際のcvsクライアントを使用してCVSにコミットされます。トピックブランチの各マイクロコミットをエクスポートできますが、通常、最新のmasterでマージコミットを作成し、その単一のマージコミットをCVSにエクスポートするのが好きです。マージコミットをエクスポートする場合、差分の生成に使用するコミットの親をgitに伝える必要があります。また、マージが早送りの場合は機能しません(早送りマージの説明については man git-merge の "HOW MERGE WORKS"セクションを参照してください)。マージの実行時に--no-ffオプションを使用します。以下に例を示します。

# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD

git-cvsexportcommitのマニュアルページ で、これらの各オプションの意味を確認できます。 git configで-wオプションを設定するオプションがあります:

% git config cvsexportcommit.cvsdir /path/to/cvs/checkout

何らかの理由でパッチが失敗した場合、私の経験では、(残念ながら)変更されたファイルを手動でコピーし、cvsクライアントを使用してコミットする方がよいでしょう。ただし、トピックブランチをマージする前にmasterがCVSで最新であることを確認している場合、これは発生しません。

何らかの理由(ネットワーク/許可の問題など)でコミットが失敗した場合、エラー出力の最後に端末に出力されたコマンドを取得し、CVS作業ディレクトリで実行できます。通常、次のようになります。

% cvs commit -F .msg file1 file2 file3 etc

次回git cvsimportを実行するとき(少なくとも10分待機)、エクスポートされたコミットのパッチがローカルリポジトリに再インポートされます。 CVSコミットは異なるタイムスタンプと異なるコミッター名を持っているため、これらのコミットIDは異なります(上記の最初のcvsimportで作成者ファイルをセットアップしたかどうかによって異なります)。

CVSクローンのクローン作成

cvsimportを実行する必要がある人が複数いる場合は、cvsimportを実行する単一のgitリポジトリを持ち、他のすべてのリポジトリをクローンとして作成する方が効率的です。これは完全に機能し、クローン化されたリポジトリは上記のようにcvsexportcommitsを実行できます。ただし、注意点が1つあります。 CVSコミットが異なるコミットIDを使用して戻る方法(前述)により、クローンブランチが中央のgitリポジトリを追跡することは望ましくありません。デフォルトでは、これはgit cloneがリポジトリを設定する方法ですが、これは簡単に修正できます:

% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge

これらの構成を削除した後、中央リポジトリから新しいコミットをプルするときに、どこから何をプルするかを明示的に指定する必要があります。

% git pull Origin master

全体として、このワークフローは非常に管理しやすく、完全にgitに移行する場合の「次善策」は実用的ではないことがわかりました。

238
Brian Phillips

盲目的にcvsimportを信頼し、インポートされたツリーがCVSリポジトリにあるものと一致するかどうかを確認するべきではありません。 Eclipse CVSのプラグインを使用して新しいプロジェクトを共有することでこれを行いましたが、矛盾があることがわかりました。

(同じように誤って削除されたファイルを元に戻すために)同じコミットメッセージで1分以内に実行された2つのコミットが1つの大きなコミットにグループ化され、ツリーからファイルが失われました。

「fuzz」パラメーターを1分未満に変更することで、この問題を解決できました。

例:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

一番下の行:インポート後にツリーを確認

21
shil88

ブライアン・フィリップスの答えに加えて: git-cvsserver もありますが、これはCVSサーバーのように機能しますが、実際にはgitリポジトリにアクセスします...しかし、いくつかの制限があります。

3
Jakub Narębski