[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12. ファイルの扱い方

オペレーティングシステムは, データを指定したファイル(file)に恒久的に保存します. ですから, Emacsで編集するテキストの多くはファイルから取り込み, 最終的にはファイルに格納されます.

ファイルを編集するには, Emacsに対してファイルを読むように指示して, ファイルの内容のコピーを入れたバッファを用意させる必要があります. これを, ファイルを訪問する/訪れる(visiting)といいます. 編集コマンドはバッファ内のテキストに直接作用します. つまり, Emacs内にあるコピーを操作します. バッファをファイルに保存(save)した場合に限り, 変更はファイルそのものに反映されます.

ファイルを訪問したり保存したりすることに加えて, Emacsは, ファイルを, 削除したり, コピーしたり, 名前を変更したり, 別のファイルへ追加したり, 複数の版を保持したり, ファイルディレクトリを操作したりできます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.1 ファイル名

ファイルを操作するほとんどのEmacsコマンドには, ファイル名を指定する必要があります. (保存と復元の操作を除く. バッファはこれらの操作に対して使うファイル名を記録している. ) ファイル名は, ミニバッファを使って入力します(see section ミニバッファ). 長いファイル名の指定を簡単にする補完も使えます. See section 補完.

多くの操作には, デフォルトファイル名があり, <RET>だけを打って空の引数を指定した場合に使われます. 通常, デフォルトファイル名は, カレントバッファで訪問したファイルの名前です. こうすることで, Emacsのファイルコマンドで当該ファイルを操作するのが簡単になります.

各バッファにはデフォルトディレクトリがあります. 通常は, そのバッファの訪問先のファイルのディレクトリと同じです. ディレクトリを指定しないでファイル名を入力すると, デフォルトディレクトリを使います. スラッシュ(‘/’)で始まらない相対的なディレクトリを指定すると, デフォルトディレクトリ相対に解釈します. デフォルトディレクトリは変数default-directoryに保持されていて, バッファごとに別々の値を持ちます.

たとえば, デフォルトファイル名が‘/u/rms/gnu/gnu.tasks’ならば, デフォルトディレクトリは‘/u/rms/gnu/’です. ディレクトリを指定しないで‘foo’とだけ打つと, ‘/u/rms/gnu/foo’を意味します. ‘../.login’は, ‘/u/rms/.login’を意味します. ‘new/foo’は, ファイル名‘/u/rms/gnu/new/foo’を意味します.

コマンドM-x pwdは, カレントバッファのデフォルトディレクトリを表示し, コマンドM-x cdは, それを(ミニバッファで読んだ値に)設定します. バッファのデフォルトディレクトリは, cdコマンドを使ったときだけ変更されます. ファイルを訪問しているバッファのデフォルトディレクトリは, 訪問したファイルのディレクトリに初期化されます. C-x bで作ったバッファのデフォルトディレクトリは, その時点のカレントバッファのデフォルトディレクトリと同じです.

デフォルトディレクトリは, ミニバッファでファイル名を読むときに, 実際にミニバッファに表示されます. これには2つの目的があります. デフォルトが何であるかを示すことで, 相対ファイル名を打ち込めるようにし, しかも, その意味を確実に知ることができるようにします. もう1つは, デフォルトディレクトリを編集して, 別のディレクトリを指定できるようにします. 変数insert-default-directorynilに設定すると, デフォルトディレクトリを挿入しません.

ミニバッファで入力するとき, テキストの一部として入っているデフォルトディレクトリを無視して, 絶対ファイル名を打っても何の問題もありません. 最終的なミニバッファの内容は不正なように見えても, そうではありません. たとえば, ミニバッファには‘/usr/tmp/’が入っていて ‘/x1/rms/foo’を追加すると, ‘/usr/tmp//x1/rms/foo’となります. Emacsは連続した2個のスラッシュの始めのスラッシュまでをすべて無視するので, 結果として‘/x1/rms/foo’となります. See section ファイル名入力用のミニバッファ.

ファイル名の中の‘$’は環境変数で置き換えられます. たとえば, シェルコマンド‘export FOO=rms/hacks’で, 環境変数FOOを設定してあるとします. そうすると, ‘/u/rms/hacks/test.c’の略称として ‘/u/$FOO/test.c’や‘/u/${FOO}/test.c’を使えます. 環境変数の名前は, ‘$’のうしろにある英数字全部です. あるいは, ‘$’のうしろにある括弧で囲まれたものです. シェルコマンドで設定した環境変数がEmacsに影響を及ぼすのは, Emacsを起動するまえに設定したものに限ります.

名前の中に‘$’があるファイルを参照するには, ‘$$’と打ちます. 1個の‘$’に対して変数の置き換えを行うときに, この2個の‘$’は1個の‘$’に変換されます. あるいは, ファイル名全体を‘/:’でクォートします (see section クォートしたファイル名).

(変数の)置き換えを行うLisp関数はsubstitute-in-file-nameです. 置き換えは, ミニバッファで読んだファイル名だけに適用されます.

変数file-name-coding-systemnil以外を設定すると, ファイル名に非ASCIIを含めることができます. See section コーディングシステムの指定.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.2 ファイルを訪問する

C-x C-f

ファイルを訪問する(find-file).

C-x C-r

ファイルを眺めるために訪問し, 変更を許さない (find-file-read-only).

C-x C-v

最後に訪問したファイルのかわりに, 別のファイルを訪問する (find-alternate-file).

C-x 4 f

別のウィンドウでファイルを訪問する (find-file-other-window). 選択されているウィンドウに表示されている内容は変化しない.

C-x 5 f

新たなフレームでファイルを訪問する (find-file-other-frame). 選択されているフレームに表示されている内容は変化しない.

M-x find-file-literally

ファイルの内容をいっさい変換せずに訪問する.

ファイルを訪問する/訪れるとは, ファイルの内容のコピーを編集できるようにEmacsバッファに入れることです. Emacsは, 訪問する各ファイルごとに新たにバッファを作ります. バッファ名は, ディレクトリ部分を取りさったファイル名から作ります. たとえば, ファイル名‘/usr/rms/emacs.tex’の バッファ名は‘emacs.tex’となります. その名前のバッファがすでに存在するならば, まだ使われていない名前になるようなもっとも小さい数を使って, ‘<2>’, ‘<3>’などを付加して唯一の名前を作ります.

各ウィンドウのモード行にはウィンドウ内に表示している バッファ名が示されているので, 編集しているバッファが何かいつでもわかります.

編集コマンドによる変更は, Emacsバッファに対して行われます. バッファを保存するまでは, 変更は, 訪問先のファイルや他のどんな恒久的なものにも影響しません. バッファを保存するとは, バッファの現在の内容をそのバッファの訪問先のファイルに書き出すことです. See section ファイルを保存する.

バッファに未保存の変更がある場合, バッファは変更されているといいます. バッファを保存しないと変更内容が失われてしまうので, これは重要なことです. モード行の左端近くに2個の星印を表示して, バッファが変更されていることを示します.

ファイルを訪問するには, コマンドC-x C-ffind-file)を使います. このコマンドに, 訪問したいファイル名を続けて<RET>で終えます.

ファイル名はミニバッファ(see section ミニバッファ)で読まれ, このときデフォルトや標準的な方法の補完を使えます(see section ファイル名). ミニバッファ内でC-gと打てば, C-x C-fをアボートできます.

C-x C-fが正しく完了したことは, 画面上に新たに現れるテキストと モード行に現れる新たなバッファ名で確認できます. 指定したファイルが存在せず作成もできない場合や読めない場合には, エコー領域にエラーメッセージが表示されます.

すでに訪問しているファイルを再度訪問すると, C-x C-fは別のコピーを作らずに, そのファイルを入れた既存のバッファを選択します. しかし, そうするまえに, 訪問してから, あるいは, 保存してから以降に ファイルが変更されたかどうか検査します. ファイルが変更されていると警告メッセージを表示します. See section 同時編集に対する保護.

新たにファイルを作りたいときにはどうするのでしょう? 単に訪問すればよいのです. Emacsはエコー領域に‘(New File)’と表示しますが, それ以外に関しては, あたかも空のファイルが存在するかのようにふるまいます. 変更してから保存すれば, ファイルを作成できます.

Emacsはファイルの内容から, 行区切りの方法, すなわち, (GNU/LinuxやUNIXで使われる)改行, (Microsoftシステムで使われる)復帰改行, (Machintoshで使われる)復帰のみを認識します. さらに, Emacsの通常の方法, つまり, 改行文字で行を区切るように 内容を自動的に変換します. これは, コーディングシステム変換(see section コーディングシステム)の 一般的な機能の一部であり, さまざまの異なるオペレーティングシステムから持ってきた ファイルを同一の方法で編集できるようにします. テキストを変更してファイルに保存すると, Emacsは逆変換を行い, 必要ならば, 改行を 復帰改行や復帰のみに戻します.

指定したファイルが実際にはディレクトリならば, C-x C-fはEmacsのディレクトリブラウザであるdiredを起動するので, ディレクトリの内容を『編集』できます(see section ディレクトリエディタdired). diredは, ディレクトリ内のファイルを, 消去したり, 眺めたり, 操作するのに便利です. しかし, 変数 find-file-run-dirednilならば, ディレクトリを訪問しようとするとエラーになります.

指定したファイル名にワイルドカード文字が含まれていると, Emacsは一致するすべてのファイルを訪問します. ワイルドカード文字そのものを含む名前のファイルを訪問するには, See section クォートしたファイル名.

オペレーティングシステムが変更を許さないファイルを訪問すると, Emacsはバッファを読み出し専用に設定するので, 修正できなかったり, 修正できてもあとで保存に手間取ります. C-x C-qvc-toggle-read-only)で, バッファを書き込み可能にできます. See section その他のバッファ操作.

ときには, 自分でまちがって変更しないように, ファイルを読み出し専用で訪問したい場合があります. そういう場合には, コマンドC-x C-rfind-file-read-only)で ファイルを訪問します.

(ファイル名をまちがって打ったりして) 存在しないファイルを意図せずに訪問してしまったときには, C-x C-vコマンド(find-alternate-file)を使って 本当の目的のファイルを訪問します. C-x C-vC-x C-fと同様ですが, (バッファが変更されていればまず保存するかどうか聞いてから) カレントバッファを消去します. 訪問するファイル名を読むときには, ミニバッファにデフォルトファイル名全体を挿入し, ディレクトリ部分の直後にポイントを置きます. これは, ファイル名をほんの少しまちがって入力したときに便利です.

存在するのに読めないファイルを訪問すると, C-x C-fはエラーを通知します.

C-x 4 ffind-file-other-window)は, 別のウィンドウで, 指定したファイルを入れたバッファを選択することを除けば, C-x C-fと同じです. C-x 4 fを実行するまえに選択されていたウィンドウは, 同じバッファを表示したままです. ウィンドウを1つだけ表示しているときにこのコマンドを使うと, そのウィンドウを2つに分けて, 一方のウィンドウにはまえと同様に同じバッファを 表示しますが, もう一方には新たに指示したファイルを表示します. See section 複数のウィンドウ.

C-x 5 ffind-file-other-frame)も同様ですが, 新たなフレームを開くか, 捜しているファイルを表示している既存のフレームを見えるようにします. ウィンドウシステムを使っているときだけ, この機能を利用できます. See section フレームとXウィンドウシステム.

特別な符号化や変換をせずにファイルを文字の列として編集したいときには, M-x find-file-literallyコマンドを使います. このコマンドは, C-x C-fのようにファイルを訪問しますが, 形式変換(see section 整形済みテキストの編集), 文字コード変換(see section コーディングシステム), (圧縮を)自動展開(see section 圧縮されたファイルの参照)といったことをしません. (そのままの文字の列としてではなく)普通の方法で同じファイルを すでに訪問している場合には, このコマンドは, そのままの文字の列として訪問するかどうか聞いてきます.

