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


100

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


「Distributed CVS」とは、「Distributed VCS」または「DVCS」を意味すると思います。これは「Distributed Version Control System」の略です。
Patrick McElhaney、2009

分散バージョン管理システムを意味します。
たつひろさと09

回答:


237

幸いにも、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つの点に注意してください。

  1. gitリポジトリのルートディレクトリにいることを確認してください。あなたが他の場所にいるなら、それcvsimportは再び永遠にかかる新鮮なことをしようとします。
  2. 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に移行する場合の「次善の策」は実用的ではないことがわかりました。


3
ありがとうございました。これは私に非常に役立ちました。特に、非早送りマージを使用してCVSの変更を単一のコミットにバンドルすることに関するヒント。
skiphoppy 2009年

8
参考までに、git-cvsimportに使用することを提案する-Aオプションは、マンページで「推奨されない...後でgit-cvsexportcommit(1)を使用して変更を再びCVSにエクスポートする場合」と記載されています。私の場合、私は実際に著者がそのまま出てくる方法が好きです。
skiphoppy 2009年

2
ヒントをありがとう。私が行った便利なことの1つは、.gitconfigの[alias]の下に「cvs =!git cvsimport -k -a」を追加することです。これにより、 "git cvs"がDTRT(ツリーの上から)するようになります。
bstpierre 2010

1
git cvsimportDebianに欠けている場合は、試してくださいapt-get install git-cvs
Tino

5
Mac OSX mavricksには完全にcvs Initialized empty Git repository in /Users/gus/projects/foo/foobar/.git/ Can't exec "cvsps": No such file or directory at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-cvsimport line 777. Could not start cvsps: No such file or directory git cvsimport: fatal: cvsps reported errorがなく、git cvsimportはcvsに依存しているようです。残念ながら、これはCVSの不在を回避できません:(
Gus

22

cvsimportを盲目的に信頼してはならず、インポートされたツリーがCVSリポジトリ内のものと一致するかどうかを確認してください。私はeclipse CVSのプラグインを使用して新しいプロジェクトを共有することでこれを実行しましたが、不整合があることがわかりました。

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

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

例:

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

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.