[ www.notava.org > メモ > CVS ]


個人的なメモですから、もちろん無保証・自己責任で。

CVS

以下、

R リポジトリが必要。リポジトリはcvs initによって作られる。
W 作業ディレクトリが必要。作業ディレクトリはcvs checkoutによって作られる。
C cvs commitするまで、実行されない

環境変数

CVSROOT :local:dir CVSのリポジトリの位置を設定。オプション-dで代用可
:ext:name@host:dir
EDITOR viとか
エディタを設定。オプション-eで代用可
CVSEDITOR
CVS_RSH ssh 認証にsshを使う

リポジトリの初期化

cvs init リポジトリを初期化

リポジトリにファイル・ディレクトリを追加

R cvs import -m message リポジトリdirectory no_vendor first_revision リポジトリ上にdirectoryがなければ作成し、カレントディレクトリ以下のファイルを追加。no_vendorとfirst_revisionは他の適当な文字列でも良い。作業ディレクトリは作られない。一部のファイル(CVS*~*.o など)は無視される。
R cvs import -I ! -m message リポジトリdirectory no_vendor first_revision 上と同じだが、一部のファイルを無視しない。
RWC cvs add -m message 手元directories... ディレクトリを追加
RWC cvs add -kkv -m message 手元files... テキストファイルをキーワード置換を有効にして追加
RWC cvs add -ko -m message 手元files... テキストファイルをキーワード置換を無効にして追加
RWC cvs add -kb -m message 手元files... バイナリファイルを追加
RW cvs admin -kkv/-ko/-kb 手元files... すでに追加されてしまったファイルの置換の設定を変更する

キーワード置換は、ファイルをリポジトリから得るときに行われる。commitする時には、手元のファイルをキーワード置換しないでリポジトリに反映させ、その後手元のファイルに対してキーワード置換が行われる。

$Author: koto $
そのリビジョンをcommitした人
$Date: 2003/01/25 05:28:34 $
そのリビジョンをcommitした時刻
$Header: CVSROOT/Test/file.txt,v 1.1.1.1 2003/01/25 05:28:34 koto Exp $
リポジトリ上の名前(フルパス)、リビジョン、日付時刻、Author、ファイル状態、ロックされていればロックしている人
$Id: file.txt,v 1.1.1.1 2003/01/25 05:28:34 koto Exp $
Header と同様だが、フルパスではない
$Name: $
ファイルを取り出すときに使用したタグ名
$Locker: $
ロックしている人
header $Log: file.txt,v $
ログを追加

ファイルを削除

RWC cvs remove -f 手元files... リポジトリおよび作業ディレクトリからファイルを削除

ファイルの移動

RWC cvs remove 手元old && mv 手元old 手元new && cvs add -m message 手元new ファイルを移動(改名)

リポジトリからファイルを得る

R cvs checkout -P リポジトリdirectories/files... ファイルを得て作業ディレクトリを作成
R cvs export -r HEAD リポジトリdirectories/files... リリース用にファイルを得る
RW cvs update -P カレントディレクトリ以下のファイルについて、リポジトリへの他人による更新を手元へ反映する
RW cvs update -P 手元directories/fiels... 指定したファイルについて、リポジトリへの他人による更新を手元へ反映する

update時のメッセージは、

U file 作業ディレクトリのファイルは、リポジトリのファイルと一致するように更新された。U はサーバとの通信でファイル全体が送信され、P は差分が送信されたことをあらわす。
P file
A file cvs add されたが commit されていない。
R file cvs remove されたが commit されていない。
M file 作業ディレクトリのファイルは編集されている。リポジトリのファイルとは一致しないが、リポジトリに対する編集は、手元のファイルへ反映された。
C file 作業ディレクトリのファイルは編集されている。リポジトリに対する編集を手元のファイルへ反映させようとしたが、競合を解決できなかった。
? file このファイルはリポジトリ上に存在しない。

手元の更新をリポジトリへ反映

RW cvs commit -m message カレントディレクトリ以下のファイルのアップデートを反映
RW cvs commit -m message 手元directories/files... 指定されたファイルのアップデートを反映

他人がcommitしていた場合、Up-to-date check failed というエラーになる。updateが必要。

作業ディレクトリを放棄

RW cvs release 作業ディレクトリを放棄