2つの特別なフック変数で, ファイルを訪問する操作を修正して拡張できます. 存在しないファイルを訪問すると, find-file-not-found-hooksのリスト内の関数群を実行します. この変数は関数のリストを保持していて, 呼び出した関数の中のどれかがnil以外を返すまで1つ1つ順に呼び出します. ファイルが存在するかどうかに関わらず, どんなファイルを訪問するときでも find-file-hooksには関数のリストが入っていると仮定され, それらの1つ1つを順にすべて呼び出します. いずれの場合でも, 関数は引数を受け取りません. 2つの変数のうち, 先にfind-file-not-found-hooksを使います. これらの変数はノーマルフックではありません. これらの名前が‘-hook’ではなくて‘-hooks’で終っていることで, その事実を表しています. See section フック.

編集するファイルに対して自動的にメジャーモード(see section メジャーモードの選択方式)を 設定し, そのファイルに対して特別なローカル変数(see section ファイルにローカルな変数)を 定義する方法がいくつかあります.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3 ファイルを保存する

Emacsにおいてバッファを保存するとは, バッファの内容をそのバッファの訪問先のファイルへ書き戻すことです.

C-x C-s

カレントバッファを訪問先のファイルに保存する(save-buffer).

C-x s

任意のバッファかすべてのバッファをそれぞれの訪問先のファイルに保存する (save-some-buffers).

M-~

カレントバッファを変更していないことにする(not-modified).

C-x C-w

カレントバッファを指定したファイルに保存する(write-file).

M-x set-visited-file-name

カレントバッファを保存するファイルの名前を変更する.

ファイルを保存して変更を恒久的なものとするには, C-x C-ssave-buffer)と打ちます. 保存を完了するとC-x C-sはつぎのようなメッセージを表示します.

 
Wrote /u/rms/gnu/gnu.tasks

選択されているバッファが変更されていなければ (バッファを作って以降, あるいは, 最後に保存して以降に, 変更されていない), 保存しても何もならないので実際には保存しません. かわりに, C-x C-sはつぎのようなメッセージをエコー領域に表示します.

 
(No changes need to be saved)

コマンドC-x ssave-some-buffers)は, 変更された任意のバッファやすべてのバッファを保存できるようにします. 各バッファについて, 何をするか聞いてきます. このとき選べる返答は, query-replaceに対するものに似ています.

y

このバッファを保存し, 残りのバッファについても質問する.

n

このバッファを保存しないが, 残りのバッファについては質問する.

!

このバッファを保存し, 残りのすべてのバッファについても質問せずに保存する.

<RET>

何も保存せずにsave-some-buffersを終了する.

.

このバッファを保存し, 他のバッファについては何も聞かずに save-some-buffersを終える.

C-r

質問対象のバッファを閲覧する. 閲覧(view)モードから抜けると, save-some-buffersに戻りふたたび質問する.

C-h

これらのオプションについてのヘルプメッセージを表示する.

Emacsから抜けるキー列C-x C-cは, save-some-buffersを起動するので, 同じ質問をしてきます.

バッファを変更したけれども変更を保存したくないならば, それを避けるための処置をすべきでしょう. そうしないと, C-x sC-x C-cを使うたびに, まちがってバッファを保存してしまいがちです. 1つの方法は, M-~not-modified)と打つことです. これは, バッファが変更されていることを示すフラグを消します. こうしておくと, 保存コマンドはバッファを保存する必要がないと結論します. (‘~’は「否定」(not)を意味する数学記号としてしばしば使われる. よってM-~は, メタ付き「否定」. ) set-visited-file-name(下記参照)を使って, 別のファイルを訪問しているバッファである旨の印を付けることもできます. このときファイル名には, 重要でない使っていないものを指定します. あるいは, ファイルからテキストを再度読み直して, ファイルを訪問したり保存したりした以降のすべての変更を取り消します. これを復元(reverting)といいます. See section バッファを復元する. すべての変更がもとに戻るまでアンドゥコマンドC-x uを繰り返し使って, 変更しなかったことにもできます. しかし, 復元のほうが簡単です.

M-x set-visited-file-nameは, カレントバッファで訪問しているファイルの名前を変更します. このコマンドは, ミニバッファで新たなファイル名を読み取ります. そして, 訪問先ファイル名を設定し直し, それに従って(新しい名前が使われていなければ) バッファ名も変更します. set-visited-file-nameは, 新たに指定した訪問先のファイルへはバッファを保存しません. あとで保存する場合に備えて, Emacs内部の記録を変更するだけです. また, バッファには『変更された』旨の印を付け, C-x C-sがそのバッファを保存しようとするようにします.

別のファイルを訪問しているという旨の印をバッファに付けて, ただちに保存したい場合には, C-x C-wwrite-file)を使います. このコマンドは, set-visited-file-nameに続けてC-x C-sを 実行するのと等価です. ファイルを訪問していないバッファに対してC-x C-sを使うことは, C-x C-wと同じ効果があります. つまり, ファイル名を読み取り, バッファにはそのファイルを訪問しているという印を付け, バッファをそのファイルに保存します. ファイルを訪問していないバッファのデフォルトのファイル名は, バッファのデフォルトディレクトリとバッファ名を組み合わせて作ります.

新しいファイル名がメジャーモードを示唆するものであれば, C-x C-wは, 多くの場合, そのメジャーモードに切り替えます. コマンドset-visited-file-nameもそのようにします. See section メジャーモードの選択方式.

Emacsがファイルを保存しようとするときに, ディスク上の最新版の日付がEmacsが最後に読み書きしたものと合わなかったら, Emacsはそのことを通知します. というのは, 同時に編集したために引き起こされた問題である可能性があるので, ユーザーにただちに知らせる必要があるからです. See section 同時編集に対する保護.

変数require-final-newlinenil以外だと, Emacsはファイルを保存するたびに, ファイルの末尾に改行がなければ改行を挿入します. デフォルトはnilです.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3.1 バックアップファイル

多くのオペレーティングシステムでは, ファイルを書き換えるとファイルに入っていたそれまでの記録は 自動的に破棄されます. したがって, Emacsでファイルを保存すると, ファイルの古い内容は捨てられます. しかし, 実際に保存するまえに, 古い内容をバックアップファイル と呼ばれる別のファイルにEmacsが注意深くコピーすれば, 古い内容は破棄されません.

ほとんどのファイルでは, バックアップファイルを作るかどうかは 変数make-backup-filesで決まります. 多くのオペレーティングシステムでは, この変数のデフォルト値はtであり, Emacsはバックアップファイルを作ります.

版管理システム(see section VC(版管理, バージョンコントロール))が管理するファイルに対しては, バックアップファイルを作るかどうかは 変数vc-make-backup-filesで決まります. デフォルトはnilです. というのは, すべての古い版を版管理システムに保管してあるので, バックアップファイルは冗長だからです. See section VC作業ファイルの扱い方.

変数backup-enable-predicateのデフォルト値は, ‘/tmp’にあるファイルのバックアップファイルを 作らないようにします.

Emacsでは, 単一のバックアップファイルを保持することも, 編集した各ファイルごとに一連の番号付きバックアップファイルを 保持することもできます.

Emacsがファイルのバックアップファイルを作るのは, バッファからそのファイルへ最初に保存したときだけです. たとえ何度ファイルを保存したとしても, そのバックアップファイルは, ファイルを訪問する以前の内容を保持し続けます. 通常これは, 今の編集セッションを始める以前の内容を バックアップファイルが保持していることを意味します. しかしながら, バッファを消去してから再度ファイルを訪問すると, それ以降に保存するときには新たにバックアップファイルを作ります.

少なくとも一度は保存したとしても, バッファからもう1つバックアップファイルを作るように明示的に 指示することもできます. C-u C-x C-sでバッファを保存すると, このとき保存した版は, バッファを再度保存するときには バックアップファイルになります. C-u C-u C-x C-sもバッファを保存しますが, まずファイルの古い内容をバックアップファイルにします. C-u C-u C-u C-x C-s はその両方を行います. ファイルの以前の内容からバックアップファイルを作り, さらに, バッファを再度保存するとこのとき保存した版から もう1つバックアップファイルを作るように準備します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3.1.1 単一バックアップファイルと番号付きバックアップファイル

単一バックアップファイルを作ることを選択すると(デフォルト), バックアップファイルの名前は, 編集しているファイルの名前に‘~’を付加したものになります. したがって, ‘eval.c’のバックアップファイルは‘eval.c~’となります.

番号付きの一連のバックアップファイルを作ることを選択すると, バックアップファイルの名前は, もとのファイル名に ‘.~’と数字ともう1つ‘~’を付加したものになります. したがって, ‘eval.c’のバックアップファイルは, ‘eval.c.~1~’, ‘eval.c.~2~’, …, ‘eval.c.~259~’というように どこまでも続きます.

保護機構のために 普通の名前でバックアップファイルを書けなくなると, ユーザーのホームディレクトリの‘%backup%~’に バックアップファイルを書きます. そのファイルはたった1つしか存在できないので, 最新のバックアップにしか利用できません.

単一バックアップか番号付きバックアップかの選択は, 変数version-controlで制御されます. この変数に設定できる値はつぎのとおりです.

t

番号付きバックアップを作る.

nil

ファイルに対して番号付きバックアップファイルがすでにあるならば 番号付きバックアップを作る. さもなければ, 単一バックアップを作る.

never

どんな場合にも番号付きバックアップを作らない. つねに単一バックアップを作る.

各バッファではローカルにversion-controlを設定できるので, そのバッファのファイルに対するバックアップの作成方法を制御できます. たとえば, rmailモードでは, rmailファイルのバックアップを1個だけに限定するために, version-controlにはローカルにneverを設定します. See section ローカル変数.

環境変数VERSION_CONTROLを設定すると, さまざまなGNUユーティリティに どのようにバックアップファイルを扱うか指示できます. Emacsも環境変数に従って動作し, 開始時にそれに一致するようにLisp変数version-controlを設定します. 環境変数の値が‘t’か‘numbered’なら, version-controltになります. 環境変数の値が‘nil’か‘existing’なら, version-controlnilになります. 環境変数の値が‘never’か‘simple’なら, version-controlneverになります.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3.1.2 バックアップの自動削除

ディスク容量を無限に浪費することを避けるために, Emacsは番号付きバックアップの版を自動的に削除できます. 一般には, Emacsは始めの数個と最新の数個のバックアップを残して, そのあいだのものをすべて削除します. これは, 新たにバックアップを作るごとに行われます.

2つの変数kept-old-versionskept-new-versionsは, このような削除を制御します. それらの値は, それぞれ, 新たにバックアップを作るときに, 保持すべき最古(番号が最小)のバックアップの個数, 保持すべき最新(番号が最大)のバックアップの個数です. それらの値は, バックアップの新版を作った直後に使われることに 注意してください. 新たに作ったバックアップも, kept-new-versionsの数に含まれます. デフォルトでは, どちらの変数も2です.

delete-old-versionsnil以外ならば, 何もいわずに余分な中間の版を削除します. デフォルト値であるnilならば, 余分な中間の版を削除するかどうかを聞いてきます.

diredの.(ピリオド)コマンドも古い版を削除するために使えます. See section diredでのファイル削除.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3.1.3 コピーと改名

