CVSの使い方  - MacOSXで事始め -

Last described 23-Aug-2003

1. 最初に
2. ユーザ/リポジトリ毎の設定
2.1 環境変数 ${CVSROOT} の設定
2.2 リポジトリ格納用ディレクトリの作成と初期化
2.3 cvsignore ファイルの作成と設定
2.4 cvswrappers ファイルの修正
3. モジュール(プロジェクト)の作成
3.1 プロジェクトの原型ディレクトリを作成する
3.2 必要に応じて .cvsignore や .cvswrappers ファイルを作成する
3.3 リポジトリにプロジェクトを登録する(モジュールを作成する)
3.4 原型ディレクトリを削除するか、アーカイブ形式にして保存する
4. 作業用ディレクトリの作成と廃棄
4.1 作業用のディレクトリを作成する
4.2 作業用のディレクトリを破棄する
5. 開発・更新作業 (Terminal編)
5.1 ファイルやディレクトリを追加した時
5.2 ファイルやディレクトリを削除した時
5.3 リポジトリの最新状態に合わせて、作業用ディレクトリ内を更新する
5.4 作業用ディレクトリ内の変更結果を、リポジトリに登録する
5.5 タグを付ける(その時点の状態に目印を付ける)
6. 開発・更新作業 (Project Builder編)
6.1 Project Builder の準備
6.2 Project Builder で可能な作業
7. モジュールのバックアップ/削除/復元(移動)
7.1 モジュールのバックアップ
7.2 モジュールの削除
7.3 モジュールの復元


1. 最初に

 本編は、ローカルマシン上に CVSリポジトリを作成して、個人で CVS を利用するための覚え書きです。 読み手の前提条件として、CVS がおおよそどのようなソフトウェアであるか知っており、 Terminal上でUnixツールの基本操作ができることを想定しています。
 これ以降、以下の条件で作業するものとして話を進めます。
※CVS: Concurrent Versions System
※動作確認したソフトウェアのバージョンは、MacOSX:10.2.4、CVS:1.10、ProjectBuilder:2.0.

2. ユーザ/リポジトリ毎の設定

2.1   環境変数 ${CVSROOT} の設定

 まず、リポジトリを格納するためのディレクトリ(フォルダ)の場所と名前を決めます。 通常、場所はユーザ用ディレクトリの直下にしておきます。名前は適当で構いません。 場所と名前を決めたら、以下のようにして環境変数を設定します。
[G4Cube:~] terra% setenv CVSROOT ${HOME}/cvsroot
[G4Cube:~] terra% env | grep "CVSROOT" ¶    # ←設定内容を確認する
CVSROOT=/Users/terra/cvsroot
環境変数の設定はログアウトすると消えてしまうので、.login ファイルに以下の行を追加しておきます。
setenv CVSROOT ${HOME}/cvsroot
これ以降は、CVSROOT環境変数が常に設定されているものとして話を進めます。

2.2   リポジトリ格納用ディレクトリの作成と初期化

 リポジトリを格納するためのディレクトリ(フォルダ)を作成し、初期化します。
[G4Cube:~] terra% mkdir ~/cvsroot
[G4Cube:~] terra% cvs init ¶

2.3   cvsignore ファイルの作成と設定

 ${CVSROOT}/CVSROOT(= /Users/terra/cvsroot/CVSROOT)ディレクトリの下に、cvsignore というテキストファイルを作成します。 MacOSX 特有の特殊ファイルを CVS の管理対象としないようにするために、cvsignore ファイルには、以下のようなファイルパターン定義を記述します。
.DS_Store
._*         # UFS等におけるリソースフォーク格納用ファイル.
*.app       # MacOSXのアプリケーション.
*.build     # Project Builder が中間生成物を格納するディレクトリ(?)
*.pbxindex  # Project Builder が高速検索用のインデックス類を格納するディレクトリ(?)
*.pbxuser   # Project Builder がユーザの作業状態を保存するファイル(?)
 管理対象外にするファイルパターンは、これが絶対というものではありませんので、状況に応じて追加/削除してください。 ただし、CVS には デフォルトで管理対象外とするファイルパターンがあるので、 これらと同じパターンをあらためて記述する必要はありません。
 なお、プロジェクトによって管理対象にするか否かが替るようなファイルパターンについては、 プロジェクトの作業用ディレクトリに .cvsignore ファイルを作成して指定する方法を採ります。