ウォッチ

RW cvs watch add -a edit/unedit/commit/all 手元directories/files... cvs editcvs uneditあるいはcvs releasecvs commit、あるいはこれらのいずれかが行われた場合に、たとえばメールで通知する
RW cvs watch remove 手元directories/files... watch add のキャンセル
RW cvs watch on 手元directories/files... 他人がそのファイルを編集するのにcvs editを義務付ける
RW cvs watch off 手元directories/files... watch on のキャンセル
RW cvs edit 手元directories/files... watch on されているファイルを編集する。cvs commit で解除される。
RW cvs edit -a edit/unedit/commit/all 手元directories/files... watch on されているファイルを編集し、その間他人の操作を通知する
RW cvs unedit 手元directories/files... 編集を破棄して、cvs edit以前の状態に戻す
RW cvs watchers 手元directories/files... cvs watch add によって(?)監視している人のリストを表示
RW cvs editors 手元directories/files... cvs edit によって(?)編集している人のリストを表示

ログ・履歴・状態

R? cvs history report flags... options... directories/files... reportは、-c(コミットのみ)や-e(すべての種類)。flags...-a(すべてのユーザ)や-l(最後の変更)。options...-D date-r revisionなど。
R? cvs history -ea -z +0900 directories/files... | sort -k2,3 指定したファイルへのアクセスの履歴を時刻順にソートして表示
RW cvs log 手元directories/files... ログを表示
RW? cvs status 手元directories/files... ファイルの状態を表示

ここから先は、少し難しい話。

リビジョンと枝

リポジトリには、過去にcommitされたファイルのそのときの内容がすべて記録されている。それらはリビジョンと呼ばれる、偶数個の数値をピリオドで区切って並べたもので識別される。リビジョンXで識別されるファイルを、単にリビジョンXと呼んだり、Xのことをリビジョン番号と呼んだりする。リビジョンはファイルごとにばらばらに管理される。つまり、異なるファイルについて同じリビジョン番号が存在しうるが、それらの間に関係は無い(ユーザが意図的に管理しない限り)。リビジョンはどれかのに属し、その枝はリビジョンの最後の数値と直前のピリオドを削ったもの(ただし、最後の数値の前に0とピリオドを入れて表示される場合がある。例えば1.1.1のかわりに1.1.0.1)。数値1つで表される枝(つまり、枝1.1.1などではなく、枝1、枝2、...、枝10、...)をまとめて、と呼ぶ。 幹ではない枝の最後の数値と直前のピリオドを削るとリビジョンになるが、その枝とこのリビジョンとの関係は気にしなくてよい(通常、その枝の最初のリビジョンを与えるリビジョンであるが、常にそうなるわけではない)。

特定のファイルを得る

R(W) cvs export/checkout/update -D date directories/files... 指定時刻以前で、最新のものを得る。dateは、たとえば2001-01-252001-01-25 20:05:12 GMT。sticky date を date に設定する。
R(W) cvs export/checkout/update -r revision directories/files... 指定されたリビジョンのファイルを得る。sticky tag を revision に設定する。
R(W) cvs export/checkout/update -r branch directories/files... 指定された枝に属すリビジョンの中で、最新のファイルを得る。sticky tag を branch に設定する。
R(W) cvs export/checkout/update -r branch:date directories/files... 指定された枝に属すリビジョンの中で、指定された時刻以前で最新のファイルを得る。sticky tag を branch に設定する?
RW cvs update -P -A 手元directories/files... sticky tag や sticky date をついていない状態にする。幹の中で最新のファイルを得る(次のadmin -bが指定されていなければ)。
RW cvs update -P 手元directories/files... sticky tag や sticky date がついていれば、その枝、リビジョン、時刻に基づいて、ファイルを得る。ついていなければ、幹の中で最新のファイルを得る(次のadmin -bが指定されていなければ)。
RW cvs admin -bbranch 手元directories/files... sticky tag や sticky dateがついていない状態のupdateにおいて、幹ではなく、枝branchを検索する。-bと引数の間にスペースを入れてはならない。

checkoutやupdateに対する -D-rは、そのファイルの以降のupdate(やcommit?)のデフォルトとして使われる。これらのデフォルト値は sticky date や sticky tag と呼ばれる。-Aはそれらを剥ぎ取る。sticky date や sticky tag はユーザごとに設定される。

