ソースファイルが複数のユーザーによって変更される可能性がある場合は、ソースファイルへの書き込み権を調整する必要があります。更新記録を管理することによって、変更がいつどのような理由で行われたかを特定することができます。
ソースコード管理システム (SCCS) を使用して、ソースファイルへの書き込み権の管理およびソースファイルの変更の監視を行うことができます。SCCS は、同時に 1 人のユーザーだけにファイルの更新を許可し、履歴ファイルにすべての変更を記録します。
SCCS を使用して、以下のことを行うことができます。
編集するファイルの任意のバージョンのコピーを SCCS 履歴から取り出すことができます。
ファイルのバージョンをチェックアウトおよびロックし、他のユーザーによる変更を禁止します。あるユーザーが行なった編集を消去してしまうような変更を、他のユーザーが勝手に行うことを防止します。
ファイルに更新をチェックインします。ファイルをチェックインする際に、変更内容を要約したコメントを入力することもできます。
チェックアウトしたコピーへの変更を取り消すこともできます。
編集可能なファイルを確認できます。
選択した複数のバージョン間の違いを確認できます。
これまでにチェックインされた変更を要約したバージョンログを表示できます。
ソースコード管理システムは、sccs(1) コマンドで構成されます。このコマンドは、/usr/ccs/bin ディレクトリにあるユーティリティプログラムのフロントエンドです。SCCS のユーティリティプログラムの一覧は、表 5-2 を参照してください。
sccs create コマンドは、ファイルを SCCS に管理させます。このコマンドは、新しい履歴ファイルを作成し、ソースファイルのすべての内容を最初のバージョンとして使用します。デフォルトでは、履歴ファイルは SCCS サブディレクトリにあります。
$ sccs create program.c program.c: 1.1 87 lines
SCCS は、作成されたファイルの名前、バージョン番号 (1.1)、行数を出力します。
元のファイルが誤って喪失または損傷してしまったときのために、sccs create は新しいファイル名の先頭にコンマを付けたファイルに (これをコンマファイルと呼びます) 元のファイルへの 2 つ目のリンクを作成します。履歴ファイルの初期化に成功すると、SCCS は新たに読み取り専用バージョンを取り出します。このバージョンとそのコンマファイルとを比較して検証した後は、コンマファイルを削除してください。
$ cmp ,program.c program.c (何も出力されない場合はファイルが完全に 一致していることを意味します) $ rm ,program.c
SCCS が取り出す読み取り専用バージョンは、まだ編集しないでください。ファイルを編集するには、後述の sccs edit コマンドを使用してファイルをチェックアウトする必要があります。
履歴ファイルと現在のバージョンとを区別するため、履歴ファイルの名前に s. という接頭辞が使用されます。この履歴ファイルはしばしば s. ファイル (s ドットファイル) とも呼ばれます。また、履歴ファイルは、慣用的に SCCS ファイルとも呼ばれます。
SCCS 履歴ファイルの形式については、sccsfile(4) を参照してください。
以下の sccs サブコマンドは、バージョン管理機能を実行します。以下にサブコマンドを要約しています。create 以外のサブコマンドについての詳細は、「sccs サブコマンド」で説明しています。
前述の履歴ファイルおよび最初のバージョンを初期化します。
編集を行うために書き込み可能なバージョンをチェックアウトします。このコマンドを実行したユーザーを所有者として書き込み可能なコピーを取り出し、他のユーザーが変更をチェックインできないように、履歴ファイルをロックします。
変更をチェックインします。このサブコマンドによって、sccs edit 処理が完了します。変更を記録する前に、コメントを入力するためのプロンプトが表示されます。コメントは、履歴ファイル中のバージョンログに保存されます。
ファイルの読み取り専用コピーを s. ファイルから取り出します。デフォルトでは、最新のバージョンが取り出されます。取り出されたバージョンは、コンパイル、フォーマット、表示を行うためのソースファイルとして使用できます。ただし、このバージョンは編集または変更を行うためのものではありません。読み取り専用バージョンのファイルアクセス権を変更すると、ファイルへの変更が無効になる場合があります)。
ディレクトリをファイル名引数として指定すると、sccs はそのディレクトリ内のすべての s. ファイルに対して get サブコマンドを実行します。
sccs get SCCS
上記のコマンドは、SCCS サブディレクトリ内のすべての s.file の読み取り専用バージョンを取り出します。
バージョンログと、各バージョンに対応するコメントを表示します。
バージョンをチェックインすると、SCCS は、チェックインしたテキストと直前のバージョンとの、行ごとの相違だけを記録します。この相違をデルタと呼びます。edit または get により取り出されるバージョンは、それまでにチェックインされたデルタから構成されます。
「デルタ」と「バージョン」は、しばしば同義語として使用されます。ただし、これらの意味は正確には同一ではありません。選択したデルタを省略したバージョンを取り出すこともできます (「取り出したバージョンからデルタを削除する」を参照してください)。
SCCS のデルタ ID (SID) は、特定のデータを示すための番号です。SID は、ドット (.) で区切った 2 つの番号で構成されます。最初のデルタの SID は、デフォルトでは 1.1 です。SID の最初の部分はリリース番号、2 番目の部分はレベル番号です。デルタをチェックインすると、レベル番号が自動的に 1 つずつ増えます。リリース番号は、必要に応じて増やすことができます。SCCS は、この他に分岐デルタ用の 2 つのフィールドも認識します (分岐デルタについては 「分岐」を参照してください)。
厳密には、SID はデルタそのものを示しますが、デルタとそれ以前のバージョンから構築したバージョンのことを「デルタ」という場合もあります。
SCCS は、ソースファイル中の特定のキーワードを認識して展開します。このキーワードを使用して、チェックインするバージョンのテキストにそのバージョン固有の情報 (SID など) を含めることができます。編集を行うファイルをチェックアウトするときに、ID キーワードは以下のようになります。
%C%
ここで、C は大文字です。ファイルをチェックインする際に、SCCS はキーワードを対応する情報に置換します。たとえば、%I% は、現在のバージョンの SID に展開されます。
ID キーワードは、一般的にはコメントまたは文字列の定義中に含めます。少なくとも 1 つの ID キーワードがソースファイルに含まれていない場合は、SCCS は以下のような診断を出力します。
No Id Keywords (cm7)
ID キーワードについての詳細は、「ID キーワードを使用してバージョン固有情報を組み込む」を参照してください。
以下のサブコマンドは、バージョンを取り出したり変更をチェックインする際に使用します。
ソースファイルを編集するには、まず sccs edit を使用してファイルをチェックアウトする必要があります (sccs edit コマンドは、sccs get で -e オプションを使用する場合と同じ結果になります)。
SCCS は、取り出したバージョンのデルタ ID と、変更をチェックインしたときに割り当てられる新しいデルタ ID を返します。
$ sccs edit program.c 1.1 new delta 1.2 87
取り出したファイルは、テキストエディタを使用して編集できます。ファイルの書き込み可能なコピーがある場合は、sccs edit はエラーメッセージを表示します。つまり sccs edit は、他のユーザーにもファイルへの書き込み権がある場合は、そのファイルを上書きしません。
ファイルをチェックアウトして編集が完了したら、sccs delta を使用して変更をチェックインできます。
ファイルをチェックインすることを、デルタを作成するということもあります。更新をチェックインする前に、コメントを入力するプロンプトが表示されます。コメントとして、変更についての要約を記述します。
$ sccs delta program.c comments?
コメントは、後でそのファイルを使用する時のために、わかりやすい内容にする必要があります。
バックスラッシュ (¥) と復帰改行を入力することによって、コメントを 2 行以上に渡って記述することができます。
$ sccs delta program.c comments? corrected typo in widget(), ¥ null pointer in n_crunch() 1.2 5 inserted 3 deleted 84 unchanged
SCCS は、新しいバージョンの SID と、挿入された行数、削除された行数、変更されていない行数を表示します。変更された行数は、削除された行と挿入された行の合計になります。SCCS は、作業用のコピーを削除します。sccs get を使用して、読み取り専用バージョンを取り出すことができます。
バージョンをチェックインする際には注意が必要です。少量の編集を行うたびにデルタを作成していくと、デルタが多くなりすぎる場合があります。逆に長期間ファイルをチェックアウトしたままにすると、他のユーザーがそのファイルを編集できないので不便になる場合があります。
一般に使用されるモジュールをコンパイルまたはインストールする前に、変更したすべてのファイルをチェックインしてください。手順は以下のとおりです。
必要なファイルを編集します。
必要な変更およびテストを行います。
ファイルのコンパイルおよびデバッグを行います。
ファイルをチェックインし、get を使用して読み取り専用のコピーを取り出します。
モジュールを再コンパイルします。
ファイルの最新バージョンを取得するには、以下のコマンドを使用します。
sccs get filename
以下に例を示します。
$ sccs get program.c 1.2 86
この例では、program.c を取り出し、バージョン番号および取り出された行数が表示されています。取り出された program.c のコピーは、読み取り専用になっています。
SCCS は、ファイルをチェックアウトしない限り新しいデルタを作成しないため、この取り出した読み取り専用のコピーは変更 (編集) しないでください。取り出した読み取り専用のコピーをそのまま強制的に変更すると、他のユーザーが次に sccs get または sccs edit をそのファイルに対して実行したときに、そのファイルに加えた変更が無効になる場合があります。
チェックアウトしたバージョンの変更で、まだチェックインされていないものを、保留中の変更と呼びます。ファイルの編集中に、sccs diffs を使用して保留中の変更を確認できます。diffs サブコマンドは、diff(1) を使用して、作業用 (編集中) のコピーとチェックインされた最新のバージョンとを比較します。
$ sccs diffs program.c ------ program.c ------ 37c37 < if (((cmd_p - cmd) + 1) == l_lim) { --- > if (((cmd_p - cmd) - 1) == l_lim) {
diff コマンドのほとんどのオプションを使用することができます。diff の -c オプションを呼び出すには、sccs diffs に -C という引数を使用します。
sccs unedit は、保留中の変更を取り消します。これは、ファイルの編集を間違ってしまったときに編集を最初からやり直す場合に便利です。unedit は、チェックアウトしたバージョンを削除し、履歴ファイルのロックを解除し、チェックインされている最新のバージョン (最後にチェックインしたバージョン) の読み取り専用コピーを取り出します。unedit を使用すると、ファイルをチェックアウトしなかったのと同じ状態になります。編集を再開するには、sccs edit を使用してファイルをもう一度チェックアウトします (「書き込み可能なコピーを修復する : sccs get -k -G」も参照してください)。
sccs delget は、delta および get の動作を組み合わせて一度に実行します。sccs delget は、変更をチェックインし、 チェックインした新しいバージョンの読み取り専用コピーを取り出します。ただし、SCCS が delta の実行中にエラーが発生した場合は、get は実行されません。ファイル名のリストを (複数のファイルを一度に) 処理する際は、delget は可能なすべての delta を実行し、delta でエラーが発生した場合は、すべての get の処理を実行しません。
sccs deledit は、delta を実行した後に edit を実行します。バージョンをチェックインした後、すぐに編集を再開することができます。
-r オプションを使用すると、取り出す SID を指定できます。
$ sccs get -r1.1 program.c 1.1 87
必要なデルタの SID は不明でも、チェックインした日付ならわかるという場合があります。以下の形式で -c オプションと日時を指定して、その日時以前にチェックインされた最新のバージョンを取り出すことができます。
-cyy [mm [dd [hh [mm [ss ]]]]]
以下に例を示します。
$ sccs get -c880722120000 program.c 1.2 86
この例は、1988 年 7 月 22 日午後 12 時の時点で最新のバージョンを取り出します。年以外のフィールドは省略できます (デフォルトでは現在になります)。また、指定された箇所に区切りとして句切り文字を挿入できます。前述のコマンドは、以下のように書き換えることができます。
sccs get -c"88/07/22 12:00:00" program.c
2000 年問題について : SCCS は日付を表わす書式として 2 けたで年を表します。Sun は、年として 69 〜 99 の値が指定されている場合は 1969 〜 1999、00 〜 68 の場合は 2000 〜 2068 にそれぞれ解釈するという、X/Open グループにより提案された仕様 (XCU5) を採用しています。
sccs get -k -Gfilename は、新しいバージョンをチェックアウトせずに、テキストの書き込み可能なコピーを取り出し、-G で指定されたファイル名で保存します。このコマンドは、diff コマンドとテキストエディタを使用して、損傷した作業中のコピーを置き換えたりまたは修復したりする際に便利です。
前述のように、SCCS では、ID キーワード (SID) を使用して、チェックインするバージョンにバージョン固有の情報を組み込むことができます。ID キーワード (ファイル中に挿入します) は、変更をチェックインする際にそのバージョンに対応する情報に自動的に置換されます。SCCS ID キーワードは、以下のような形式になります。
%C%
ここで、C は大文字の一文字を表わしています。
たとえば、%I% は、最新デルタの SID に展開されます。%W% は、ファイル名、SID、一意の文字列 @(#) をファイルに取り込みます。この文字列 @(#) は、what コマンドによりテキストファイルと バイナリファイルの両方で検索されます。これによって、ファイルまたはプログラムがどのバージョンのソースから構築されたかを確認することができます。%G% キーワードは、最新のデルタの日付に展開されます。その他の ID キーワードとそれらが展開されたときの文字列については、表 5-1 を参照してください。
この方法で文字列を定義すると、C のオブジェクトファイルにバージョン情報が組み込まれます。この方法を使用して ID キーワードをヘッダー (.h) ファイルに組み込む場合は、ヘッダーファイルごとに異なる変数を使用してください。これにより、静的 (static) 変数を再定義しようとするエラーを防止できます。
バージョン固有の情報を C プログラムに取り込むには、以下のようにします。
static char SccsId[ ] = "%W%¥t%G%";
ファイル名が program.c の場合、この行はバージョン 1.2 が取り出されたときに以下のように展開されます。
static char SccsId[ ] = "@(#)program.c 1.2 08/29/80";
コンパイルされたプログラムで文字列が定義されているため、この方法によりコンパイルしたプログラムにソースファイルの情報を組み込むことができます。ソースファイルの情報は、以下のように what コマンドで確認することができます。
$ cd /usr/ucb $ what sccs sccs sccs.c 1.13 88/02/08 SMI
シェルスクリプトなどのスクリプトでは、ID キーワードをコメント内に含めることができます。
# %W% %G% . . .
展開されたキーワードを含むバージョンをチェックインすると、バージョン固有の情報が更新されなくなります。これを通知するために、get、edit、create 実行時に ID キーワードを検出できないときには、以下のように SCCS は警告を表示します。
No Id Keywords (cm7)
以下のサブコマンドは、ファイルまたはその履歴を問い合わせる際に便利です。
SCCS を使用することによって、ファイル履歴中の任意のバージョンを取り出すことができるため、ディレクトリ内にある作業中のコピーが必要なバージョンでないという可能性もあります。what コマンドは、ファイル中の SCCS ID キーワードを検査します。また、バイナリファイルでもキーワードを検査するため、どのバージョンのソースからプログラムがコンパイルされたかを確認できます。
$ what program.c program program.c: program.c 1.1 88/07/05 SMI; program: program.c 1.1 88/07/05 SMI;
この例では、ファイルにはバージョン 1.1 の作業用のコピーが含まれています。
sccs get -g を使用すると、最新のデルタの SID を確認できます。
$ sccs get -g program.c 1.2
この例では、最新のデルタは 1.2 です。このバージョンは、前述の what の例でのバージョン 1.1 よりも新しいため、get を使用して最新のバージョンを取り出します。
どのファイルが編集中であるかを確認するには、以下のように入力します。
$ sccs info
このサブコマンドは、編集中のすべてのファイルと、ファイルをチェックアウトしたユーザー名などの情報を表示します。同様に、以下のコマンドを使用できます。
$ sccs check
このコマンドは、編集されているファイルがある場合に、警告を出力せずにゼロ以外の終了ステータスを返します。このコマンドを makefile で使用して、ソースファイルがチェックアウトされている場合に make(1S) を強制的に停止することができます。
チェックアウトしたすべてのファイルをチェックインする場合は、以下のコマンドを使用できます。
$ sccs delta 'sccs tell -u'
tell は、編集中のファイルの名前だけを 1 行に 1 つずつ表示します。-u オプションを使用すると、tell を実行したユーザーがチェックアウトしたファイルの名前だけを出力します。-u の引数としてユーザー名を指定すると、そのユーザーがチェックアウトしたファイルの名前だけを出力します。
sccs prt は、SID、作成日時、各バージョンをチェックインしたユーザー名、挿入/削除/変更なしの行数、コメントが記録されているバージョンログ (デルタテーブルとも呼びます) のリストを出力します。
$ sccs prt program.c D 1.2 80/08/29 12:35:31 pers 2 1 00005/00003/00084 corrected typo in widget(), null pointer in n_crunch() D 1.1 79/02/05 00:19:31 zeno 1 0 00087/00000/00000 date and time created 80/06/10 00:19:31 by zeno
最新バージョンのコメントだけを表示するには、-y オプションを使用します。
コメントに大切な情報を記述し忘れたなどの場合に、以下のコマンドを使用して、コメントに情報を追加できます。
sccs cdc -r sid
このコマンドを実行するには、最新のデルタ (または分岐中で最新のデルタ、「分岐」を参照) を指定する必要があります。また、そのデルタをチェックインしたユーザーであるか、履歴ファイルおよび SCCS サブディレクトリの両方に書き込み権を持つ所有ユーザーである必要があります。cdc は、コメントを入力するためのプロンプトを表示し、そこで入力された情報をコメントに追加します。
$ sccs cdc -r1.2 program.c comments? also taught get_in() to handle control chars
prt を使用して新しいコメントを表示すると、以下のようになります。
$ sccs prt program.c D 1.2 80/08/29 12:35:31 pers 2 1 00005/00003/00084 also taught get_in() to handle control chars *** CHANGED *** 88/08/02 14:54:45 pers corrected typo in widget(), null pointer in n_crunch() D 1.1 79/02/05 00:19:31 zeno 1 0 00087/00000/00000 date and time created 80/06/10 00:19:31 by zeno
チェックインした 2 つのバージョン、たとえば 1.1 と 1.2 の 2 つのデルタを比較するには、以下のコマンドを使用して、両者の違いを確認します。
$ sccs sccsdiff -r1.1 -r1.2 program.c
ファイルの変更内容および変更を行なったデルタをすべて表示するには、-m と -p のオプションを使用します。
$ sccs get -m -p program.c 1.2 1.2 #define L_LEN 256 1.1 1.1 #include <stdio.h> 1.1 . . . 84
特定のデルタに対応する行を抽出するため、出力を grep(1V) にパイプすることができます。
$ sccs get -m -p program.c | grep '^1.2'
-p だけを使用すると、取り出したバージョンの中身を (ファイルではなく) 標準出力に送ることができます。
prs サブコマンドと -d dataspec オプションを使用すると、SCCS が管理するファイルに関する情報を取り出し、それをレポートとして表示することができます。dataspec 引数には、履歴ファイルの一部分に対応するデータキーワードのセットを指定します。データキーワードは、以下の書式で指定します。
:X :
表 5-3 にデータキーワードのリストを示しています。引数 dataspec では、データキーワードを任意の回数使用できます。有効な dataspec は、テキストおよびデータキーワードで構成される文字列を二重引用符で囲んだものです。prs は、認識した各キーワードを履歴ファイルの適切な値に置換します。
データキーワードの値の形式は、1 行または複数行のいずれかです。前者の場合は、展開された値は単純な文字列になります。後者の場合は、展開された値に復帰改行が含まれます。
タブは ¥t で、復帰改行 は ¥n でそれぞれ指定します。
以下に例を示します。
$ sccs prs -d"Users and/or user IDs for :F: are:¥n:UN:" program.c Users and/or user IDs for s.program.c are: zeno pers $ sccs prs -d"Newest delta for :M:: :I:. Created :D: by :P:." -r program.c Newest delta for program.c: 1.3. Created 88/07/22 by zeno.
入力ミスなどの、修正する必要はあるけれども修正したファイルを新たなデルタとして追加する必要はない、というような小さなバグを含むデルタをチェックインしてしまうことがあります。または、ファイルの内容は正しいけれど、デルタのコメントが不完全であるあるいは誤っている場合があります。いずれの場合も、sccs fix を使用してファイルに対して変更を行い、最新のデルタに対応するバージョンログのエントリを置き換えることができます。
$ sccs fix -r 1.2 program.c
このコマンドは、program.c のバージョン 1.2 をチェックアウトします。修正後にこのファイルをチェックインすると、履歴ファイル中のデルタ 1.2 がファイルに加えた変更に置き換えられ、(新しい) コメントを入力するプロンプトが表示されます。sccs fix を使用するときには、-r オプションを使用して末端の (最新の) デルタの SID を指定する必要があります。
以前にチェックインしたデルタ 1.2 は実質的には削除されますが、SCCS はそれを削除されたデルタとして履歴ファイル中で記録します。
sccs fix を使用する前に、現在のバージョンのコピーを作成しておいてください。
最新のデルタを完全に削除するには、rmdel サブコマンドを使用します。-r を使用して SID を指定する必要があります。fix は削除されたデルタの記録を保持していますが rmdel は保持しないので (詳細は、sccs rmdel(1) を参照してください)、通常は rmdel よりも fix を使用することをお勧めします。
以前のバージョンの書き込み可能なコピーを取り出すには、get -k を使用します。このコマンドは、過去の複数のデルタを調べる必要がある場合に便利です。
以前のバージョンのデルタを使用して新しいデルタを作成するには、以下の手順に従います。
sccs edit を使用して ファイルをチェックアウトします。
get -k を使用して、以前のバージョンの書き込み可能なコピーを取り出します。
sccs get -k -r sid -Goldname filename
oldname にはファイル名、filename には取り出した以前のバージョンを一時に保存するファイルの名前 (元のファイル名 oldname とは異なる名前) を指定します。
現在のバージョンを以前のバージョンに置き換えます。
mv oldname filename
ファイルをチェックインします。
特定のデルタを削除した方が簡単な場合があります。また、SCCS を使用してファイルの複数の更新を管理する方法については、「分岐」を参照してください。
デルタ 1.3 で行なった変更が、次のバージョンである 1.4 には適切でないとします。編集用のファイルを取り出す際に、-x オプションを使用して、作業用のコピーからデルタ 1.3 を削除することができます。
$ sccs edit -x1.3 program.c
デルタ 1.5 をチェックインする際には、そのデルタにはデルタ 1.4 での変更が含まれますが、デルタ 1.3 での変更は含まれません。さらに、削除するデルタをコンマで区切ったリストを -x に指定したり、あるいはハイフンで削除するデルタの範囲を指定して、複数のデルタを削除することができます。たとえば、1.3 と 1.4 を削除する場合は、以下のコマンドを使用できます。
$ sccs edit -x1.3,1.4 program.c
$ sccs edit -x1.3-1.4 program.c
次の例では、SCCS は 1.3 からリリース 1 において現時点で最新のデルタまでを削除します。
$ sccs edit -x 1.3-1 program.c
-x を使用する場合は、バージョン間で衝突が生じることがあります。たとえば、特定の行について挿入と削除の両方が指定されている場合があります。この場合は、SCCS は影響のある行の範囲を示すメッセージを表示します。このメッセージを十分に確認して、SCCS が取り出したバージョンが正しいかどうかを確認してください。
各デルタは、(「変更のセット」として) 削除できるため、関連する変更を各デルタごとにまとめると便利です。
comb サブコマンドは、選択したデルタを結合または削除して新しい履歴ファイルを構成する Bourne シェルスクリプトを生成します。comb サブコマンドは、ディスク容量を節約したい場合に便利です。
複数のデルタを結合する際には、comb で生成したスクリプトは、ファイルのバージョンログ (コメントを含む) の一部を削除します。
-psid オプションでは、スクリプト実行後の再構成で保存する最も古いデルタを指定します。
-c sid-list
このオプションを使用して、含めるデルタのリストを指定できます。sid-list には、各デルタをコンマで区切ったリストを指定します。2 つの SID をハイフン (-) で区切って、範囲を指定することができます。-p と -c を同時に使用することはできません。-o オプションは、再構成に含めるデルタの個数を最小限にします。
-s オプションは、再構成後の履歴と元の履歴のサイズ (ブロック数) を比較するスクリプトを生成します。比較結果では、再構成後の履歴が元の履歴の何パーセントであるかが表示されます。
comb を使用する際は、元の履歴ファイルを保存してください。comb はディスク容量を節約するためのコマンドですが、節約されない場合もあります。場合によっては、生成された履歴ファイルが元の履歴ファイルよりも大きくなります。
オプションが指定されていない場合は、comb はそれまでの変更を保持するために必要な最小限の祖先を保存します。
通常は、SCCS は ASCII テキストを含むソースファイルに対して使用しますが、このバージョンの SCCS では、バイナリファイル (NULL または制御文字を含むファイル、または最後が復帰改行でないファイル) のバージョン管理も行うことができます。バイナリファイルは、チェックインの際にテキストファイルにエンコードされます。作業用のコピーは、取り出した時にはデコードされます (詳細は、uuencode(1C) を参照してください)。
SCCS を使用して、アイコン、ラスタイメージ、画面フォントなどのファイルの変更を追跡することができます。
sccs create -b を使用すると、ファイルをバイナリファイルとして処理することができます。バイナリファイルに対して create または delta を使用すると、以下のような警告メッセージが表示されます。
Not a text file (ad31)
また、以下のメッセージも表示されます。
No id keywords (cm7)
これらのメッセージは無視して構いません。これらのメッセージ以外については、通常通り処理が行われます。
$ sccs create special.font special.font: Not a text file (ad31) No id keywords (cm7) 1.1 20 No id keywords (cm7) $ sccs get special.font 1.1 20 $ file special.font SCCS/s.special.font special.font: vfont definition SCCS/s.special.font: sccs
SCCS を使用してソースファイルの更新を管理し、それらのソースファイルをもとにしてオブジェクトを作成してください。
エンコードされたバイナリファイルは各バージョンごとに大きく異なるため、バイナリファイルのソースの履歴ファイルはテキストのソースの場合よりも急速に大きくなります。ただし、すべてのソースファイルで同一のバージョン管理システムを使用すると、管理がより簡単になります。
SCCS を使用している場合、実際のソースファイルは履歴ファイルであり、作業用のコピーではありません。
プロジェクトでの作業中に、テストまたはデバッグ用にソースの複製を作成したい場合は、自分の作業用ディレクトリに SCCS のサブディレクトリへのシンボリックリンクを作成できます。
$ cd /private/working/cmd.dir $ ln -s /usr/src/cmd/SCCS SCCS
これにより、以下のコマンドを使用して、ソースファイルの作業用のコピーを複製して取り出すことができます。
sccs get SCCS
複製したディレクトリでの作業中にも、元のディレクトリでの場合と同様にファイルのチェックインまたはチェックアウトを行うことができます。
多くの場合、SCCS を make(1s) とともに使用して、ソフトウェアプロジェクトを管理します。make を使用すると、ソースファイルの自動取り出しを行うことができます (他のバージョンの make では、自動取り出しを行うために特別な規則を使用します)。また、すべてのソースファイルの以前のバージョンを取り出し、make を使用してプロジェクトの以前のバージョンを再構築することもできます。
$ mkdir old.release ; cd old.release $ ln -s ../SCCS SCCS $ sccs get -c"87/10/01" SCCS SCCS/s.Makefile: 1.3 47 . . . $ make . . .
構築処理中にはソースファイルをチェックインしないでください。プロジェクトの完成が近くなったら、すべてのファイルをチェックインして構築するようにしてください。これによって、公開される完成プロジェクトのソースが安定します。
複数のファイルで構成されるソース間で SID の整合性を保つことができます。SID の整合性を維持するには、すべてのファイルをまとめて sccs edit します。変更は、必要に応じて任意のファイルに行うことができます。そしてすべてのファイル (変更されていないものも含む) をチェックインしてください。edit および delta の実行時に引数として SCCS のサブディレクトリを指定すると、すべてのファイルを簡単にチェックアウトおよびチェックインすることができます。
$ sccs edit SCCS . . . $ sccs delta SCCS
SCCS サブディレクトリを引数として delta サブコマンドを実行すると、コメントの入力を 1 回だけ要求されます。コメントは、チェックインされるすべてのファイルに適用されます。変更されたファイルを特定するには、各ファイルのバージョンログ (デルタテーブル) の "lines added, deleted, unchanged" のフィールドを比較します。
プログラムの新しいリリースを作成するには、編集用のファイルをチェックアウトする際に、edit で -rn オプションを使用します。n に作成するリリース番号を指定します。
$ sccs edit -r 2 program.c
この場合は、新しいバージョンのデルタを使用するときに、そのデルタがリリース 2 での最初のデルタになり、SID が 2.1 となります。ディレクトリにあるすべての SCCS のファイルのリリース番号を変更するには、以下のコマンドを使用します。
$ sccs edit -r 2 SCCS
SCCS が s. ファイル (履歴ファイル) を更新する際には、x. ファイルという一時コピーに書き込みます。更新が終了すると、SCCS は x. ファイルの内容を古い s. ファイルに上書きします。これにより、処理が異常終了した場合でも履歴ファイルは失われません。x. ファイルは、履歴ファイルと同一のディレクトリに作成され、履歴ファイルと同じアクセス権が与えられ、実効ユーザーによって所有されます。
SCCS ファイルが同時に更新されることを防止するために、履歴ファイルを更新するサブコマンドは、z. ファイルというロックファイルを作成します。z. ファイルには、更新を実行するプロセスの PID が含まれています。更新が終了すると、z. ファイルは削除されます。z. ファイルは、SCCS ファイルが含まれているディレクトリ中にモード 444 (読み取り専用) で作成され、実効ユーザーによって所有されます。
SCCS ファイルに適用されるデルタは、ツリーのノード (節) とみなすことができます。このツリーのルート (根) は、ファイルの最初のバージョンです。ルートのデルタ (ノード) の番号は、デフォルトでは「1.1」です。それ以降のデルタ (ノード) は、1.2、1.3 と順に番号が付きます。前述のように、SID はリリース番号とレベル番号を示します。後続のデルタでは、レベル番号が 1 ずつ増えていきます。また、ファイルを大幅に変更する際に、新しいリリースをチェックアウトする方法についてもすでに説明しました。前のリリースで新しいレベルを指定した場合を除き、新しいリリース番号は、後続のすべてのデルタにも適用されます。
したがって、ファイルは下図のように推移します。
この構造は、SCCS デルタツリーの幹と呼びます。幹は、SCCS ファイルの通常の進展経過を表しています。あるデルタの変更は、それ以前のすべてのデルタに依存しています。
ただし、ツリーに分岐を作成すると便利な場合があります。たとえば、バージョン 1.3 が製品化されていて、リリース 2 の開発がすでに進行しているプログラムがあるとします。この場合は、リリース 2 のデルタがすでに存在している可能性があります。
ユーザー (顧客) から、バージョン 1.3 での問題点が報告され、リリース 2 の公開までその修正を延期できないとします。問題を修正するために必要な変更は、バージョン 1.3 のデルタに対して行う必要があります。このため、リリース 2 での作業とは別に、新しいバージョンを作成する必要があります。こうして、新しいデルタによってツリー上に新しい分岐が形成されます。
分岐デルタの SID は、次のようにリリース番号、レベル番号、分岐番号、シーケンス番号の 4 つの部分で構成されます。
release.level.branch.sequence
分岐番号は、特定の幹のデルタの子孫である (幹のデルタから派生した) 分岐それぞれに対して、最初の分岐は 1、次は 2 というように順に割り当てられます。シーケンス番号は、特定の分岐に属する各デルタに順次割り当てられます。したがって、下図のように、1.3.1.1 は、デルタ 1.3 から派生した最初の分岐の最初のデルタを示します。
分岐の概念は、ツリー中のその他のデルタにも適用されます。生成されたデルタの名前は、前述のように決定されます。分岐したデルタでは、リリース番号とレベル番号は、幹にある祖先のデルタと常に同一になります。
分岐番号は、幹との相対的な位置とは無関係に、分岐が作成された順で割り当てられます。したがって、分岐デルタは常に名前から識別できます。幹のデルタを分岐デルタの名前から識別できますが、幹のデルタから分岐デルタを特定することはできません。
たとえば、デルタ 1.3 から派生する分岐が 1 つある場合は、その分岐のすべてのデルタは 1.3.1.n という名前になります。この分岐のデルタからさらに派生する分岐が 1 つある場合は、新しい分岐のすべてのデルタは 1.3.2.n という名前になります。
デルタの名前が 1.3.2.2 の場合は、そのデルタが 2 番目に作成された分岐上の 2 番目のデルタで、その幹は デルタ 1.3 ということだけを特定できます。
特に、デルタ 1.3.2.2 の名前から、そのデルタと幹にある祖先のデルタ (1.3) の間にあるデルタをすべて特定することはできません。
分岐デルタを使用してさらにツリー構造を形成できますが構造が複雑になるので、分岐はできるだけ少なくすることをお勧めします。
並行して開発している、バグの修正やテストを行うための別のバージョンを追跡する必要がある場合は、分岐を使用できます。ただし分岐を作成する前に、SCCS admin コマンドを以下のように使用して履歴ファイルの b (branch) フラグを有効にする必要があります。
$ sccs admin -f b program.c
-fb オプションは、履歴ファイル中に b フラグを設定します。
program.c のデルタ 1.3 から分岐を作成するには、次のように sccs edit サブコマンドを使用します。
$ sccs edit -r 1.3 -b program.c
編集したバージョンをチェックインすると、分岐デルタの SID に 1.3.1.1 が含まれます。この分岐から以降に作成するデルタは、1.3.1.2 から順に SID が割り当てられます。
通常、get を使用して取り出したバージョンには分岐デルタは含まれていません。分岐バージョン (分岐デルタを関連付けたバージョン) を取り出すには、-r オプションを使用して明示的に指定する必要があります。次の例のようにシーケンス番号を省略すると、SCCS は分岐中で最上位 (最後) のデルタを取り出します。
$ sccs get -r 1.3.1 program.c 1.3.1.1 87
テストの完了後に、テストした機能を製品に組み込む場合があります。しかし、製品の開発は幹のバージョンで進行したために、分岐バージョンと幹での最新バージョンとの間に互換性がない場合があります。
この問題を解決する場合は、sccs edit の -i オプションを使用して、ファイルをチェックアウトする際に含めるデルタのリストを指定すると便利です。指定したデルタでの変更が衝突する場合は警告が表示されます。衝突は、あるデルタでは削除する必要がある行が、別のデルタでは挿入する必要がある場合に発生します。衝突の解決はユーザーが行いますが、衝突している箇所は特定することができます。
履歴ファイルおよびすべての一時 SCCS ファイルは、SCCS サブディレクトリに保存されます。標準のファイル保護機構に加えて、SCCS では、特定のリリースを凍結したり、リリースへのアクセスを特定のユーザーに制限できます (詳細は、sccs admin(1) を参照してください)。SCCS 以外のユーティリティによる修正を禁止するため、通常は履歴ファイルのアクセス権は 444 (すべてのユーザーに対して読み取り専用) に設定されます。通常、履歴ファイルは編集しないでください。
履歴ファイルへのリンクは 1 つだけにする必要があります。SCCS ユーティリティは、修正用のコピー (x. ファイル) を変更してそのコピーの名前を変更することによって、履歴ファイルを更新します。
help サブコマンドは、SCCS のエラーメッセージおよびユーティリティに関する情報を表示します。
help では、引数として SCCS ユーティリティ名または SCCS のエラーメッセージのコード (括弧で示されます) を指定する必要があります。ディレクトリ /usr/ccs/lib/help には、help が表示するさまざまなメッセージが含まれているファイルがあります。
admin コマンドを使用して、多数のパラメータ、特にフラグを設定できます。フラグは、-f オプションを使用して追加できます。
たとえば、以下のコマンドは、d フラグの値を 1 に設定します。
$ sccs admin -f d1 program.c
このフラグは、以下のコマンドを使用して削除できます。
$ sccs admin -d d program.c
最も便利なフラグを以下に示します。
sccs edit で -b オプションを使用して、分岐を作成することができます (「分岐」を参照してください)。
sccs get または sccs edit で使用されるデフォルトの SID です。これがリリース番号の場合は、特定のリリースだけにバージョンが制限されます。
ID キーワードがファイルに含まれていない場合に、エラーを表示します。これは、ID キーワードがないバージョン、または誤って ID キーワードが展開されているバージョンをチェックインすることを防ぐのに便利です。
%Y% という ID キーワードがこのフラグの値に置き換えられます。
file で指定したファイルに含まれるテキストを、s. ファイルにコメントとして保存します。マニュアルや設計と実装について説明するドキュメントなどを指定します。-t オプションを使用すると、s. ファイルを他のユーザーに渡す場合に、ドキュメントも確実に渡すことができます。file を省略すると、コメントは省略されます。コメントを表示するには、prt -t を使用します。
sccs admin コマンドは、ファイルに対して何度でも安全に使用できます。admin を使用する際に、現在のバージョンを取り出す必要はありません。
val サブコマンドを使用すると、履歴ファイルに関する検査を行うことができます。val は、以下の状態になっていないかどうかを常に検査します。
履歴ファイルが壊れている。
履歴ファイルを開いて読み取ることができない。
ファイルが SCCS 履歴に含まれていない。
val で -r オプションを使用すると、指定した SID が存在するかどうかを調べます。
他のユーザーによる編集が原因で、履歴ファイル自体が破壊されることがあります。ファイルには検査合計 (チェックサム) が含まれるため、破壊されたファイルを読み込むたびにエラーが表示されます。検査合計を修正するには、以下のコマンドを使用します。
$ sccs admin -z program.c
履歴ファイルが破壊されていると SCCS で表示されたときは、検査合計が正しくないということよりも重大な障害を示している場合があります。履歴ファイルを修正する前に、現在の変更内容を保存してください。
キーワード |
展開結果 |
---|---|
%Z% |
@(#) (what コマンド用の検索文字列) |
%M% |
現在のモジュール (ファイル) 名 |
%I% |
割り当てられている最上位の SID |
%W% |
%Z% %M% タブ %I% の短縮形 |
%G% |
%I% キーワードに対応するデルタの日付 |
%R% |
現在のリリース番号 |
%Y% |
-t フラグの値 (sccs admin により設定) |
表 5-2 SCCS ユーティリティコマンド
SCCS ユーティリティプログラム |
|
---|---|
コマンド |
マニュアルページ名 |
admin | sccs-admin(1) |
cdc | sccs-cdc(1) |
comb | sccs-comb(1) |
delta | sccs-delta(1) |
get | sccs-get(1) |
help | sccs-help(1) |
prs | sccs-prs(1) |
prt | sccs-prt(1) |
rmdel | sccs-rmdel(1) |
sact | sccs-sact(1) |
sccsdiff | sccs-sccsdiff(1) |
unget | sccs-unget(1) |
val | sccs-val(1) |
what | what(1) |
表 5-3 prs -d で指定するデータキーワード
キーワード |
データ項目 |
ファイルセクション |
値 |
形式 |
---|---|---|---|---|
:Dt: |
デルタ情報 |
デルタテーブル | :Dt: = :DT: :I: :D: :T: :P: :DS: :DP: |
1 行 |
:DL: |
デルタ行の統計情報 |
デルタテーブル | :Dt: = :Li:/:Ld:/:Lu: |
1 行 |
:Li: |
delta により挿入された行 |
デルタテーブル | nnnnn |
1 行 |
:Ld: |
delta により削除された行 |
デルタテーブル | nnnnn |
1 行 |
:Lu: |
delta により変更されていない行 |
デルタテーブル | nnnnn |
1 行 |
:DT: |
デルタの種類 |
デルタテーブル | D または R |
1 行 |
:I: |
SCCS ID 文字列 (SID) |
デルタテーブル | :Rf3:.:Lf3:.:Bf3:.:S: |
1 行 |
:R: |
リリース番号 |
デルタテーブル | nnnn |
1 行 |
:L: |
レベル番号 |
デルタテーブル | nnnn |
1 行 |
:B: |
分岐番号 |
デルタテーブル | nnnn |
1 行 |
:S: |
シーケンス番号 |
デルタテーブル | nnnn |
1 行 |
:D: |
デルタが作成された日付 |
デルタテーブル | :Dy:/:Dm:/:Dd: |
1 行 |
:Dy: |
デルタが作成された年 |
デルタテーブル | nn |
1 行 |
:Dm: |
デルタが作成された月 |
デルタテーブル | nn |
1 行 |
:Dd: |
デルタが作成された日 |
デルタテーブル | nn |
1 行 |
:T: |
デルタが作成された時 |
デルタテーブル | :Th:::Tm:::Ts: |
1 行 |
:Th: |
デルタが作成された時間 |
デルタテーブル | nn |
1 行 |
:Tm: |
デルタが作成された分 |
デルタテーブル | nn |
1 行 |
:Ts: |
デルタが作成された秒 |
デルタテーブル | nn |
1 行 |
:P: |
デルタを作成したユーザー |
デルタテーブル | ログ名 |
1 行 |
:DS: |
デルタのシーケンス番号 |
デルタテーブル | nnnn |
1 行 |
:DP: |
前のデルタのシーケンス番号 |
デルタテーブル | nnnn |
1 行 |
:DI: |
追加、削除、無視されたデルタのシーケンス番号 |
デルタテーブル | :Dn:/:Dx:/:Dg: |
1 行 |
:Dn: |
追加されたデルタ (シーケンス番号) |
デルタテーブル | :DS: :DS: ... |
1 行 |
:Dx: |
削除されたデルタ (シーケンス番号) |
デルタテーブル | :DS: :DS: ... |
1 行 |
:Dg: |
無視されたデルタ (シーケンス番号) |
デルタテーブル | :DS: :DS: ... |
1 行 |
:MR: |
デルタの MR (変更要求) の数 |
デルタテーブル | テキスト |
複数行 |
:C: |
デルタのコメント |
デルタテーブル | テキスト |
複数行 |
:UN: |
ユーザー名 |
ユーザー名 | テキスト |
複数行 |
:FL: |
フラグのリスト |
フラグ | テキスト |
複数行 |
:Y: |
モジュールの種類のフラグ |
フラグ | テキスト |
複数行 |
:MF: |
MR の妥当性検査のフラグ |
フラグ | yes または no |
複数行 |
:MP: |
MR の妥当性検査のプログラム名 |
フラグ | テキスト |
1 行 |
:KF: |
キーワードエラー / 警告フラグ |
フラグ | yes または no |
1 行 |
:BF: |
分岐フラグ |
フラグ | yes または no |
1 行 |
:J: |
連結編集のフラグ |
フラグ | yes または no |
1 行 |
:LK: |
ロックされたリリース |
フラグ | :R: ... |
1 行 |
:Q: |
ユーザー定義キーワード |
フラグ | テキスト |
1 行 |
:M: |
モジュール名 |
フラグ | テキスト |
1 行 |
:FB: |
切り下げの境界 |
フラグ | :R: |
1 行 |
:CB: |
切り上げの境界 |
フラグ | :R: |
1 行 |
:Ds: |
デフォルトの SID |
フラグ | :I: |
1 行 |
:ND: |
NULL データフラグ |
フラグ | yes または no |
1 行 |
:FD: |
ファイルのコメント |
コメント | テキスト |
複数行 |
:BD: |
本体 |
本体 | テキスト |
複数行 |
:GB: |
取得した本体 |
本体 | テキスト |
複数行 |
:W: |
what(1) 文字列の形式 |
N/A | :Z: :M:¥t:I: |
1 行 |
:A: |
what(1) 文字列の形式 |
N/A | :Z: :Y: :M: :I: :Z: |
1 行 |
:A: |
what(1) 文字列の区切り文字 |
N/A | @(#) |
1 行 |
:F: |
SCCS ファイル名 |
N/A | テキスト |
1 行 |
:PN: |
SCCS ファイルのパス名 |
N/A | テキスト |
1 行 |