2.4   cvswrappers ファイルの修正

 リポジトリからファイルを取り出したり格納したりする際に、ファイルの種類に応じて適切な扱いを行うように、 ${CVSROOT}/CVSROOT ディレクトリにある cvswrappers というテキストファイルを修正します。 MacOSXには /Developer/Tools ディレクトリに記述済みの cvswrappers ファイルがあるので、 これを上書きコピーして使うのが手っ取り早い方法です。
[G4Cube:~] terra% cp -i /Developer/Tools/cvswrappers  ${CVSROOT}/CVSROOT/ ¶
overwrite /Users/terra/cvsroot/CVSROOT/cvswrappers? y ¶
 プロジェクトによって管理対象にするか否かが替るようなファイルパターンについては、 プロジェクトの作業用ディレクトリに .cvswrappers ファイルを作成して指定する方法を採ります。 また、cvswrappers を利用して漢字コードや改行コードを自動変換するような場合もありますが、 このようなケースでは、ユーザの作業環境により扱い方が変動するので、ユーザのホームディレクトリに .cvswrappers ファイルを作成して指定する方法を併用するのがベターかと思います。

3. モジュール(プロジェクト)の作成

3.1   プロジェクトの原型ディレクトリを作成する

 何かを開発・更新するには作業用のディレクトリが必要になるものです。 その原型となるディレクトリを作成し、その中にプロジェクトを構成するファイルを格納します。 Project Builder を利用して作成したディレクトリ(フォルダ)でも問題ありません。 CVS ではファイル名やサブディレクトリ名の変更ができない(削除と新規登録で代用することになる)ので、 よく考えて名前は付けましょう。

3.2   必要に応じて .cvsignore や .cvswrappers ファイルを作成する

 プロジェクトに特有の管理対象外ファイルや扱い方を指定する場合は、 原型ディレクトリの下に .cvsignore や .cvswrappers ファイルを作成して、ファイルパターンを記述します。
# .cvsignore ファイルの内容例 -- OPEN-R開発環境用 
*.elf
*.bin
*.BIN

3.3   リポジトリにプロジェクトを登録する(モジュールを作成する)

 Project Builderを利用している場合は、一旦、Project Builderを終了させます。
 そして、必ず原型ディレクトリに移動してから、
[G4Cube:~] terra% cd ~/projectX
[G4Cube:~/projectX] terra% ls -aF ¶     # ←単にディレクトリを確認しているだけ.
.               .cvsignore      main.cpp
..              .cvswrappers    projectX.1
.DS_Store       build/          projectX.pbproj/
以下のようにコマンドを実行します。
[G4Cube:~/projectX] terra% cvs import -m "Project since 2002"  projectA  terra  first
    #                                     (1)                  (2)       (3)    (4)
    # (1): メッセージ.簡単な説明文.何か指定しないとviが起動して面倒.
    # (2): モジュール名.今後の作業で、何かと指定することになります.
    # (3): ベンダータグ.作成者名を意味する文字列でOK.
    # (4): リリースタグ.モジュール全体のバージョン識別名称.
I projectA/.DS_Store
N projectA/.cvsignore
N projectA/.cvswrappers
N projectA/main.cpp
・・・
 モジュール名は、そのままリポジトリ内に作成されるディレクトリ名になると同時に、 checkout/export する時の作業用ディレクトリのデフォルト名にもなります。 コマンドで指定するモジュール名を、プロジェクト登録(import)時の原型ディレクトリ名と同じ(projectX)にする必要はないので、 後のことを考えて、原型ディレクトリ名と違う名前(projectA)を付けても構いません。

3.4   原型ディレクトリを削除するか、アーカイブ形式にして保存する

 作業ミスを防ぐために、原型ディレクトリは削除するか、不安があるならアーカイブ形式にして保存しておきます。 後で作業用ディレクトリを作成する時に、同じ名前のディレクトリが残っていると、 そのまま原型ディレクトリに上書きしようとしてコピーの作成に失敗することがあるからです。 最悪、作業用ディレクトリを破棄(release)することもできない事態に陥ります。

4. 作業用ディレクトリの作成と廃棄

4.1   作業用のディレクトリを作成する

 開発・更新作業を開始する時には、リポジトリからモジュールのコピーを取り出して、作業用のディレクトリを作成します。
[G4Cube:~] terra% ls ${CVSROOT} ¶
CVSROOT     projectA    # ←取り出すモジュール(プロジェクト)名を確認する
[G4Cube:~] terra% cvs checkout -d projectX  projectA
    #                              (1)       (2)
    # (1): 作業用ディレクトリを指定する.省略するとモジュール名と同じ名前になる.
    # (2): コピーを取り出すモジュール名.