RW cvs status 手元directories/files... ファイルの状態を得る。sticky tag や sticky date も表示される。

sticky tag がリビジョンをさしていたり、sticky date が設定されている場合、ファイルを編集してもcvs commitすることはできない。

commit

ファイルを編集してcvs commitしたとき、新しいリビジョンは次のように決まる(らしい)。admin -bしてupdate -Aすると、sticky tag は設定されていない状態になるので注意。

RW cvs commit -r branch -m message 手元directories/files... 指定された枝に属すリビジョンで、最新のものの最後の数値をインクリメントしたもの
RW cvs commit -r revision -m message 手元directories/files... revisionは、2つの整数をピリオドで区切ったもの(つまり、幹に属すリビジョン)。指定されたリビジョンでcommitする。
RW cvs commit -m message 手元directories/files... sticky tag が設定されていない場合、2つの数値をピリオドで区切ってできるリビジョンで最も大きいものの、2つ目の数値をインクリメントしてできるリビジョン(例えば最新のファイルが 2.3 なら、新しいリビジョンは 2.4)。sticky tag が枝を指している場合、その枝の最新のリビジョンをインクリメントしてできるリビジョン。

枝の作成・タグ

タグは、リビジョンや枝についた名前。全ユーザで共有される。-rオプションの引数で使うことができる。

RW cvs tag -c tag 手元directories/files... ファイルの、直前のcheckoutやupdateで得たリビジョンに文字列でタグをつける。commitは不要で即座に動作する。
RW cvs tag -b tag 手元directories/files... ファイルの、直前のcheckoutやupdateで得たリビジョンを元に新しい枝を作る(新しい枝を作り、直前のcheckoutやupdateで得たファイルの内容を、その枝に属す最初のリビジョンとして登録する)。さらに枝に文字列でタグをつける。commitは不要で即座に動作する。Sticky Tagは変わらない。

差分の抽出

RW cvs diff format_option <-r tag/-D date> <-r tag/-D date> 手元directories/files... 差分を表示。format_optionはGNU diffライクなフォーマットオプション。
RW cvs diff format_option <-r tag/-D date> 手元directories/files... 手元のファイルと、指定されたリビジョンのファイルとの差分を表示
RW cvs diff format_option 手元directories/files... 手元のファイルと、直前のcheckoutやupdateで得たリビジョンとの差分を表示

2つのリビジョン間の差分を、手元のファイルへ適応する

RW cvs update -P -j branch 手元directories/files... 枝の元になっているファイルから、その枝の最新のファイルの間で更新された内容を、作業ディレクトリのファイルへ反映させる。
RW cvs update -P -j revision1 -j revision2 手元directories/files... revision1からrevision2の間で更新された内容を、作業ディレクトリのファイルへ反映させる。例えば、revision1に対して追加・削除・置換を行うことでrevision2が作られている場合、同様の追加・削除・置換を作業ディレクトリのファイルに対して行おうとする。
RW cvs update -P -j revision2 -j revision1 手元directories/files... revision1からrevision2の間で更新された内容を、作業ディレクトリのファイルに対して元に戻す。例えば、revision1に対して追加・削除・置換を行うことでrevision2が作られている場合、同様の追加・削除・置換が作業ディレクトリのファイルにすでに行われていると考えて、その追加・削除・置換を元に戻そうとする。

import

R cvs import -m message リポジトリdirectory vendor release リポジトリ上にdirectoryがなければ作成し、カレントディレクトリ以下のファイルを追加。枝1.1.1にタグvendorをつけ、ファイルをその枝へ登録される。さらにそのリビジョンにタグreleaseを付ける。
R cvs import -b 1.1.3 -m message リポジトリdirectory vendor release 上と同様だが、対象となる枝は 1.1.1 ではなく 1.1.3

運用

基本的には、

プロジェクトを枝分かれさせたい場合、

ある機能のためにコードを追加したいが、将来そのコードを自由に取り外ししたい

まず、新しい枝を作ってコードの追加を行います。

枝に加えた変更を、普段の枝に反映させます。

普段の枝からコードを取り除きたい場合、

追加したコードにバグがあって修正したい場合、

あるいは、次の手順でも良い。

あるいは、