バックアップファイルは, 古いファイルをコピーする, あるいは, それを改名することで作ります. 古いファイルに複数の名前があると, これには違いが出てきます. 古いファイルを改名してバックアップファイルにすると, (古いファイルの)別の名前もバックアップファイルを指します. 古いファイルをコピーした場合には, (古いファイルの)別の名前は編集しているファイルを指し続け, その名前で参照される内容も新しい内容になります.

バックアップファイルを作る方法は, 元ファイルの所有者とグループにも影響します. コピーするならば, 何も変更されません. 改名すると, ファイルの所有者はあなたになり, ファイルのグループはデフォルトになります (オペレーティングシステムごとにグループのデフォルトは異なる).

所有者を変更することは, 多くの場合, よいことです. というのは, 所有者がつねに最後にファイルを編集した人を表すからです. 同様に, バックアップの所有者はその版を作った人を表します. ときには, ファイルの所有者を変更すべきでないファイルがあります. そのようなファイルについては, backup-by-copying-when-mismatchをローカルに設定する ローカル変数リストをファイルに入れておくのがよいです.

改名するかコピーするかは, 3つの変数で制御されます. デフォルトは, 改名です. 変数backup-by-copyingnil以外ならばコピーします. nilのときには, 変数backup-by-copying-when-linkednil以外ならば, 複数の名前を持つファイルではコピーし, 編集中のファイルには名前が1つだけなら改名します. 変数backup-by-copying-when-mismatchnil以外のときには, 改名するとファイルの所有者やグループが変更されるときにはコピーします. スーパーユーザーでEmacsを起動すると, backup-by-copying-when-mismatchのデフォルトはtです.

ファイルを版管理システム(see section VC(版管理, バージョンコントロール))で管理している場合には, 通常Emacsはそのファイルのバックアップを通常の方法では作りません. チェックインとチェックアウトは, ある意味でバックアップを作ることに似ています. 残念なことに, これらの操作は典型的にはハードリンクを切るという 類似性があります. つまり, あるファイルの別の名前を使っていたとすると そのファイル名がなくなるのです. Emacsにできることはありません. 版管理システムが処理します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.3.2 同時編集に対する保護

2人のユーザーが同じファイルを訪問し, 両者がそれを編集し, 両者がそれを保存すると, 同時編集が発生します. こういったことが起きていることを誰も知らせなければ, 最初に保存したユーザーは, あとになって自分の変更が失われていることを知るでしょう.

ある種のシステムでは, 2人目のユーザーがファイルを変更し始めたことを Emacsがただちに検知して警告を発します. すべてのシステムでは, ファイルを保存するときにEmacsが検査して, 他人の変更を上書きしようとしているならば警告します. ファイルを保存するかわりに適切な修正操作を行えば, 他人の作業結果を失うことを避けられます.

ファイルを訪問しているEmacsバッファで初めて修正を行うと, Emacsはそのユーザーがファイルをロックしたと記録します. (同じディレクトリ内に異なる名前のシンボリックリンクを作ることで実現する. ) 変更を保存するとEmacsはロックを消します. つまり, ファイルを訪問しているEmacsバッファに未保存の変更があるときには ファイルをロックしておくのです.

他人がロックしているファイルを訪問先とするバッファを 修正し始めると衝突が起こります. Emacsが衝突を検知すると, Lisp関数ask-user-about-lockを呼び出して, どうするかを聞いてきます. この関数をカスタマイズのために再定義することもできます. この関数の標準の定義では, ユーザーに質問をし, 3つの返答を受理します.

s

ロックを横取りする. ファイルをすでに変更していた人はロックを失い, あなたがロックを得る.

p

続行する. 誰かがファイルをロックしたままであるにもかかわらず, ファイルを編集する.

q

放棄する. これはエラー(file-locked)を引き起こし, バッファ内で修正しようとしたことは, 実際には行われない.

ロックはファイル名に基づいて動作することに注意してください. ファイルに複数の名前があると, Emacsには2つの名前が同じファイルで あることはわからないので, 2人のユーザーが異なる名前で同じファイルを編集することは防げません. しかし, 名前に基づいたロックなので, 保存しない限り実在しない新規ファイルの編集をEmacsはインターロック (14) できます.

Emacsがロックを作れる構成になっていないシステムもあります. また, ロックファイルを書けない場合もあります. こういった状況では, Emacsがあらかじめトラブルを検知することはできませんが, 他人の変更を上書きしてファイルを保存しようとしたときには, 衝突を検知できます.

Emacsやオペレーティングシステムがクラッシュすると, 古いロックファイルが残っていることあります. そのため, ときどき偽の衝突についての警告を受けとることがあるかもしれません. 偽の衝突であると確信できれば, Emacsにとにかく続行するように指示するpを使います.

Emacsは, バッファを保存するたびに, ディスク上のファイルの最終変更日時が最後に訪問/保存したときから 更新されていないことをまず検査します. 変更日時が不一致ならば, なんらかの方法でそのファイルが変更されたことを示し, Emacsが本当に保存するとそれらの変更が失われてしまいます. これを避けるために, Emacsは警告のメッセージを表示し, 保存するまえに確認を求めます. ファイルが変更された理由を承知していて, それが問題でないことを知っていることもあるでしょう. そうならば, yesと答えて続行できます. さもなければ, C-gで保存を中断して, その事態を調査するべきです.

同時編集が発生したことを知らされたときにまず行うべきことは, C-u C-x C-d(see section ファイルディレクトリ)でディレクトリ一覧を見ることです. このコマンドは, ファイルの現在の所有者を表示します. その人に連絡して, 編集を続けないように警告しましょう. そのつぎの段階は, 別の名前でEmacsバッファを保存して, diffで2つのファイルを比較することでしょう.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.4 バッファを復元する

広範囲にファイルを変更したあとで気が変わったときには, そのような変更を捨てるためにファイルのまえの版を読み込みます. これには, カレントバッファに作用する M-x revert-bufferを使います. 意図せずにバッファを復元することは, たくさんの作業結果を失うことになるので, このコマンドにはyesで確認を与える必要があります.

revert-bufferは, ファイルの先頭から同じ距離(文字数)に ポイントを保ちます. 少し編集しただけなら, 復元前後のポイント位置はだいたい同じ部分にあります. 徹底的に変更してしまったときには, 古いファイルでのポイント位置では まったく異なるテキスト部分に位置付けるでしょう.

復元すると, 改めて変更するまでは, そのバッファには『変更なし』の印が付きます.

diredバッファのように, ファイル以外のデータを反映するバッファでも 復元できる場合があります. その場合, 復元とは, 適切なデータに基づいて内容を計算し直すことを意味します. C-x bで明示的に作ったバッファを復元することはできません. そういった指示をすると, revert-bufferはエラーを報告します.

自動的にかつ頻繁に変更されるファイル, たとえば, 実行中のプロセスから出力されるログ, を編集するときには, C-x C-fでファイルを再訪問すると 何も聞かずにファイルを復元できると便利です.

こういったふるまいを指示するには, 変数revert-without-queryに正規表現のリストを設定します. これらの正規表現の1つにファイル名が一致すると, find-filerevert-bufferは, バッファが変更されていない限り, そのファイルが変更されていても復元します. (テキストを編集してしまったときには, 変更を捨てさるのはまちがっている. )


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.5 自動保存, 不慮の事故に対する備え

Emacsは(打鍵数に基づいて)定期的に, 訪問しているすべてのファイルを何も聞かずに保存します. これを自動保存(auot-saving)と呼びます. これは, システムがクラッシュしたときに 失ってしまう作業結果をある程度以下に制限します.

自動保存を実施する時間になるとEmacsは各バッファを調べて, そのバッファに自動保存が指定されていて, かつ, 最後に自動保存した以後に変更されている場合は, そのバッファを自動保存します. 実際にファイルを自動保存すると, エコー領域にメッセージ‘Auto-saving...’を表示します. 自動保存の最中に発生したエラーは捕獲されるので, 打ち込んだコマンドの実行に干渉することはありません.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.5.1 自動保存ファイル

自動保存は, 通常, 訪問先のファイルそのものへは保存しません. というのは, 予定の半分を変更しただけでプログラムにまだ一貫性がないのに 保存してしまうのは望ましくないからです. そのかわりに自動保存ファイルと呼ばれる別のファイルに自動保存し, (C-x C-sなどで)明示的に保存するよう指示されたときだけ, 訪問先のファイルに保存します.

通常, 自動保存ファイルの名前は, 訪問先のファイルの名前の前後に ‘#’を付加したものです. したがって, ファイル‘foo.c’を訪問したバッファは, ファイル‘#foo.c#’に自動保存されます. ファイルを訪問していないほとんどのバッファは, 明示的に指定したときだけ自動保存されます. それらのバッファの自動保存ファイルの名前は, バッファ名のまえに‘#%’, あとに‘#’を付けたものになります. たとえば, 送信するメッセージを作成するバッファ‘*mail*’は, ‘#%*mail*#’というファイルに自動保存されます. 自動保存ファイルの名前は, Emacsの一部(関数make-auto-save-file-nameauto-save-file-name-p)をプログラムし直さない限り, この方法で作られます. バッファの自動保存に使うファイル名は, そのバッファで自動保存をオンにしたときに計算されます.

大きなバッファで相当量のテキストを削除したときには, そのバッファの自動保存を一時的にやめます. 意図せずにテキストを削除してしまった場合には, 自動保存ファイルに削除してしまったテキストが残っているほうが, 自動保存ファイルとしてより役に立つからです. こうなったあとで自動保存をふたたびオンにするには, C-x C-sでバッファを保存するか, C-u 1 M-x auto-saveを使います.

訪問先のファイルそのものに自動保存を行いたい場合には, 変数auto-save-visited-file-namenil以外の値を設定します. こうすると, 自動保存と明示的な保存には, 何の違いもありません.

訪問先のファイルにバッファを保存すると, バッファの自動保存ファイルは削除されます. これを禁止するには, 変数delete-auto-save-filesnilを設定します. C-x C-wset-visited-file-nameで 訪問先ファイル名を変更すると, 新たな訪問先ファイル名に合わせて自動保存ファイルも改名されます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.5.2 自動保存の制御

変数auto-save-defaultnil以外ならば, ファイルを訪問するたびにそのファイルのバッファの自動保存をオンにします (ただしバッチモードを除く. see section Emacsの起動と終了). この変数のデフォルトはtなので, 通常, ファイルを訪問したバッファは自動保存されます. コマンドM-x auto-save-modeで, 既存バッファの自動保存をオン/オフできます. 他のマイナモードのコマンドと同じように, 正の引数を指定するとM-x auto-save-modeは自動保存をオンにし, 0か負の引数を指定すると自動保存をオフにし, 引数を指定しないと自動保存のオン/オフを切り替えます.

Emacsは, 最後に自動保存してから何文字打鍵したかに基づいて 定期的に自動保存します. 変数auto-save-intervalには, 自動保存の間隔を表す文字数を指定します. デフォルトは300です.

しばらく打鍵しないでいるときにも自動保存は行われます. 変数auto-save-timeoutは, 自動保存(およびガベッジコレクション)を 行うまでにEmacsが待つべき秒数を表します. (カレントバッファが大きいと, 実際の時間間隔も長くなる. これは, 大きなバッファの自動保存には時間がかかるので, その編集中は邪魔にならないようにするため. ) アイドルのときには, 自動保存はつぎの2つのことを達成します. 1つは, 端末からしばらく離れているときに, すべての作業結果が保存されることを保証すること. もう1つは, 実際に打鍵しているときの自動保存を いくぶんでも避けるようにすることです.

重大なエラーを受け取ったときにも, Emacsは自動保存を行います. これには, ‘kill %emacs’のようなシェルコマンドで Emacsジョブを強制終了した場合や, 電話回線やネットワーク接続が途切れた場合を含みます.

