幸いにも、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を追加できます。
このプロセスが完了すると、master
CVSのHEADを反映するブランチが作成git cvsimport
されます(ただし、デフォルトでは、最後の10分間のコミットを無視して、完了していないコミットをキャッチしないようにします)。その後git log
、友達を使用して、まるで最初からgitを使用しているかのように、リポジトリの履歴全体を調べることができます。
構成の微調整
将来的には、CVSからの増分インポート(およびエクスポート)を簡単にするいくつかの構成の微調整があります。これらはgit cvsimport
マニュアルページに記載されていないため、予告なく変更される可能性がありますが、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つの点に注意してください。
- gitリポジトリのルートディレクトリにいることを確認してください。あなたが他の場所にいるなら、それ
cvsimport
は再び永遠にかかる新鮮なことをしようとします。
master
ブランチ上にいることを確認して、変更をローカル/トピックブランチにマージ(またはリベース)できるようにします。
ローカルでの変更
実際には、常にブランチに変更を加え、master
それらの変更をCVSリポジトリにエクスポートする準備ができたときにのみマージすることをお勧めします。ブランチで好きなワークフロー(マージ、リベース、スカッシュなど)を使用できますが、もちろん標準のリベースルールが適用されます。他の誰かがブランチで変更をベースにしている場合は、リベースしないでください。
CVSへの変更のエクスポート
このgit cvsexportcommit
コマンドを使用すると、単一のコミットをCVSサーバーにエクスポートできます。単一のコミットID(またはで定義されている特定のコミットを説明するもの)を指定できますman git-rev-parse
。次に、差分が生成され、CVSチェックアウトに適用され、(オプションで)実際のcvs
クライアントを使用してCVSにコミットされます。トピックブランチの各マイクロコミットをエクスポートすることもできますが、通常は最新の状態でマージコミットを作成し、master
その単一のマージコミットをCVSにエクスポートします。マージコミットをエクスポートする場合、差分の生成に使用するコミットの親をgitに指示する必要があります。また、マージが早送りであった場合(これは早送りマージman git-merge
の説明については、「差し込み印刷の方法」セクションを参照)は機能しないため、--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のmanページで確認できます。あなたの-w
git設定でオプションを設定するオプションがあります:
% 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に移行する場合の「次善の策」は実用的ではないことがわかりました。