私は、cvsを使用するプロジェクトのコードで他の人々と協力するつもりです。分散vcsを使用して作業を行い、終了時またはたまにコードとすべての改訂履歴をcvsにコミットしたい場合があります。プロジェクトのcvsリポジトリへの書き込みアクセス権がないため、あまり頻繁にコミットできません。リビジョン履歴をcvsにエクスポートするにはどのツールを使用できますか?現在、gitまたはMercurialを使用することを考えていましたが、エクスポートを簡単にできる場合は別の分散vcを使用できます。
まだ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つのこと:
cvsimport
を実行しようとします。master
ブランチにいることを確認して、変更をローカル/トピックブランチにマージ(またはリベース)できるようにします。実際には、ブランチに常に変更を加え、それらの変更をCVSリポジトリにエクスポートする準備ができたときにのみmaster
にマージすることをお勧めします。ブランチで好きなワークフロー(マージ、リベース、スカッシュなど)を使用できますが、もちろん標準のリベースルールが適用されます。他の誰かがブランチに変更を加えている場合はリベースしないでください。
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
で作成者ファイルをセットアップしたかどうかによって異なります)。
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に移行する場合の「次善策」は実用的ではないことがわかりました。
盲目的に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
一番下の行:インポート後にツリーを確認
ブライアン・フィリップスの答えに加えて: git-cvsserver もありますが、これはCVSサーバーのように機能しますが、実際にはgitリポジトリにアクセスします...しかし、いくつかの制限があります。