コマンドM-x do-auto-saveで, 自動保存の実施を明示的に指示できます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.5.3 自動保存ファイルからのデータ回復

コマンドM-x recover-file <RET> file <RET>で, 自動保存ファイルの内容から紛失データを復旧できます. このコマンドは, fileを訪問してから, (確認したあとで)その自動保存ファイル‘#file#’ から内容を回復します. そのあとに, C-x C-sfileそのものに復旧したテキストを保存します. たとえば, ‘foo.c’の自動保存のファイル‘#foo.c#’から ‘foo.c’を復旧するにはつぎのようにします.

 
M-x recover-file <RET> foo.c <RET>
yes <RET>
C-x C-s

M-x recover-fileは確認するまえに, 指定したファイルと自動保存ファイルが置かれたディレクトリの一覧を表示するので, それらのサイズや日付を比較できます. 自動保存ファイルのほうが古いと, M-x recover-fileはそのファイルを読み込むようには 聞いてきません.

Emacsやコンピュータがクラッシュしても, コマンドM-x recover-sessionを使えば, 編集中だったすべてのファイルを自動保存ファイルから復旧できます. このコマンドは, まず, 記録されている中断されたセッション一覧を表示します. 希望する箇所へポイントを移動し, C-c C-cと打ちます.

つぎに, recover-sessionはそのセッションで編集中だった 各ファイルについてそのファイルを復旧するか聞いてきます. yを答えると, recover-fileを呼び出し, 普通のとおりに動作します. もとのファイルとその自動保存ファイルの日付を表示し, ファイルを復旧するかどうかをもう一度聞いてきます.

recover-sessionが終了すると, 復旧を選んだファイルはEmacsバッファに入っています. これらのバッファを保存してください. こうすることで初めてファイルに保存できます.

中断されたセッションは, あとで復旧するために ‘~/.saves-pid-hostname’というファイルに記録されています. これらの名前の‘~/.saves’の部分は, auto-save-list-file-prefixの値です. この変数を個人の‘.emacs’ファイルで設定すれば, 別の場所にセッション記録を置くことができます. しかし, 同様にrecover-sessionも再定義して, 変更した新しい場所を探すようにする必要があります. 個人の‘.emacs’ファイルでauto-save-list-file-prefixnilを設定すると, 復旧のためのセッションを記録しません.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.6 ファイル名の別名

シンボリックリンクやハードリンクを使うことで, 同じファイルをいくつかの異なるファイル名で指すことができます. ハードリンクは, ファイルを直接に指している別の名前です. すべての名前は等しく有効で, それらに優劣はありません. 対照的に, シンボリックリンクは定義された別名の一種です. ‘foo’が‘bar’へのシンボリックリンクであるとき, どちらの名前でもファイルを指せますが, ‘bar’が本当の名前であり, ‘foo’は別名にすぎません. シンボリックリンクがディレクトリを指しているときには, より複雑な状況になります.

同一のファイルに対して2つの名前で訪問すると, Emacsは通常2つの別々のバッファを作成しますが, その状況を警告します.

同一のファイルを異なる名前で別々のバッファに訪問することを避けたいならば, 変数find-file-existing-other-namenil以外の値を設定します. そうすれば, どのファイル名を指定しようとも, find-fileはファイルを訪問している既存のバッファを使います.

変数find-file-visit-truenamenil以外であれば, バッファに記録するファイル名は, ユーザーが指定した名前ではなくて, ファイルの(すべてのシンボリックリンクをその先の名前に置き換えて得られる) 実名になります. find-file-visit-truenameを設定すると, find-file-existing-other-nameも暗に設定されます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7 VC(版管理, バージョンコントロール)

版管理システムは, ファイルの変更されていない部分を通常は一度だけ格納して, ソースファイルの複数の版を記録できるパッケージです. 版管理システムは, 各版の作成時刻, 作成者, その版の変更部分に関する記述などの履歴情報も記録します.

Emacsの版管理パッケージはVCと呼ばれます. このコマンドは, 3つの版管理システム, RCS, CVS, SCCSで動作します. GNUプロジェクトでは, フリーソフトウェアでありFree Software Foundationから 入手できるRCSとCVSを推奨します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.1 VC入門

VCはEmacsから版管理システムを使えるようにして, 編集作業を版管理操作に滑らかに統合します. VCは統一された版管理インターフェイスを提供するので, どの版管理システムを使っているかに関わらず, 同じ使い方ができます.

本節では, 版管理を概観するとともに, VCが扱う版管理システムの概要を説明します. 使用する版管理システムにすでに慣れているならば, 本節は読み飛ばしてください.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.1.1 利用可能な版管理システム

VCでは, 現在3つの版管理システム, つまり, バックエンドで動作します. RCS, CVS, SCCSの3つです.

RCSはフリーの版管理システムでFree Software Foundationから入手ができます. RCSは, 扱えるバックエンドの中では, たぶん, もっとも成熟したものです. VCコマンド群は, RCSに概念的にもっとも近いものです. RCSでできるほとんどのことはVCからもできます.

CVSは, RCSの上に作られてRCSの機能を拡張していて, より洗練されたリリース管理, 複数ユーザーの並行開発を許しています. CVSの下では, VCの基本的な編集操作を使えますが, あまり一般的でない操作に関しては, コマンド行からCVSを呼ぶ必要があります. CVSを使うには保管庫(リポジトリ, repository)を設定しなければなりませんが, ここで扱うには複雑すぎる話題です.

SCCSはフリーではありませんが, 版管理システムとしては広く使われています. 能力の観点からすれば, VCが扱える3つのうちでもっとも弱いです. SCCSに欠けている機能(たとえばスナップショット)はVC自身で 実現して補っていますが, 複数の枝分かれのようなVCの他のいくつかの機能はSCCSでは利用できません. RCSを使えない理由があるときに限ってSCCSを使うべきです.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.1.2 VCの概念

ファイルが版管理の管理下にあるとき, そのファイルは版管理システムに登録されているといいます. 各登録されたファイルには, ファイルの現状とその変更履歴を記述した対応する マスタファイルが存在します. この情報は, 現在の版や以前の版を再構成するのに十分です. 通常, マスタファイルには, それぞれの版について, その版の変更点を言葉で記述した記録項目も記録されています.

版管理の下で管理されているファイルを, そのマスタファイルに対応する作業ファイルと呼ぶこともあります. 普通のファイルと同様に, 作業ファイルを編集して変更します. (SCCSやRCSでは, ファイルを編集するまえにファイルをロック (15) する必要がある. ) 一連の変更を終えたら, ファイルをチェックイン, つまり, 記録項目とともに変更をマスタファイルに記録します.

CVSでは, 1つのマスタファイルに対応する作業ファイルを複数個持てます. しばしば, 各ユーザーが1個ずつ作業ファイルを持てます. RCSでもこのようにできますが, RCSの通常の使い方ではありません.

典型的な版管理システムには, 複数のユーザーが同じファイルを使う際の 調停を行うためのなんらかの機構が必要です. 1つの方法は(Emacsが同時編集の検出に使うロックに類似だが, それとは別の) ロックを使うことです. 別の方法は, ファイルをチェックインする時点で, 他人の変更分を併合することです.

ロックを使う版管理の場合, 作業ファイルは変更できないように 通常は読み出し専用です. 版管理システムに対して, 書き込み可能な作業ファイルを作り, それをロックするように要求します. 一度には1人のユーザーだけがこれをできます. 自分の変更分をチェックインすると, ファイルのロックを外し, 作業ファイルをふたたび読み出し専用にします. これにより, 他のユーザーがさらに変更するために ファイルをロックできるようになります. SCCSはつねにロックを使いますし, RCSも通常はロックを使います.

RCSでは別の方法もあって, 各ユーザーがいつでも作業ファイルを変更できます. このモードではロックは必要ありませんが, 使うこともできます. 新版を記録する方法は, やはりチェックインです.

CVSでは, 通常, 各ユーザーはいつでも各自の作業ファイルを変更できますが, チェックイン時に他のユーザーの変更分を併合する必要があります. しかし, CVSでもロックを使うようにもできます (see section VCのバックエンドに対するオプション).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.2 VCとモード行

版管理の下にあるファイルを訪問すると, Emacsはそのことをモード行に示します. たとえば, ‘RCS-1.3’は, そのファイルにはRCSが使われていて, 現在の版が1.3であることを表します.

バックエンドの名前と版番号のあいだの文字は, ファイルの版管理状態を示します. ‘-’は, (ロックを使っているのであれば) 作業ファイルがロックされていないこと, あるいは, (ロックを使っていないのであれば)ファイルが変更されていないことを表します. ‘:’は他のユーザー(たとえば, ‘jim’)がロックしていることを表し, ‘RCS:jim:1.3’のように表示されます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.3 VC下の基本的な編集

主要なVCコマンドは, 状況に応じてロックかチェックインを行う 汎用コマンドです.

C-x C-q
C-x v v

このファイルに対して論理的なつぎの版管理操作を実施する.

正確にいえば, この操作を行うコマンドはvc-next-actionであって, C-x v vにバインドしてあります. しかし, C-x C-qの通常の意味は, 読み出し専用バッファを書き込み可能にするか, あるいは, その逆を行います. この操作を, 適切な版管理操作を実施することで 版管理下で管理されているファイルに対しても同じことを 正しく行うように拡張したのです. 登録されたファイルに対してC-x C-qを打つと, C-x v vのように動作します.

このコマンドの正確な動作は, ファイルの状態と版管理システム(バックエンド) がロックを使うかどうかに依存します. SCCSとRCSは通常はロックを使いますが, CVSは通常はロックを使いません.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.3.1 ロック使用時の基本的な編集

(SCCSの場合とRCSのデフォルトの場合)ファイルに対してロックを使う場合, C-x C-qは, ファイルをロックする, あるいは, ファイルをチェックインするのいずれかを行います.

以上の規則は, CVSでロックを使用している場合にも適用できますが, 『ロックを横取りする』ことはありません.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.3.2 ロック非使用時の基本的な編集

CVSのデフォルトのように, ロックを使わないときには, 作業ファイルはいつでも書き込み可能です. ファイルを編集するまえにすべきことは何もありません. モード行の状態表示は, ファイルが変更されていなければ‘-’です. 作業ファイルに変更を保存するとただちに‘:’に変わります.

以下は, CVSを使っているときのC-x C-qの動作です.

以上の規則は, RCSのロックを使わないモードにも適用できますが, マスタファイルから自動的に変更を併合する機能は実装してありません. 残念なことに, あなたが編集を始めたあとに, 他のユーザーが同じファイルに変更を チェックインしても何も警告されないのです. しかも, このような事態が発生すると, あなたが自分の版をチェックインしたときに, そのユーザーの変更は実質的には取り除かれてしまいます (とはいえ, マスタファイルの中には残っているので, 完全になくなるわけではない). したがって, 自分の変更をチェックインするまえには, 現在の版が変更されていないことを確認する必要があります. Emacsの将来の版では, このような危険性を取り除き, RCSでも自動併合を行えるように考えています.

また, このモードでもRCSのロックを使えますが, 必須ではありません. ファイルを変更していないときにC-x C-qを使うと, RCSの通常の(ロックを使う)モードのように, ファイルをロックします.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.3.3 記録項目用バッファの機能

変更をチェックインすると, C-x C-qは記録項目をまず読みます. 記録項目を入力するように, ‘*VC-Log*’というバッファを立ち上げます. 入力し終えたら, ‘*VC-Log*’でC-c C-cと打ちます. 実際にチェックインを行うと, このように行われます.

