幸いにも、CVSの使用を余儀なくされている私たちにとって、gitはあなたがやりたいことを正確に行うためのかなり良いツールを提供します。私の提案(ここで$ workで行うこと):
初期クローンの作成
git cvsimportCVSリビジョン履歴を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を追加できます。
このプロセスが完了すると、masterCVSの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ページで確認できます。あなたの-wgit設定でオプションを設定するオプションがあります:
% 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に移行する場合の「次善の策」は実用的ではないことがわかりました。