文書を書くときにも当てはまることだが、何か「もの」を書いているときに は書き直したい部分がどんどん出てくる。それとは逆に、書き直す前のものを 保存しておきたいこともよくある。
このような場合に、一つのファイルを新規に作成したときから、現在、未来 に渡って任意の時点の全てのバージョンを記録できるツールを利用すると良い。 このようなものをバージョン管理ツール といい、大切なファイルを 作成する場合には欠かせないものである。
RCS (Revision Control System) を使うと、 プログラムのソースやテキストファイル形式の文書の任意の時点の状態を保存し、 あとから任意のバージョンを取り出すことができる。RCSを利用してバージョン 管理する場合の流れは以下のようになる。
(このバージョンを保存したいと思ったときに)
登録したいファイルを チェックイン する。
そのままプログラミング(文書執筆)を続ける
そののち、以前に登録していたバージョンを参照したいときには、
などの操作ができる。
RCSを使うためには、管理したいファイルのあるディレクトリに
RCS
というディレクトリを作成しておく。RCS
ディレクトリは、管理したいファイルの全てのバージョンを保存する
特別なファイルを格納するために使われる。RCS
ディレクトリ
を作成しなくてもRCSは利用できるが、管理ファイルが散乱するので
かならず
% mkdir RCS
しておこう。
編集するファイルをRCS管理下に置くには、チェックイン という作 業を行なう。チェックインすると、現在のファイルの内容が登録される。チェッ クインした場合、元のファイルは一時的に「読み取り専用」モードになり編集禁 止状態になる。編集を続けるには、チェックアウト という作業を行な う。チェックアウトすることで、ファイルが読み書きできるようになる。 したがって、ファイルをRCS管理するときの編集の流れは、
編集 → チェックイン ↑ ↓ チェックアウト ← 保存
のようになる。ファイルをチェックインするときには、そのときまでに やった作業の簡単な説明を書くことができる。
Emacsを利用してファイルをRCS管理するととても簡単である。
C-x v v をタイプすると説明を入れるバッファが あらわれるので、メモとなる適当な言葉を入れて(省略可能) C-c C-c をタイプする
C-x v v をふたたびタイプする。
キー操作として、C-x v v を覚えておけば良い。 実際にやってみよう。
ここで、foo.c
をRCS管理するやり方を追ってみよう。
foo.c
を作成する
簡単のためファイルの内容は以下のとおりとする。
/* $Id:$ */ #include <stdio.h> int main() { puts("Hello, world!"); }
ファイルが書けたら保存しておく。
C-x v vをタイプする。初回にチェックインすると
そのファイルがRCS管理されるようになる。チェックインされた状態では
ファイルがリードオンリーモードになりの修正が禁止される。
リードオンリーモードになると、ミニバッファに %%
記号が出る。
以後の編集は、チェックインとチェックアウトを繰り返しながら進める。
ファイルがリードオンリーの場合は、チェックインされた状態である。 チェックアウトのために C-x v v する。これで 編集が可能になる。
プログラムをバージョンアップしよう。以下のように修正する。
/* $Id$ */
#include <stdio.h>
int main()
{
puts("Hello, world!");
exit(0);
}
追加が終わったら保存する。
C-x v vをタイプする。下半分にログメッセージを 入力するためのバッファが現れるので、ここに簡単なメモを残す。 面倒なら何も書かなくて良いが、あとでそのバージョンを取り出す かもしれないときは分かりやすいメモを書いておく。C-x v v をタイプしたときに出てくるが、ログメッセージを書き終わったら C-c C-c をタイプする。
/* $Id$ */ #include <stdio.h> int main() { puts("Hello, world!"); } - かんな-E.E:%%-F1 foo.c [1] (C Encoded-kbd RCS-1.1)--L4-All-- exit を足したよ
ログメッセージを書いたら C-c C-c でチェックインが 完了する。
以上、チェックインとチェックアウトを繰り返していく。
過去にチェックインしたものをいつでも取り出せる。そのときには、 チェックインしたときのログメッセージが手がかりとなる。
C-x v l をタイプする(最後は log のエル)。 下のウィンドウに過去にチェックインしたときのログがあらわれる。
RCS file: RCS/foo.c,v Working file: foo.c head: 1.2 branch: locks: strict access list: symbolic names: keyword substitution: kv total revisions: 2; selected revisions: 2 description: ---------------------------- revision 1.2 date: 2003/06/15 14:49:03; author: ta01002; state: Exp; lines: +1 -0 exitを足したよ ---------------------------- revision 1.1 date: 2003/06/15 14:21:34; author: ta01002; state: Exp; Initial revision
直前のバージョンとの差分を見るには C-x v = を タイプする。
もっと古いバージョンと比べたいときは、C-x v l の ログ一覧から比較したいバージョンの Revision 番号を調べる。 番号を覚えておいて C-u C-x v = をタイプする。
File or dir to diff: (default visited file) ~/C-lang/ (そのままリターン) Older version: (default 1.2) 1.1 (古いバージョン番号を入力する) Newer version (default: current source): (そのままリターン)
現在のソースとの比較結果が下のバッファにあらわれる。
--- foo.c 2003/06/15 14:49:03 1.2 +++ foo.c 2003/06/15 14:56:53 @@ -1,6 +1,6 @@ #includeint main() { - puts("Hello, world"); + printf("Hello, world\n"); exit(0); }
行の先頭にマイナスのついているのが、元のプログラムから消えた行、 プラスのついているのが新しい方に現れた行を意味する。上の例の場合 マイナスのついている
puts("Hello, world");
の行が消され、
printf("Hello, world\n");
に書き換えられたことを表している。
利用できるキーの一覧を挙げておこう。
RCSの全ての機能を利用するにはコマンドを利用する。
チェックインには、ci
コマンドを使う。
ci [オプション] ファイル
ファイルをチェックインする。良く使うオプションは以下のとおり。
-u
チェックインした後ファイルを消さない(デフォルトは消す)
-l
チェックインした後すぐにチェックアウトして編集を 継続できるようにする
ci
するとログメッセージの入力を求めてくる。
簡単なメッセージを入れたら、最後にピリオドだけの行を入れて終了する。
チェックアウトには、co
コマンドを使う。
co [オプション] ファイル
ファイルをチェックアウトする。良く使うオプションは以下のとおり。
-rリビジョン
指定したリビジョン 番号のファイルを取り出す。
-pリビジョン
指定したリビジョン のファイルを 標準出力に書き出す。中だけ見たいときに
% co -p1.1 foo.c | less
などとするとディスク上の foo.c
はそのままで
リビジョン 1.1 の foo.c
を見ることができる。
-D日付け
指定した日付け のバージョンを取り出す。
-D"2003/05/30"
のように指定する。
指定したバージョンとの差分を見るには rcsdiff
コマンド
を使う。
とするとリビジョン の時点のものと現在のファイル の差分が表示される。
C-x v = でプログラムの変更した箇所を調べたときに出てきた 内容は GNU diff 形式 という。テキストファイルの変更点のみを 記したもので、元のファイルがどんなに大きくても、修正点が少なければ diff形式はその部分だけで済む。大きなプログラムを配布する場合に 新しいバージョンの変更点のみをdiff形式で配布することにより、 とても少ない通信量で済ませることができる。
% diff -ua 旧ファイル 新ファイル > file.diff
として差分を file.diff
に保存する。相手側が
旧ファイル を持っていた場合相手側では
% patch < file.diff
とすると、手元にあるファイルが新しいものに書き換えられる。