チェックインをアボートするには, そのバッファではC-c C-cを 打たないでください. 別のバッファに切り替えて, 別の編集をします. 別のファイルをチェックインしようとしない限り, 入力していた記録項目は‘*VC-Log*’バッファに残っていますから, チェックインを完了するため, いつでもそのバッファに戻れます.

複数のソースファイルを同じ理由で変更したときには, 多くのファイルに同じ記録項目を指定できると便利です. こうするには, まえの記録項目の履歴を使います. コマンド, M-n, M-p, M-s, M-rは, ミニバッファの履歴コマンドのように働きます (ただし, これらのコマンドはミニバッファの外部で使う).

ファイルにチェックインするたびに, 記録項目用バッファはVC記録(vc-log)モードになります. このモードは2つのフック, text-mode-hookvc-log-mode-hookを 起動します. See section フック.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.4 旧版の調査と比較

版管理の便利な機能の1つは, ファイルの任意の版を調べたり, 2つの版を比較できることです.

C-x v ~ version <RET>

訪問しているファイルの版versionを それ専用のバッファで調べる.

C-x v =

カレントバッファの内容とファイルのチェックインした最新版とを比較する.

C-u C-x v = file <RET> oldvers <RET> newvers <RET>

fileの指定した2つの版を比較する.

C-x v g

表示色を変えてCVSの注記コマンドの結果を表示する.

1つの旧版を調べるには, ファイルを訪問してC-x v ~ version <RET>vc-version-other-window)と打ちます. これにより, ファイルの版versionのテキストを ‘filename.~version~’という名前のファイルに収め, 別のウィンドウのそれ専用のバッファでそのファイルを訪問します. (RCSでは, 旧版を選択して, それから枝分かれを作成できる. see section ファイルの複数の枝分かれ. )

しかし通常は, コマンドC-x v =vc-diff)で ファイルの2つの版を比較したほうが, もっと便利です. 引数を指定しないC-x v =では, カレントファイルの内容 (必要があればファイルに保存する)とファイルのチェックインしてある 最新版とを比較します. 数引数を指定したC-u C-x v =では, ファイル名と2つの版番号を読み取ってから, 指定したファイルの2つの版を比較します.

登録したファイルのかわりにディレクトリ名を指定すると, このコマンドは, そのディレクトリとその下にあるサブディレクトリに 置かれているすべての登録されたファイルの指定した2つの版を比較します.

チェックインしてある版は, その番号で指定します. 入力が空だと, (チェックインしてある版とは異なるかもしれない)作業ファイルの 現在の内容を指定します. 版番号のかわりに, スナップショット名(see section スナップショット)を指定することも できます.

このコマンドは, 変数diff-switchesで指定されるオプションを用いて, diffプログラムを実行して動作します. その出力は別のウィンドウの特別なバッファに表示されます. M-x diffコマンドと違って, C-x v =では新版と旧版の 相違箇所には移動できません. というのは, 通常, 一方の版, あるいは, 両方の版は, 比較するときにはファイルとしては存在していないからです. それらは, マスタファイルの記録の中に存在するだけです. M-x diffについてより詳しくは, See section ファイルの比較.

CVSで管理しているファイルに関しては, 一目でわかるように複数の表示色を使って, CVS注記コマンドの結果を表示できます. これには, M-x vc-annotateを使います. 赤は新版, 青は旧版, それらの中間色は中間の版を表します. 数引数nは, 時間尺度を伸ばします. つまり, ある表示色で表す期間をn倍します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5 VCの副次的なコマンド

本節では, VCの副次的なコマンドを説明します. 1日に一度くらい使うようなコマンドです.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5.1 VCへのファイル登録

ファイルを訪問してからC-x v ivc-register)と打つだけで, ファイルを版管理の管理下に置けます.

C-x v i

訪問したファイルを版管理に登録する.

ファイルを登録するには, Emacsはそのファイルに対してどの版管理システムを 使うか選ぶ必要があります. vc-default-back-endに, RCS, CVS, SCCSの いずれかを設定すれば, 明示的に指定できます. あるいは, ‘RCS’, ‘SCCS’, ‘CVS’という名前の サブディレクトリがあるなら, Emacsは対応する版管理システムを使います. 指定がまったくなければ, デフォルトでは, RCSがインストールされていればRCS, さもなければSCCSを選びます.

ロックを使用している場合には, C-x v iは, ファイルのロックを解除し読み出し専用にします. ファイルの編集を始めたい場合には, C-x C-qと打ちます. CVSにファイルを登録したあとでは, C-x C-qと打って最初の版を記録する必要があります.

新しく登録されたファイルの最初の版番号は, デフォルトでは1.1です. 異なるデフォルトを指定するには, 変数vc-default-init-versionに設定します. あるいは, C-x v iに数引数を指定すると, そのファイルだけに使う最初の版番号をミニバッファで読みます.

vc-initial-commentnil以外ならば, C-x v iはこのソースファイルの目的を記した初期コメントを読みます. これは記録項目(see section 記録項目用バッファの機能)を読むのと同じように動作します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5.2 VC状態表示コマンド

C-x v l

版管理の状態と変更履歴を表示する.

ファイルの詳しい版管理状態や履歴を見るには, C-x v lvc-print-log)と打ちます. 記録項目を含めてカレントファイルの変更履歴を表示します. 出力は別のウィンドウに表示されます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5.3 版管理操作のアンドゥ

C-x v u

バッファとファイルを最新のチェックインしてある版に復元する.

C-x v c

訪問先ファイルのマスタファイルに最後に入れた変更を取り除く. つまり, 最後のチェックインをアンドゥする.

これまでの一連の変更を破棄してチェックインしてある最新版へ復元したいときは, C-x v uvc-revert-buffer)を使います. ロックを使用しているときには, ファイルのロックを解除するので, 変更を始めるまえにまずファイルをロックし直す必要があります. チェックインした最新版から変更していないと判断できない限り, C-x v uは確認を求めてきます.

C-x v uは, ファイルをロックしたけれどもやはりファイルを変更しないと決めたときに, ロックを解除するコマンドでもあります.

すでにチェックインしてしまった変更を取り消すには, C-x v cvc-cancel-version)を使います. このコマンドは, チェックインした最新版のすべての記録を捨てさります. さらに, C-x v cは, 作業ファイルとバッファを 以前の版(捨てた最新版の1つまえの版)に復元するかどうか 聞いてきます.

noと答えると, VCはバッファでの変更を保持して ファイルもロックしたままにします. チェックインした変更に明らかなまちがいがあるとわかったときに, この「復元しない」という選択肢は便利です. 誤りを含んだチェックインを取り消し, 誤りを訂正してから, 改めてファイルをチェックインできます.

C-x v cがバッファを復元しないときには, そのかわりに, バッファ内のすべての版管理ヘッダの展開形をもとの形に戻します (see section 版管理ヘッダの挿入). なぜなら, バッファはもはや既存のどの版にも対応しないからです. ふたたびチェックインすると, チェックインの過程で, 新たな版番号として正しくヘッダを展開します.

しかしながら, RCSの‘$Log$’ヘッダを 自動的にもとの形に戻すことは不可能です. このヘッダの機能を使うなら, 取り消した版に対応する項目を削除することで, もとの形に手で戻す必要があります.

多くの作業結果を簡単に失ってしまうので, C-x v cを起動するときには十分注意してください.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5.4 VC下のdired

大きなプログラムを扱っているときは, ディレクトリの木構造全体の中で どのファイルが変更されたのかを調べたり, 版管理の下に置かれているすべてのファイルの状態を一度に見られると便利です. コマンドC-x v dvc-directory)を使えば, 版管理に関連したファイルだけを含んだディレクトリ一覧を作れます.

C-x v dは, VC diredモードを使うバッファを作ります. これは, 普通のdiredバッファ(see section ディレクトリエディタdired)にそっくりですが, (ロックされていたり, 未更新の)注意を払うべきファイルだけを 通常は表示します. これを簡素な表示と呼びます. 変数vc-dired-terse-displaynilを設定すると, VC diredは, 関連するすべてのファイル, つまり, 版管理の下に置かれたファイルとすべてのサブディレクトリを表示します (完全な表示). VC diredバッファのコマンドv tは, 簡素な表示と完全な表示を切り替えます. (see section VC diredコマンド. )

デフォルトでは, VC diredは, 指定したディレクトリやそれより下に置かれた 注意を払うべきファイルや関連するファイルの再帰的な一覧を作ります. この動作を変えるには, 変数vc-dired-recursenilを設定します. すると, VC diredは, 指定したディレクトリにあるファイルだけを表示します.

各ファイルを表す行には, ハードリンク数, 所有者, グループ, ファイルサイズの かわりに版管理状態があります. ファイルが変更されていなければ, つまり, マスタファイルの内容に同期しているならば, 版管理状態は空です. そうでなければ, 括弧で括ったテキストになります. RCSとSCCSでは, ファイルをロックしているユーザーの名前が示されます. CVSでは, cvs状態(‘cvs status’)を簡略化したものが示されます. つぎは, RCSを使っている場合の例です.

 
  /home/jim/project:

  -rw-r--r-- (jim)      Apr  2 23:39 file1
  -r--r--r--            Apr  5 20:21 file2

ファイル, ‘file1’と‘file2’が, 版管理の下に置かれていて, ‘file1’はユーザーjimがロックしていて, ‘file2’はロックされていません.

つぎは, CVSを使っている場合の例です.

 
  /home/joe/develop:

  -rw-r--r-- (modified) Aug  2  1997 file1.c
  -rw-r--r--            Apr  4 20:09 file2.c
  -rw-r--r-- (merge)    Sep 13  1996 file3.c

保管庫のものに比べて, ‘file1.c’は変更されていますが, ‘file2.c’は変更されていません. ‘file3.c’も変更されていますが, 保管庫には他の変更がチェックインされています. ‘file3.c’をチェックインするまえに, それらの変更を併合する必要があります.

VC diredで(『完全な表示』のときに)サブディレクトリを表示するときには, 版管理の下には絶対に置かれないものは省略します. デフォルトでは, ‘RCS’や‘CVS’などのVCのサブディレクトリが含まれます. これは, 変数vc-directory-exclusion-listを設定して カスタマイズできます.

普通のdiredのように, C-u C-x v dと打てば, ‘ls’プログラムに渡す追加オプションを指定して, VC diredの出力書式を微調整できます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.5.5 VC diredコマンド

VC diredモードでも, 通常のdiredコマンドはすべて普通に動作しますが, vは例外で, 版管理プレフィックスとして再定義してあります. vc-diffvc-print-logのようなVCコマンドは, v =v lいうように打てば起動できます. これらのコマンドの多くは, 現在行のファイルに作用します.

コマンドv vvc-next-action)は, 印を付けたすべてのファイルに作用するので, 複数のファイルを一度にロックしたりチェックインしたりできます. 複数のファイルに作用する場合, 各ファイルの現状に応じて個別に扱います. つまり, あるファイルはロックしたり, 別のファイルはチェックインしたりします. これは混乱の原因かもしれません. 同じ状態の一連のファイルに印を付けて, 混乱を防止するのはユーザーの責任です.

ファイルをチェックインするときには, v vは1つの記録項目を読んで, それをチェックインするすべての ファイルに使います. これは, 同じ変更に属する一連のファイルを一度にチェックインする場合に 便利です.