cvs checkout: Updating projectA
U projectA/.cvsignore
U projectA/.cvswrappers
U projectA/main.cpp
・・・
[G4Cube:~] terra% cvs history ¶        # ←チェックアウト状態を確認する
O 01/05 10:17 +0000 terra projectA   =projectX=     ~/*
 CVSでは、モジュールのコピーを取り出すと同時にチェックアウト中の状態になり、作業中であることがリポジトリに記録されます。 つまり、正規の手順を踏まずに、このコピー(作業用ディレクトリ)を削除したり、作業用ディレクトリの名前を変更したりすることは厳禁ということです。
 同じプロジェクト(モジュール)であっても、更新する目的やファイルが異なる場合は、 それぞれの用途に合わせて複数の作業用ディレクトリを作成すると便利です。
[G4Cube:~] terra% cvs checkout -d projectX-prg  projectA ¶
・・・
[G4Cube:~] terra% cvs checkout -d projectX-doc  projectA ¶
・・・
[G4Cube:~] terra% cvs history ¶        # ←チェックアウト状態を確認する
O 01/05 10:17 +0000 terra projectA   =projectX-prg= ~/*
O 01/05 10:18 +0000 terra projectA   =projectX-doc= ~/*

4.2   作業用のディレクトリを破棄する

 作業用ディレクトリの破棄は、開発・更新作業が完了した時、もしくは、これまでの作業を無効にして最後に commit した時の状態に戻したい時に行います。 下記のコマンドを実行すると、チェックアウトが解除されると同時に、作業用ディレクトリが削除されます。
[G4Cube:~/projectX] terra% cd .. ¶     # ←作業用ディレクトリから必ず抜け出す
[G4Cube:~] terra% cvs release -d  projectX    # 最後に / を付けないこと!
You have [0] altered files in this repository.
Are you sure you want to release (and delete) directory `projectX': y ¶
[G4Cube:~] terra% cvs history ¶
・・・                                  # ←破棄した projectX が無いことを確認する

5. 開発・更新作業 (Terminal編)

 本章の作業は全て、チェックアウト状態にある作業用ディレクトリにて行います。

5.1   ファイルやディレクトリを追加した時

 ファイルやディレクトリを追加した後には、以下のようにコマンドを実行します。
[G4Cube:~/projectX] terra% cvs add  newfile.html
    #                                  (1)
    # (1): ファイル名/ディレクトリ名.複数個の指定やワイルドカード指定も可能.
cvs add: scheduling file `newfile.html' for addition
cvs add: use 'cvs commit' to add this file permanently

5.2   ファイルやディレクトリを削除した時

 ファイルやディレクトリを削除した後には、以下のようにコマンドを実行します。
[G4Cube:~/projectX] terra% cvs remove oldfile.html
    #                                  (1)
    # (1): ファイル名/ディレクトリ名.複数個の指定やワイルドカード指定も可能.
cvs remove: scheduling `oldfile.html' for removal
cvs remove: use 'cvs commit' to remove this file permanently

5.3   リポジトリの最新状態に合わせて、作業用ディレクトリ内を更新する

 個人が一人でリポジトリを使う時には、リポジトリが知らない間に更新されていることはあり得ない話です。 しかし、リポジトリの最新状態を反映するコマンド(cvs update)には、他にも効用があり、 一人で使う場合にも非常に便利なコマンドです。
[G4Cube:~/projectX] terra% cvs update -P -d ¶
M main.cpp       # ←M:この作業用ディレクトリ内で更新をしたファイル
? temp.log       # ←?:この作業用ディレクトリ内で追加(新規作成)したファイル
A newfile.html   # ←A:この作業用ディレクトリ内で追加、かつ cvs add したファイル
R oldfile.html   # ←R:この作業用ディレクトリ内で削除、かつ cvs remove したファイル
U projectX.1     # ←U:リポジトリの最新状態を反映して、書き込まれたファイル
cvs update: Updating build
・・・

5.4   作業用ディレクトリ内の変更結果を、リポジトリに登録する

 ファイルを更新/追加/削除する作業が一段落したら、その結果をリポジトリに登録(commit)します。 commitしてもチェックアウトの状態は維持されるので、作業はそのまま続けることができます。
[G4Cube:~/projectX] terra% cvs commit -m "just OK"
    #                                     (1)
    # (1): メッセージ.簡単な説明文.何か指定しないとviが起動して面倒.
cvs commit: Examining .
cvs commit: Examining build
・・・
Checking in main.cpp;
/Users/terra/cvsroot/projectA/main.cpp,v  <--  main.cpp
new revision: 1.2; previous revision: 1.1
done
・・・

5.5   タグを付ける(その時点の状態に目印を付ける)

 プロジェクト内のファイル間の整合がとれたら(開発しているプログラムが正常に動作するようになったら)、 全てのファイルに同じタグを付けておくことを奨めます。 このような状態のファイルは、後で変更/改良作業を行う時の基準として何度も参照されることになるため、 人間でも管理しやすいような目印がある方が便利だからです。
[G4Cube:~/projectX] terra% cvs tag "v1_0r1" ¶    # 空白や .,:;$@ 文字は不可.
cvs tag: Tagging .
T .cvsignore
T .cvswrapper
T main.cpp
・・・
 利用例を以下に示します。
[G4Cube:~] terra% cvs diff -r "v1_0r1"  main.cpp ¶
Index: main.cpp
===================================================================
RCS file: /Users/terra/cvsroot/projectX/main.cpp,v
retrieving revision 1.2
diff -r1.2 main.cpp
7c7
<   int accume[16];
---
>   int accume[DEFAULT_ARRAY_SIZE];
※CVS が自動的に付けるリビジョン番号は、各々のファイルを commitした回数により決まります。 そのため、同時期のファイルに同じリビジョン番号が付いているという保証は、どこにもありません。

6. 開発・更新作業 (Project Builder編)

6.1   Project Builder の準備

 チェックアウト状態にある作業用ディレクトリの *.pbproj ファイルを Project Builder で開くことで、 CVS を利用した開発・更新作業ができるようになります。

6.2   Project Builder で可能な作業

 5.1節〜5.4節に相当する作業は、Project Builderのメニューから実行可能です。 基本的な操作は、私のへたな説明を読むより、実際に使ってみてもらう方が理解しやすいと思います。 また、Project Builderのヘルプにも説明があるので、そちらも参照して下さい。



7. モジュールのバックアップ/削除/復元(移動)

7.1   モジュールのバックアップ

[G4Cube:~] terra% cvs -d /Users/terra/cvsroot1  history ¶
# 対象モジュールがチェックアウト中で無いことを確認してから、次の作業をする.
[G4Cube:~] terra% cd /Users/terra/cvsroot1
[G4Cube:~/cvsroot1] terra% tar cvzf ~/projectA.tgz  projectA

7.2   モジュールの削除

[G4Cube:~] terra% cvs -d /Users/terra/cvsroot2  history ¶
# 対象モジュールがチェックアウト中で無いことを確認してから、次の作業をする.
[G4Cube:~] terra% cd /Users/terra/cvsroot2
[G4Cube:~/cvsroot2] terra% rm -r projectA ¶

7.3   モジュールの復元

[G4Cube:~] terra% cd /Users/terra/cvsroot3
[G4Cube:~/cvsroot3] terra% ls ¶
CVSROOT     projectB    projectC        # ←復元するモジュールが存在しないことを確認
[G4Cube:~/cvsroot3] terra% tar xvzf ~/projectA.tgz ¶    # モジュールを解凍

[HOME] > [INDEX]

Appendix

◇  CVSがデフォルトで管理対象外とするファイル名のパターン

.
..
.#*
#*
,*
_$*
*~
*$
*.a
*.bak
*.BAK
*.elc
*.exe
*.ln
*.o
*.obj
*.olb
*.old
*.orig
*.rej
*.so
*.Z
.del-*
.make.state
.nse_depinfo
core
CVS
CVS.adm
cvslog.*
RCS
RCSLOG
SCCS
tags
TAGS

◇  Project Builder使用時に管理すべきファイルについて

 私の場合は、最初の頃、きちんとファイルを追加/保存して、かつプロジェクト全体を選択してから [CVS]-[変更をコミット]するという手順を踏んでいても、build や *.pbproj ディレクトリ以下のファイルが リポジトリに反映されていないという現象がありました。
[G4Cube:~] terra% cvs release -d  projectX
? build/projectX.build/projectX.pbxindex/strings.pbxstrings
M projectX.pbproj/terra.pbxuser
You have [2] altered files in this repository.
Are you sure you want to release (and delete) directory `projectX': 
 このような現象が起きないように cvsignore のファイルパターンは決めてあるつもりですが、 Apple の資料等をきちんと調べた訳ではないので間違いがあるかもしれません。 リポジトリから取り出したコピーだけでビルドできているようなので、一応、大丈夫そうですけど・・。

[HOME] > [INDEX]
(c) Kazufumi Terada, 2003