v tvc-dired-toggle-terse-mode)と打てばいつでも, (ロックされていたり, 内容が未更新のものだけを表示する) 簡素な表示と完全な表示とを切り替えられます. 特別なコマンド* lvc-dired-mark-locked)もあります. これは現在ロックされている(CVSの場合には, 内容が未更新である) すべてのファイルに印を付けます. つまり, 現在ロックされいるもの以外のすべてのファイルをバッファから 削除する別の方法は, * l t kと打つことです.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.6 ファイルの複数の枝分かれ

版管理の用途の1つは, ファイルの複数の『現在』版を維持することです. たとえば, さまざまな完了していない新しい機能を徐々に付け加えている プログラムの異なる版を持つかもしれません. そういった開発の独立した流れを(branch)と呼びます. VCでは, 枝を作ったり, 別の枝へ切り替えたり, 2つの枝を併合したりできます. しかし, 今のところ, RCSだけで枝を使えることに注意してください.

ファイルの開発の主要な流れを(trunk)と呼びます. 幹にある版は, 普通, 1.1, 1.2, 1.3, …と番号が付けられます. そのような版のどれからでも, 独立した枝を始めることができます. 版1.2から始まる枝の版番号は1.2.1.1となり, 同じ枝の後続の版番号は1.2.1.2, 1.2.1.3, 1.2.1.4, …となります. 版1.2から始まる別の枝があれば, それらの版番号は, 1.2.2.1, 1.2.2.2, 1.2.2.3, …となります.

版番号の最後の要素を省略したものを枝番号と呼びます. これは, その枝にある版の中でもっとも大きい番号の版, 先頭版を指します. まえの例の枝は, 枝番号1.2.1と1.2.2です.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.6.1 枝の切り替え

枝を切り替えるには, C-u C-x C-qと打ってから, 選択したい版番号を指定します. その版をロックしない(書き込み不可)で訪問するので, ロックするまえに調べることができます. このような枝の切り替えが可能なのは, ファイルがロックされていない場合に限ります.

枝の中での版番号を省略して枝番号だけを指定できます. すると, その枝の先頭版を選ぶことになります. <RET>だけを打つと, Emacsは幹の上のもっとも大きい版を選びます.

(幹を含む)どれかの枝へ切り替えたあとでは, 明示的に他の枝を選択するまで, それ以降のVCコマンドはその枝を使います.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.6.2 新しい枝の作成

先頭版(枝の中にある最新版)から新たな枝を作るには, 必要ならまずその版を選択してから, C-x C-qでそれをロックし, 必要な変更を施します. そして, 変更をチェックインするときに, C-u C-x C-qを使います. このコマンドでは, 新版に対する版番号を指定できます. 現在の版から始まる枝として適切な番号を指定する必要があります. たとえば, 現在の版が2.5ならば, その時点で存在する枝の数に依存しますが, 枝番号は, 2.5.1, 2.5.2, …です.

旧版(先頭版ではないもの)から新しい枝を作るには, その版をまず選択してから(see section 枝の切り替え), それをC-x C-qでロックします. 旧版をロックすると, 本当に新しい枝を作るのかどうか確認してきます. noで答えると, かわりに, 最新版をロックするかどうか聞いてきます.

変更してから, ふたたびC-x C-qと打って新版にチェックインします. こうすると選択した版から始まる新しい枝を自動的に作ります. 新しい枝を特に指定する必要はありません. なぜなら, 枝の先頭版でないところに新版を付け加える唯一の方法だからです.

枝を作ったあとでは, その枝に『留まり』ます. つまり, それ以降にチェックインすると, その枝に新版が作られます. 枝を去るには, C-u C-x C-qで明示的に別の版を選ぶ必要があります. ある枝から別の枝へ変更を移すには, 次節で説明する併合コマンドを使ってください.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.6.3 枝の併合

ある枝で変更を完了したときには, それらの変更をファイルの開発の主流(幹)に 取り込みたいことがしばしばあるでしょう. これは簡単な操作ではありません. というのは, 幹でも開発は進行しているので, 別の向きに変更されているファイルに変更を併合する必要があるからです. VCでは, vc-mergeコマンドで併合(とそれ以外のことも)できます.

C-x v m (vc-merge)

作業ファイルに変更を併合する.

C-x v mvc-merge)は, 一連の変更を作業ファイルの現在の版に併合します. このコマンドはまず, ミニバッファで枝番号か2つの版番号を読み取ります. そして, その枝での変更, あるいは, 指定した2つの版のあいだの変更を調べ, それらをファイルの現在の版に併合します.

例として, 枝1.3.1である機能を実装し終えたとしましょう. この間, 幹でも開発が進んでいて版1.5になっています. 枝での変更を幹に併合するには, まず, C-u C-x C-q <RET>と打って, 幹の先頭版へ行きます. 版1.5が現在の版になります. ファイルのロックを使っている場合には, C-x C-qと打って, 版1.5をロックして変更できるようにします. 続いてC-x v m 1.3.1 <RET>と打ちます. すると, 枝1.3.1での(枝の開始点である版1.3から枝の中にある最新版までの) 一連の変更を取り出して, それらを作業ファイルの現在の版に併合します. ここで, 変更された作業ファイルをチェックインできます. つまり, 枝での変更を取り込んだ版1.6を作れるのです.

チェックインするまえに, 枝から併合したあとにさらに編集することも可能です. しかし, 併合した版をチェックインしたあとで, ロックしてさらに編集するのが, 普通は賢いやり方です. こうすれば, 変更履歴をよりよく記録に残せます.

すでに修正されているファイルに変更を併合するときには, 変更が重複する場合があります. この状況を矛盾と呼びます. 矛盾した変更の辻褄を合わせることを矛盾の解消と呼びます.

併合中に矛盾が起こると, VCはこれらを検出し, それらをエコー領域に表示してユーザーに伝え, 併合を補佐してほしいかどうか聞いてきます. yesで答えると, ediffセッションを開始します (see Ediff: (ediff)Top section ‘Ediff’ in The Ediff Manual).

noで答えると, 矛盾する変更はどちらも矛盾印で囲ってファイルに挿入します. 矛盾する部分は, 下の例のようになります. 作業ファイルの名前は‘name’であり, ユーザーBの変更を収めたマスタファイルの版は1.11です.

 
<<<<<<< name
  User A's version
=======
  User B's version
>>>>>>> 1.11

この矛盾を解消するようにファイルを手で編集できます. あるいは, ファイルを訪問してからM-x vc-resolve-conflictsと打ちます. すると上に述べたediffセッションを開始します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.6.4 複数ユーザーの枝

ファイルの異なる枝上で同時に複数の開発者が作業すると有益なことが しばしばあります. CVSでは, デフォルトで, これができます. RCSでは, 複数のソースディレクトリを作れば可能です. RCSのマスタファイルを置いた共通のディレクトリを指す‘RCS’という名前の リンクを各ソースディレクトリに置きます. こうすれば, 各ソースディレクトリでは, それぞれ独自に版を選択できます. しかし, 同じ共通のRCSレコードをすべてで共有します.

ソースファイルにRCSの版管理ヘッダ(see section 版管理ヘッダの挿入)が入っていれば, この技法は信頼性があり自動的に動作します. ヘッダにより, Emacsはいつでも作業ファイルに入っている版番号がわかります.

ファイルに版管理ヘッダが入っていないときには, 各セッションごとにどの枝で作業しているかをEmacsに明示する必要があります. こうするには, ファイルを訪問してから, C-u C-x C-qと打ち, 正しい枝番号を指定します. これにより, 編集セッションではどの枝を操作しているかを Emacsが知っていることを保証します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.7 スナップショット

スナップショットとは, ファイルの版(登録されたファイルそれぞれに1つずつ) の集合に名前を付けたもので, 一塊として扱うことができます. スナップショットの重要な種類の1つは, リリースです. これは, ユーザーへ配布する準備が整ったシステムの(理論的には) 安定した版のことです.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.7.1 スナップショットの作成と使用

スナップショットに対しては, 基本的なコマンドが2つあります. 1つは名前を指定してスナップショットを作り, もう1つは指名したスナップショットを取り出すことです.

C-x v s name <RET>

カレントディレクトリやその下に置いてある登録されたファイルの それぞれの保存された最新版をnameという名前の スナップショットとして定義する (vc-create-snapshot).

C-x v r name <RET>

カレントディレクトリやその下に置いてある登録されたファイルすべてについて, スナップショットnameに対応する版を選択する.

カレントディレクトリやその下に置いてある登録されたファイルのいずれかが ロックされていると, このコマンドは何も変更せずにエラーを報告する. これは, 進行中の作業結果を上書きしてしまうことを避けるため.

スナップショットはとても少量の資源しか使いません. ファイル名一覧とスナップショットに属する版番号を 記録するに十分な量だけでいいのです. したがって, 使いものになるものをスナップショットにすることを 躇うことはありません.

C-x v =C-x v ~(see section 旧版の調査と比較)の引数として, スナップショットの名前を指定できます. したがって, スナップショットと現在のファイル, あるいは, 2つのスナップショット同士, あるいは, 指定した名前の版とスナップショット同士を比較できます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.7.2 スナップショットの弱点

VCのスナップショット機能は, RCSの名前付きコンフィギュレーションサポート (named-configuration support)をモデルにしています. RCS固有の機能を使っているため, RCSを使って作ったVCのスナップショット は, VCを使わなくても見えます.

SCCSでは, VC自身でスナップショット機能を実装しています. VCが使うファイルには, 名前/ファイル/版番号の3つ組みが含まれます. これらのスナップショットは, VCを使ったときだけ見えます.

スナップショットはチェックインした版の集合です. ですから, スナップショットを作るときには, すべてのファイルをチェックインしてあり, しかもロックしていないことを確認してください.

ファイルを改名したり削除すると, スナップショットに問題を生じます. これはVCに固有の問題ではなく, 版管理システムに一般的な設計上の問題で, まだ誰も満足ゆく解決をできていません.

登録されたファイルを改名するなら, そのマスタファイルも一緒に改名する必要があります (コマンドvc-rename-fileは自動的にこれを行う). SCCSを使っているならば, ファイル名を新しい名前にして スナップショットの記録も更新する必要があります (vc-rename-fileはこれも行う). 記録された名前ではもはや存在しないマスタファイルを参照する 古いスナップショットは無効です. VCは(古い名前では)取り出せません. スナップショットを手で更新する方法を説明するために RCSやSCCSを詳しく説明することは, 本書の範囲を越えています.

vc-rename-fileを使えば, 取り出し操作に使える程度にはスナップショットを保てますが, すべての問題を解決できるわけではありません. たとえば, プログラムのいくつかのファイルでは, 名前で他のファイルを参照しているでしょう. 少なくとも, makefileでは, 改名したファイルを指しているでしょう. 古いスナップショットを取り出すと, 改名したファイルは新しい名前で取り出しますが, makefileで使っている名前ではありません. ですから, 取り出しただけではプログラムは動かないでしょう.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.8 VCのその他のコマンドと機能

本節では, 使用頻度の少ないVCの機能を説明します.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.8.1 変更記録とVC

プログラムに対してRCSやCVSを使い, しかも, それらに変更記録ファイル (see section 変更記録)を保持しているならば, 版管理の記録項目から変更記録項目を自動的に生成できます.

C-x v a

カレントディレクトリにある変更記録ファイルを訪れる. そして, そのディレクトリに置いてある登録された各ファイルについて, 変更記録ファイルにある最新の項目以降にチェックインされた版に関する 新たな項目を作成する. (vc-update-change-log).

このコマンドはRCSやCVSだけで動作し, SCCSでは動作しない.

C-u C-x v a

上と同様であるが, カレントバッファのファイルに関する項目だけを探す.

M-1 C-x v a

上と同様だが, 現在訪問しているファイルのうち版管理の下に置かれているファイル すべてに関する項目を探す. このコマンドはRCSでのみ動作する. しかも, デフォルトディレクトリに関する すべての項目を変更記録に追加するが, これは適切でないこともある.

たとえば, ‘ChangeLog’の最初の行の日付が1999年4月10日であり, それ以降のチェックインは Nathaniel Bowditchが1999年5月22日に ‘Ignore log messages that start with `#'.’という記録で ‘rcs2log’にチェックインしたものだけだとしましょう. そうすると, C-x v aは‘ChangeLog’を訪問して, つぎのようなテキストを挿入します.

 
1999-05-22  Nathaniel Bowditch  <nat@apn.org>

        * rcs2log: Ignore log messages that start with `#'.

このあと, 変更記録の新しい項目を好きなように編集できます.

残念ながら, ChangeLogファイルには日付しか記録していないので, 新たな変更記録項目がChangeLogファイルの既存の項目と重複することがあります. そのような日付の重複は, 手作業で削除する必要があります.

通常, ファイル‘foo’に関する記録項目は, ‘* foo: text of log entry’のように表示されます. 記録項目のテキストが‘(functionname):’で始まると, ‘foo’のうしろの‘:’は省かれます. たとえば, ‘vc.el’に関する記録項目が ‘(vc-do-command): Check call-process status.’であれば, ‘ChangeLog’の中のテキストはつぎのようになります.

 
1999-05-06  Nathaniel Bowditch  <nat@apn.org>

        * vc.el (vc-do-command): Check call-process status.

C-x v aが複数の変更記録項目を一度に追加するときには, 同じ作者がほぼ同じ日時にチェックインしたものならば, 関連する記録項目をまとめます. そのようないくつかのファイルに対する記録項目がすべて同じテキストならば, 1つの項目にまとめます. たとえば, 最後にチェックインしたものに, 以下の記録があったとします.

• ‘vc.texinfo’の記録項目: ‘Fix expansion typos.’ • ‘vc.el’の記録項目: ‘Don't call expand-file-name.’ • ‘vc-hooks.el’の記録項目: ‘Don't call expand-file-name.

これらは‘ChangeLog’の中ではつぎのようになります.

 
1999-04-01  Nathaniel Bowditch  <nat@apn.org>

        * vc.texinfo: Fix expansion typos.

        * vc.el, vc-hooks.el: Don't call expand-file-name.

通常, C-x v aは記録項目を空行で区切りますが, 関連する記録項目のテキストを‘{clumpname} ’のような ラベルで始めれば, 関連する複数の記録項目を1つの塊にする (区切りの空行を入れない)ように印を付けられます. ラベル自体は‘ChangeLog’にはコピーされません. たとえば, 記録項目がつぎのようであるとします.

• ‘vc.texinfo’の記録項目: ‘{expand} Fix expansion typos.’ • ‘vc.el’の記録項目: ‘{expand} Don't call expand-file-name.’ • ‘vc-hooks.el’の記録項目: ‘{expand} Don't call expand-file-name.

すると, ‘ChangeLog’のテキストはつぎのようになります.

 
1999-04-01  Nathaniel Bowditch  <nat@apn.org>

        * vc.texinfo: Fix expansion typos.
        * vc.el, vc-hooks.el: Don't call expand-file-name.

記録項目のテキストが‘#’で始まると, その記録項目は‘ChangeLog’にはコピーされません. たとえば, コメントの綴りまちがいだけを変更したときには, 記録項目を‘#’で始めれば, このような自明なものを‘ChangeLog’に 入れないですみます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.8.2 VC作業ファイルとマスタファイルの改名

登録したファイルを改名するときには, そのマスタファイルも同様に改名して 正しい結果を得られるようにする必要があります. 指定どおりにソースファイルを改名し, それに従って マスタファイルも改名するには, vc-rename-fileを使います. このコマンドは, 当該ファイルを指名しているどんなスナップショット (see section スナップショット)も更新するので, スナップショットでも 新しい名前を使うようになります. それにも関わらず, 修正したスナップショットは動作しないかもしれません (see section スナップショットの弱点).

誰かがロックしているファイルに対しては, vc-rename-fileを使えません.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.8.3 版管理ヘッダの挿入

版を識別する文字列を作業ファイルへ直接入れておくと便利なこともあります. 版管理ヘッダと呼ばれる特別な文字列は, 各版ごとにその版番号で置き換えられます.

RCSを使っていて, かつ, 作業ファイルに版管理ヘッダが入っていれば, Emacsは, 版管理ヘッダを使って現在の版とファイルのロック状態を決定できます. これは, 版管理ヘッダがないときにマスタファイルを参照するより, 信頼できます. 複数の枝を使う環境では, VCが正しくふるまうためには版管理ヘッダが必要です (see section 複数ユーザーの枝).

版管理ヘッダの探索は, 変数vc-consult-headersで制御されます. nil以外ならば, 編集中の版番号を決定するためにEmacsはヘッダを探します. nilを設定すると, この機能はオフになります.

適切なヘッダ文字列を入れるには, コマンドC-x v hvc-insert-headers)を使います.

C-x v h

版管理システムで使うヘッダをファイルに挿入する.

デフォルトのヘッダ文字列は, RCSでは‘$Id$’, SCCSでは‘%W%’です. 変数vc-header-alistに設定すれば, 他のヘッダを指定できます. この値は, (program . string)の形式の 要素から成るリストです. ここで, programRCSまたはSCCSであり, stringは使用する文字列です.

1つの文字列のかわりに, 文字列のリストを指定することもできます. そうすると, リストの各文字列は, 別々の行に別のヘッダとして挿入されます.

この変数に入れる文字列を書くときには, 『余分な』バックスラッシュを 使う必要がよくあります. この文字列を含むEmacs Lispファイルが版管理の下に置かれているときに, 定数中の文字列がヘッダと解釈されることを防ぐためです.

各ヘッダは, ポイント位置の新しい行に, コメント区切りの内側にタブで囲んで挿入されます. 通常, 現在のモードのコメント開始文字列とコメント終了文字列を使いますが, 特定のモードでは, この目的のための特別なコメント区切りがあります. 変数vc-comment-alistがそれらを指定します. このリストの各要素は (mode starter ender)という形式です.

変数vc-static-header-alistは, バッファ名に基づいた追加の文字列を指定します. この値は, (regexp . format)の形式の 要素から成るリストでなくてはいけません. regexpがバッファ名に一致するたびに, formatをヘッダの一部として挿入します. バッファ名に一致する各要素とvc-header-alistに指定された各文字列ごとに ヘッダ行を挿入します. vc-header-alistの文字列を要素の書式formatで処理して ヘッダ行を作ります. vc-static-header-alistのデフォルト値はつぎのとおりです.

 
(("\\.c$" .
  "\n#ifndef lint\nstatic char vcid[] = \"\%s\";\n\
#endif /* lint */\n"))

これは, つぎのようなテキストを挿入します.

 
#ifndef lint
static char vcid[] = "string";
#endif /* lint */

上のテキストは空行で始まっていることに注意してください.

複数の版管理ヘッダをファイルに入れる場合には, ファイル内ではそれらを一緒にまとめて入れておきます. revert-bufferのマーカを保存する機構は, 2つの版管理ヘッダのあいだに置かれたマーカを扱えないこともあります.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.9 VCのカスタマイズ

VCをカスタマイズする方法はたくさんあります. 設定可能なオプションは, 次節に述べる4つに分類できます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.9.1 VCのバックエンドに対するオプション

RCSとCVSには, ファイルのロックを使うかどうかを指定できます (ロックに関してはsee section VCの概念). VCはどちらを選んだかを識別し, そのようにふるまいます.

RCSでは, デフォルトはロックを使います. しかし, ファイルをロックしていなくても変更をチェックインできる, 弱いロックと呼ばれるモードがあります. 特定のファイルに対して弱いロックを使うように切り替えるには, ‘rcs -U’を使います. 詳しくは, ‘rcs’のマニュアルページを参照してください.

CVSでは, デフォルトはロックを使いません. いつでも誰もが作業ファイルを変更できます. しかし, これを制限する方法があり, ロックに似たふるまいをします.

1つの方法は, 環境変数CVSREADに何か値を設定することです. この変数が定義されていると, CVSはデフォルトでは作業ファイルを読み出し専用にします. Emacs内では, C-x C-qと打ってファイルを書き込み可能にする必要があります. そうすると, 事実上ロックを使っているかのように編集できます. しかしながら, 実際にロックされているわけではないので, 複数のユーザーが各自のファイルを同時に書き込み可能にできてしまいます. CVSREADを初めて設定するときには, ファイルの保護が正しく設定されるように, あなたのモジュールすべてを新たにチェックアウトしたことを確認してください.

ロックに似たふるまいを達成する別の方法は, CVSの監視機能を使うことです. ファイルを監視するようにしておくと, CVSはデフォルトでそのファイルを読み出し専用にします. そのため, Emacs内ではC-x C-qを使って書き込み可能にする必要があります. VCは, cvs editを実行してファイルを書き込み可能にします. すると, CVSは, あなたがファイルを変更しようとしていることを 他の開発者に通知します. 監視機能の詳しい使い方については, CVSの解説を参照してください.

変数vc-handle-cvsnilを設定すれば, CVSの管理下に置いたファイルに対してVCを使わないようにできます. こうすると, Emacsは, これらのファイルを あたかも登録されていないかのように扱い, それらに対してVCコマンドは使えません. すべてのCVS操作を手動で行う必要があります.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.9.2 VC作業ファイルの扱い方

Emacsは, 版管理の下に置かれたソースファイルに対しては, 通常バックアップファイルを作りません. 版管理を使っているファイルに対してもバックアップファイルを作りたいなら, 変数vc-make-backup-filesnil以外の値を設定します.

ロックの状態に関わらず, 普通, 作業ファイルはつねに存在します. vc-keep-workfilesnilを設定すると, C-x C-qで新版をチェックインすると, 作業ファイルを削除します. しかし, Emacsでファイルを訪問しようとすると, 作業ファイルをふたたび作ります. (CVSでは, 作業ファイルはつねに存在する. )

版管理されているファイルをシンボリックリンクを介して編集することは, 危険なことになりえます. 版管理システムを迂回してしまいます. つまり, ロックせずにファイルを編集できてしまい, 変更のチェックインには失敗します. また, 他のユーザーがあなたの変更を上書きしてしまうかもしれません. こういったことを防ぐために, VCは, 訪問する各シンボリックリンクを検査して, それが版管理の下に置かれたファイルを指しているかどうか調べます.

変数vc-follow-symlinksは, シンボリックリンクが版管理されているファイルを指しているときに どうするかを制御します. その値がnilならば, VCは警告メッセージを表示するだけです. tならば, VCは自動的にリンクを辿って, かわりに本当のファイルを訪問し, エコー領域にこのことを表示します. 値がask(デフォルト)ならば, VCはリンクを辿るかどうかを毎回聞いてきます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.9.3 VC状態検索

ファイルのロック状態を推測するとき, VCはまずファイルのRCSの版管理ヘッダ文字列を探します (see section 版管理ヘッダの挿入). ヘッダ文字列がなかったり, SCCSを使っているときは, VCは通常, 作業ファイルのパーミッションを調べます. ここまでは, すぐにできます. しかし, ファイルのパーミッションを信頼できない場合もあります. この場合, やや手間がかかりますが, マスタファイルを調べる必要があります. さらに, マスタファイルは, ファイルがロックされているかどうかは 教えてくれますが, 作業ファイルがロックされた版を本当に含んでいるかどうかは教えてくれません.

ロック状態を調べるために版管理ヘッダを使わないようにVCに指示するには, 変数vc-consult-headersnilを設定します. すると, VCは(信頼できるなら)ファイルパーミッションを使うか, マスタファイルを調べます.

変数vc-mistrust-permissionsを設定することで, ファイルパーミッションを信頼するかどうかの基準を指定できます. その値は, t(つねにファイルパーミッションを疑い, マスタファイルを調べる), nil(つねにファイルパーミッションを信頼する), あるいは, 可否を決定する1引数の関数です. その引数は, サブディレクトリ, ‘RCS’, ‘CVS’, ‘SCCS’の いずれかの名前です. 関数の戻り値がnil以外ならば, ファイルパーミッションを疑います. 作業ファイルのパーミッションがまちがって変更されていると思うなら, vc-mistrust-permissionstを設定します. すると, VCはつねにファイルの状態を決定するためにマスタファイルを調べます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.7.9.4 VCコマンドの実行

vc-suppress-confirmnil以外ならば, C-x C-qC-x v iは確認せずにカレントバッファを保存し, C-x v uも確認せずに作用します. (この変数はC-x v cには影響しない. その操作は思い切ったものなので, つねに確認するべき. )

VCモードは, RCS, CVS, SCCSのシェルコマンドを実行することで, その作業の多くを行います. vc-command-messagesnil以外ならば, VCはどのシェルコマンドを実行しているか表示し, コマンドが終了したときに追加メッセージを表示します.

変数vc-pathを設定すれば, 版管理プログラムを探すための追加のディレクトリを指定できます. これらのディレクトリは, 通常の探索パスを探すまえに探されます. しかし, 通常は適切なファイルを自動的にみつけられます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.8 ファイルディレクトリ

ファイルシステムは, ファイル群をディレクトリにまとめます. ディレクトリ一覧は, ディレクトリの中にある, すべてのファイルの一覧表です. Emacsには, ディレクトリを作成したり削除したりするコマンド, 短形式(ファイル名のみ)や長形式(サイズ, 日付, 作者を含む)の ディレクトリ一覧を作成するコマンドがあります. diredと呼ばれるディレクトリブラウザもあります. See section ディレクトリエディタdired.

C-x C-d dir-or-pattern <RET>

短形式でディレクトリ一覧を表示する(list-directory).

C-u C-x C-d dir-or-pattern <RET>

長形式でディレクトリ一覧を表示する.

M-x make-directory <RET> dirname <RET>

dirnameという名前の新しいディレクトリを作る.

M-x delete-directory <RET> dirname <RET>

dirnameという名前のディレクトリを削除する. ディレクトリは空である必要があり, さもないとエラー.

ディレクトリ一覧を表示するコマンドは C-x C-dlist-directory)です. 表示するディレクトリや一覧に含めるファイルを指定するワイルドカードを含む パターンをミニバッファから読み取ります. たとえば,

 
C-x C-d /u2/emacs/etc <RET>

とすると, ディレクトリ‘/u2/emacs/etc’の中のすべてのファイルを表示します. ファイル名のパターンを指定した例はつぎのとおりです.

 
C-x C-d /u2/emacs/src/*.c <RET>

通常, C-x C-dはファイル名だけを含んだ短形式のディレクトリ一覧を 表示します. (値は無関係な)数引数を指定すると, (‘ls -l’のように)サイズ, 日付, 作者を含む長形式の一覧を作ります.

ディレクトリ一覧のテキストは, 下位プロセスでlsを実行して取得します. Emacsの2つの変数で, lsへ渡すオプションを制御します. list-directory-brief-switchesは, 短形式一覧のときに使う オプションを与える文字列です(デフォルトは"-CF"). list-directory-verbose-switchesは, 長形式一覧のときに使う オプションを与える文字列です(デフォルトは"-l").


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.9 ファイルの比較

コマンドM-x diffは, 2つのファイルを比較し, ‘*Diff*’という名前のEmacsバッファにその違いを表示します. このコマンドは, 値が文字列である変数diff-switchesで指定された オプションを使ってdiffプログラムを実行します.

バッファ‘*Diff*’のメジャーモードはコンパイル(compilation)モードです. ですから, C-x `を使って, 2つのソースファイルで変更されている箇所を次々に訪れることができます. 特定の変更箇所にポイントを移動してから, <RET>やC-c C-cを打つか, そこでMouse-2をクリックすると, そこに対応するソースの場所へ移動できます. コンパイル(compilation)モードの他の特別なコマンドを使うこともできます. <SPC>と<DEL>でスクロール, M-pM-nでカーソル移動できます. See section Emacs下でのコンパイラの実行.

コマンドM-x diff-backupは, 指定されたファイルとその最新のバックアップとを比較します. バックアップファイルの名前を指定すると, diff-backupはそのもとのファイルとバックアップファイルとを比較します.

コマンドM-x compare-windowsは, カレントウィンドウの中のテキストと, つぎのウィンドウの中のテキストを比較します. それぞれのウィンドウのポイント位置から比較を始めます. それぞれの開始位置は, 各バッファのマークリングに積まれます. そして, 各ウィンドウでそれぞれのポイントを1文字ずつ進めることを, 両者のウィンドウで一致しないものに出会うまで行います. そして, コマンドは終了します. Emacsのウィンドウについてより詳しくは, See section 複数のウィンドウ.

数引数を指定すると, compare-windowsは 白文字の違いを無視します. 変数compare-ignore-casenil以外ならば, 大文字小文字の違いも同様に無視します.

2つの似たファイルの併合に便利な機能に関しては, See section emergeを用いたファイルの併合.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.10 その他のファイル操作

Emacsには, ファイルをさまざまに操作するコマンドがあります. それらすべては1つのファイルを操作します. これらのコマンドは, ワイルドカードを含むファイル名を受け付けません.

M-x view-fileでは, ファイルを1画面分ずつ順番に眺めることができます. このコマンドは, ミニバッファでファイル名を読み取ります. Emacsバッファにファイルを読み込んだあと, view-fileは先頭を表示します. そうしたら, 1ウィンドウ分先へスクロールするには<SPC>, 逆向きにスクロールするには<DEL>を打ちます. ファイル内を動き廻るための他のいろいろなコマンドもありますが, 変更するためのコマンドはありません. コマンド一覧を見るには, このモードで?と打ちます. コマンド群は, Emacsの普通のカーソル移動コマンドとほとんど同じです. ファイル閲覧を終了するには, qを打ちます. 閲覧用のコマンドは, 閲覧(view)モードと呼ばれる 特別なメジャーモードで定義されています.

関連したコマンド, M-x view-bufferは, Emacsの既存のバッファを閲覧します. See section その他のバッファ操作.

M-x insert-fileは, 指定したファイルの内容を カレントバッファのポイント位置に挿入します. ポイントの位置はそのままですが, 挿入された部分の直後にマークを設定します.

M-x write-regionは, M-x insert-fileの逆です. 指定したファイルにリージョンの内容をコピーします. M-x append-to-fileは, 指定したファイルの末尾にリージョンのテキストを付け加えます. See section テキストの蓄積.

M-x delete-fileは, シェルのrmコマンドのように, 指定したファイルを削除します. 1つのディレクトリ内のたくさんのファイルを削除するのなら, diredを使うほうが便利です(see section ディレクトリエディタdired).

M-x rename-fileは, ミニバッファで2つのファイル名, oldnewを読み取り, ファイルoldnewに改名します. newという名前のファイルが既存のときには, 確認にyesで応答する必要があります. そうしないと, 改名しません. これは, 改名により名前newの古い意味が失われるからです. oldnewが異なるファイルシステムの上にあるときには, ファイルoldを(newに)コピーしてから削除します.

似たコマンドM-x add-name-to-fileは, 既存ファイルの名前を消さずに別の名前を追加するために使います. 新しい名前は, 既存ファイルが置かれている同じファイルシステムに 属している必要があります.

M-x copy-fileは, ファイルoldを読んで, 新しいファイルnewに同じ内容を書き出します. newという名前のファイルが既存なら, 確認を求めてきます. というのは, コピーするとファイルnewの古い内容を上書きしてしまうからです.

M-x make-symbolic-linkは, 2つのファイル名, targetlinknameを読み取って, targetを指すlinknameという名前のシンボリックリンクを作ります. この結果, 将来linknameをオープンしようとすると, その時点でtargetという名前のファイルを参照します. その時点で名前targetが使われていなければ, エラーになります. このコマンドは引数targetを展開しないので, リンク先に相対名を書くことができます.

linknameが使われていると, リンクを作るときに確認を求めます. すべてのシステムでシンボリックリンクを使えるわけではないことに 注意してください.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.11 圧縮されたファイルの参照

Emacsには, 圧縮されたファイルを訪問すると自動的に展開し, それを変更して保存すると自動的に再度圧縮するライブラリがあります. この機能を利用するには, コマンドM-x auto-compression-modeを打ちます.

(自動展開を含む)自動圧縮がオンのときには, Emacsはファイル名で圧縮されたファイルを認識します. ファイル名の語尾が‘.gz’のものは, gzipで圧縮されたファイルであることを表します. 他の語尾の場合には, 他の圧縮プログラムであることを表します.

自動展開と自動圧縮は, Emacsがファイルの内容を使うすべての操作に適用されます. ファイルを訪問する, ファイルに保存する, ファイルの内容をバッファに挿入する, ファイルをロードする, ファイルをバイトコンパイルすることを含みます.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.12 リモートファイル

特別なファイル名の構文を使って, 他のマシン上のファイルを参照できます.

 
/host:filename
/user@host:filename

このようにすると, Emacsは, 指定したホスト上のファイルを読み書きするためにFTPプログラムを使います. あなたのユーザー名かuserを使ってFTPでログインします. 毎回パスワードを聞かれることもありますが, これはhostへのログインに使われます.

普通, リモートファイル名にユーザー名を指定しないと, あなたのユーザー名を使うことを意味します. しかし, 変数ange-ftp-default-userに文字列を設定しておけば, その文字列をかわりに使います. (FTPによるファイル参照を実装するEmacsのパッケージは, ange-ftpと呼ばれる. )

変数file-name-handler-alistnilを設定すると, FTPファイル名機能を完全にオフにできます (16).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

12.13 クォートしたファイル名

特殊文字や特別な構文の特別な効果を抑えるために, 絶対ファイル名をクォートできます. そうするには, 先頭に‘/:’を加えます.

たとえば, リモートにあるように見えるローカルなファイル名をクォートして, リモートファイル名として扱われるのを防ぎます. したがって, ディレクトリが‘/foo:’という名前であり, その中に‘bar’という名前のファイルがあるとき, Emacsでは, そのファイルを‘/:/foo:/bar’で参照できます.

/:’は, ‘~’をユーザーのホームディレクトリを表す 特殊文字として扱わないようにもします. たとえば, ‘/:/tmp/~hack’は, ディレクトリ‘/tmp’の中にある‘~hack’というファイル名を指します.

同様に, ‘/:’は‘$’を含むファイル名を ミニバッファで入力する方法の1つです. しかし, ‘$’をクォートするには, ‘/:’は(ミニ)バッファの先頭に置く必要があります.

ワイルドカード文字を‘/:’でクォートすることもできます. たとえば, ‘/:/tmp/foo*bar’でファイル‘/tmp/foo*bar’を訪問します. しかしながら, 多くの場合, 単にワイルドカード文字そのものを入力できます. たとえば, ‘/tmp’にある‘foo’で始まり‘bar’で終る名前の ファイルが‘foo*bar’であるときには, ‘/tmp/foo*bar’と指定すると, 単に‘/tmp/foo*bar’を訪問します.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by 新堂 安孝 on September 22, 2009 using texi2html 1.82.