基本的な作業サイクル

Subversionはたくさんの機能、オプション、おまけが付いていますが、 日々の作業では、おそらくその中のいくつかを使うだけでしょう。 この章では一番よく起こることを説明します。

典型的な作業サイクルは次のようなものです:

作業コピーの更新

チームを作って作業してるプロジェクトでは、自分の作業コピーを 更新してプロジェクトの他のメンバーが自分の 更新処理後に加えた変更点をすべて受け取りたくなるでしょう。 svn updateを使って自分の作業コピーを リポジトリの最新バージョンにあわせてください。

$ svn update
U  foo.c
U  bar.c
Updated to revision 2.

この場合、あなたが最後に更新してから、誰か別の人が foo.cbar.c の両方に加えた変更をコミットし、Subversionはこの変更をあなたの 作業コピーに加えるために更新しました。

svn update の出力をもう少し詳しく見てみましょう。 サーバが変更点を作業コピーに送るとき、文字コードがそれぞれのファイル の横に表示されて、あなたの作業コピーを最新にするために、どのような 動作を起こしたかを知らせます:

U foo

ファイル foo は 更新(Updated) されました(サーバから 変更を受け取りました)。

A foo

ファイルかディレクトリである foo は あなたの作業コピーに追加(Added) されました。

D foo

ファイルかディレクトリである foo は あなたの作業コピーから削除(Deleted) されました。

R foo

ファイルかディレクトリである foo は あなたの作業コピー中で置き換え(Replaced) られました。つまり foo は削除されて、同じ名前の 新しいファイルまたはディレクトリが追加されました。両方は同じ名前ですが、 リポジトリはそれらを別の履歴を持った別のものであるとみなします。

G foo

ファイル foo は新しい変更点を リポジトリから受け取りましたが、そのファイルのローカルコピーにも 修正が加えられていました。しかし両方の修正は重なっていないか、あるいは 変更の内容が自分自身のものとまったく同じであったため、Subversion はリポジトリの変更を、問題を起こすことなしにマージ (merGed)しました。

C foo

ファイル foo は、サーバから 衝突(Conflicting)のある変更を 受け取りました。サーバからの変更は、あなた自身の変更と直接重なっています。 でも心配はいりません。この衝突は人間(つまりあなた)が解消しなくては なりません。この章の後でこの状況について議論します。

作業コピーに変更を加えること

さて、これで自分の作業コピーに変更を加えることができます。 以下のような、比較的特殊な変更をすることもできます。新しい機能 を書いたり、バグをフィックスしたり、などです。このような場合に 使うSubversionコマンドは、 svn add, svn delete, svn copy, svn moveなどです。しかし、既にSubversion 管理下にあるファイルを単に編集するだけなら、コミットするまでに そのようなコマンドを使う必要はありません:

ファイルの変更

これは一番単純なタイプの変更です。ファイルを変更することについて Subversionに報告する必要はありません。どのファイルが変更された についてはSubversion自身が自動的に検出することができます。

ツリーの変更

Subversionに対して、削除、追加、コピー、移動の予告として ファイルやディレクトリを「マーク」するように 依頼することができます。このような変更は作業コピー上では直ちに 起こりますが、次にあなたがコミットするまでリポジトリ上では 追加削除は一切起きません。

ファイルを変更するには、テキストエディタ、ワードプロセッサ、 グラフィックプログラム、その他の通常利用しているツールなら なんでも使うことができます。Subversionはバイナリファイルを テキストファイルを扱うのと同じくらい簡単に扱うことができます— し、十分効率的にあつかえます。

ここでは、Subversionでツリーの変更として一番よく利用される 四つのサブコマンドを概観しておきます (あとで、svn importsvn mkdir も見ていきます)。

警告

どんなツールを使ってファイルを編集する場合でも、その内容 を Subversion に伝えずに作業コピーの構成を変えるべきではあり ません。作業コピーの構成を変えるときには svn copy, svn delete, svn move コマンドを使い、新たにファイルやディレクトリ をバージョン管理下におく場合にはsvn addコ マンドを使うようにしてください。

svn add foo

通常ファイル、ディレクトリ、シンボリックリンクのどれかである foo をリポジトリに追加する予告をします。 次のコミットでfoo は正式に親ディレクトリの 子供になります。fooがディレクトリの場合は fooにあるすべてのファイルは追加予告の対象に なります。fooだけを追加予告したい場合は --non-recursive (-N) スイッチを指定してください。

svn delete foo

通常ファイル、ディレクトリ、シンボリックリンクのどれかである foo をリポジトリから削除する予告をします。 foo が通常ファイルまたはシンボリックリンクの場合は作業コピーから直ちに 削除されます。ディレクトリの場合は削除されませんが、Subversion はそれを削除予告の状態に設定します。変更をコミットすると foo は作業コピーとリポジトリから削除されます。 [3]

svn copy foo bar

新しいアイテムbarfoo の複製として作ります。barは自動的に 追加予告されます。barが次のコミットでリポジトリ に追加される時点で、コピーの履歴が記録されます(それが fooのコピーである、という履歴)。 svn copyは中間ディレクトリを作成しません。

svn move foo bar

このコマンドはsvn copy foo bar; svn delete foo を実行することとまったく同じです。つまり、 barfooのコピーとして 追加予告され、foo は削除予告されます。 svn moveは中間ディレクトリを作成しません。

自分の変更点の調査

変更が完了したら、リポジトリにコミットする必要がありますが、普通 そうする前に、正確には自分が何を変更したのかを見ておくのは良い考え です。コミットの前に変更点を確認することで、より正確なログメッセージ を付けることができます。また、不十分な修正をしただけであることを 発見するかも知れませんし、コミットする前にその変更を破棄したりする 機会にもなります。さらに、公開する前に変更点を再検討したり詳しく調査 する機会にもなります。 svn status, svn diff, svn revert を使って正確にはどんな変更をしたかを 見ることができます。最初の二つのコマンドで、作業コピー中のどのファイル を変更したかを調べ、三番目のコマンドでそのうちのいくつか(あるいは全部) の変更を取り消すかも知れません。

Subversionはこの作業をやるために効率よく作られていて、多くの操作に ついてはリポジトリと通信することなしに実行できます。特に、 作業コピーには、.svn という隠れたディレクトリが あり、ここに作業コピーの「元なるリビジョン」 のコピーが あります。これをうまく使って Subversionは、あなたの作業ファイルのどれが 変更されたかをすばやく知ることができますし、リポジトリと通信すること なしに、変更を取り消すことすらできます。

svn status

多分、どのSubversionコマンドよりもsvn status コマンドはよく利用されるはずです。

自分の作業コピー最上位階層で引数なしにsvn status を実行すると、自分がツリーにしたすべての修正が検出できます。 以下の例はsvn status が返すことのできる 異なる状態コードです。 (以下で、# の後に書いてあるテキストは svn statusからのものではないのに注意してください。)

  L     some_dir            # svn left a lock in the .svn area of some_dir
M       bar.c               # the content in bar.c has local modifications
 M      baz.c               # baz.c has property but no content modifications
X       3rd_party           # dir is part of an externals definition
?       foo.o               # svn doesn't manage foo.o
!       some_dir            # svn manages this, but it's missing or incomplete
‾       qux                 # versioned as file/dir/link, but type has changed
I       .screenrc           # svn doesn't manage this, and is set to ignore it
A  +    moved_dir           # added with history of where it came from
M  +    moved_dir/README    # added with history and has local modifications
D       stuff/fish.c        # file is scheduled for deletion
A       stuff/loot/bloo.h   # file is scheduled for addition
C       stuff/loot/lump.c   # file has textual conflicts from an update
 C      stuff/loot/glub.c   # file has property conflicts from an update
R       xyz.c               # file is scheduled for replacement
    S   stuff/squawk        # file or dir has been switched to a branch
     K  dog.jpg             # file is locked locally; lock-token present 
     O  cat.jpg             # file is locked in the repository by other user
     B  bird.jpg            # file is locked locally, but lock has been broken
     T  fish.jpg            # file is locked locally, but lock has been stolen

この出力形式の中で、svn statusは 五つの文字を表示していて、その後にいくつかの空白が続き、 ファイルまたはディレクトリ名称がそのあとに続いています。 最初のコラム (左から一文字目の部分) は、ファイルまたはディレクトリの 状態をあらわしています。ここで表示されているコードは:

A item

通常ファイル、ディレクトリ、シンボリックリンクのいずれかである item はリポジトリに追加予告されています。

C item

ファイルitem は衝突の状態にあります。つまり、自分の作業コピーにあるローカルな変更が 更新時にサーバから受け取った変更部分と重なっています。リポジトリに 自分の変更点をコミットする前にこの衝突を解決しなくてはなりません。

D item

通常ファイル、ディレクトリ、シンボリックリンクのいずれかである item は リポジトリからの削除予告をされています。

M item

ファイルitemの内容は 修正されています。

R item

ファイル、ディレクトリ、シンボリックリンクのいずれか であるitem はリポジトリ中の item を置き換えるように準備されています。 これはまずそのオブジェクトがいったん削除され、次に同じ名前の 別のオブジェクトが追加されます。そしてそれは単一のリビジョンで ひとまとまりに実行されます。

X item

ディレクトリ item はバージョン化 されていませんがSubversionの外部定義に関連付けられています。外部定義についての 詳細は外部定義項を見てください。

? item

通常ファイル、ディレクトリ、シンボリックリンクのいずれかである item は バージョン管理下にはありません。--quiet (-q) スイッチをsvn status に渡すか、親ディレクトリにsvn:ignore 属性を 設定することで疑問符の表示を抑制できます。 無視できるファイルについての詳細は svn:ignoreを見てください。

! item

通常ファイル、ディレクトリ、シンボリックリンクのいずれかである item は バージョン管理下にありますが、それは失われているか、何か不完全な 状態にあります。Subversion以外のコマンドを使って削除された場合 には、そのアイテムは失われてしまいます。ディレクトリの場合、 チェックアウトか、更新が中断された場合、不完全な状態になることが あります。svn updateを使えばすぐにリポジトリから ファイルまたはディレクトリをもう一度取り出すことができます。 svn revert fileを使えば、失われたファイルを 復元することができます。

‾ item

通常ファイル、ディレクトリ、シンボリックリンクのいずれかである item は あるタイプのオブジェクトとして存在しますが、作業コピーには別の タイプのオブジェクトとして存在しています。 たとえばSubversionはリポジトリ中にファイルを持っているが、 svn deletesvn addを 使わずに、作業コピー中の対応するファイルを削除し、同じ名前の ディレクトリを作ったような場合です。

I item

ファイル、ディレクトリ、シンボリックリンクのいずれかである item はバージョン管理下にはなく、Subversion は svn add, svn import svn status の実行時にはこれを 無視します。無視されるファイルについてのより詳しい情報は svn:ignore を見てください。 このシンボルは svn status--no-ignore オプションを渡したときにだけ表示されることに注意してください。 —そうでなければファイルは無視され、まったく表示されません!

二番目のコラムはファイルまたはディレクトリの属性を示しています (詳しくは属性項 参照してください)。 もしM が表示されていれば 属性は修正されたことを示しています。そうでなければ空白が 表示されます。

三番目のコラムは空白か、L が 表示され、後者の場合は Subversionがそのディレクトリの .svn 作業領域をロックしていることを意味して います。svn commit が実行されている途中で svn status を実行すると L が表示されます— 多分ログメッセージを変更している最中かも知れません。 Subversionが実行されていないのなら、Subversionは多分中断され たため、ロックは、svn cleanupの実行によって 解除しなくてはなりません。(これについてはこの章の後で触れます)

四番目のコラムは空白か+ が 表示され、あとの場合はファイルまたはディレクトリは 追加または修正され、それが履歴に追加予告されていることを意味します。 これはファイルやディレクトリに対してsvn movesvn copy をしたときによく起こります。 A  +の表示がある場合 そのアイテムは履歴付きの追加予告されていることを意味します。 それはファイルか、コピーされたディレクトリのルートであるかです。 +はそのアイテムが、履歴に追加 予告されたサブツリーの一部であることを意味します。つまり、 そのアイテムのどれかの親がコピーされ、コミットを待っています。 M  + はアイテムが履歴 に追加予告されたサブツリーの一部であり、 かつ ローカルの修正も受けているという場合です。 コミットするとき、最初に親が履歴付き追加されます(コピーされます) その意味はこのファイルはコピーによって自動的に存在するということ です。次いでローカルの修正はコピーにアップロードされます。

五番目のコラムは空白か、Sに なります。これはファイルかディレクトリは作業コピーの残り パスから、ブランチに(svn switchコマンドで) 切り替わっていることを意味します。

六番目のコラムはロックに関する情報を示しています。 詳細は ロック項で説明します。

svn statusにパスを指定すると、そのアイテムに 関する情報のみを表示します:

$ svn status stuff/fish.c
D      stuff/fish.c

svn status--verbose (-v) スイッチを とりますが、その場合作業コピー中のすべてのアイテム に対して、たとえ変更がなくてもステータスを表示するという意味になります:

$ svn status --verbose
M               44        23    sally     README
                44        30    sally     INSTALL
M               44        20    harry     bar.c
                44        18    ira       stuff
                44        35    harry     stuff/trout.c
D               44        19    ira       stuff/fish.c
                44        21    sally     stuff/things
A                0         ?     ?        stuff/things/bloo.h
                44        36    harry     stuff/things/gloo.c

これは svn statusの「長い表示形式」 の出力です。再処理コラムは同じですが、二番目はアイテムの作業リビジョン になります。三番目と四番目はそれぞれアイテムが最後に変更されたリビジョン と、誰がそれをしたかの表示です。

いままで出てきたsvn status の実行は いずれもリポジトリと通信をしません。それは単に作業コピー中の .svn ディレクトリのメタデータを比較する ことによって、ローカルマシン上だけで動作します。 最後に、--show-updates(-u) スイッチがありますが、これはリポジトリと通信して、古くなった ファイルなどの情報を追加表示します:

$ svn status --show-updates --verbose
M      *        44        23    sally     README
M               44        20    harry     bar.c
       *        44        35    harry     stuff/trout.c
D               44        19    ira       stuff/fish.c
A                0         ?     ?        stuff/things/bloo.h
Status against revision:   46

二つのアスタリスク ('*') に注意してください:この状態で svn update を実行すると READMEtrout.c の変更点を受け取ることになります。 これは非常に役に立つ情報です—コミットする前には更新して README に関するサーバ上の変更点を取得 しなくてはなりません。さもなければ、最新でないという理由で コミットは失敗するでしょう(詳しくは後で述べます)。

svn diff

自分の変更点を調べる別の方法は、svn diff コマンドを使うことです。svn diff を引数 なしに実行することで、自分がどんな変更をしたかを 正確に 知ることができます。このときの 出力形式はunified diff 形式です: [4]

$ svn diff
Index: bar.c
===================================================================
--- bar.c       (revision 3)
+++ bar.c	(working copy)
@@ -1,7 +1,12 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <stdio.h>

 int main(void) {
-  printf("Sixty-four slices of American Cheese...¥n");
+  printf("Sixty-five slices of American Cheese...¥n");
 return 0;
 }

Index: README
===================================================================
--- README      (revision 3)
+++ README	(working copy)
@@ -193,3 +193,4 @@ 
+Note to self:  pick up laundry.

Index: stuff/fish.c
===================================================================
--- stuff/fish.c     (revision 1)
+++ stuff/fish.c     (working copy)
-Welcome to the file known as 'fish'.
-Information on fish will be here soon.

Index: stuff/things/bloo.h
===================================================================
--- stuff/things/bloo.h      (revision 8)
+++ stuff/things/bloo.h      (working copy)
+Here is a new file to describe
+things about bloo.

svn diff コマンドは.svn 領域 にある、「修正元リビジョン」 のコピーに対して作業コピー 中のファイルを比較した結果を出力します。 追加予告ファイルはすべて追加されたテキストとして表示され 削除予告されているファイルはすべて削除されたファイルとして表示 されます。

出力は、unified diff 形式で表示されます。 つまり、削除された行は先頭に - が付き、追加された 行は先頭に +がつきます。svn diff はさらにpatch に便利なようにファイル名称とオフセット 情報を表示します。このためdiffの出力をファイルにリダイレクトすることで 「パッチ」 を生成することができます:

$ svn diff > patchfile

たとえば、パッチファイルを別の開発者に送り、コミット前に再検討や テストをすることができます。

svn revert

上のdiff出力を見て、README に対する修正が間違っていることがわかったとしましょう: 多分 エディタで間違ったファイルに保存してしまったりしたのでしょう。

これは、svn revertを使うことの できるとても良い機会です。

$ svn revert README
Reverted 'README'

Subversion はそのファイルを.svn 領域に ある「修正元リビジョン」のコピーを上書きすることに よって、修正以前の状態に戻します。 しかし、svn revertどのような 予告操作も取り消すことができるのに注意してください—たとえば 最終的に新しいファイルを追加することをやめることができます:

$ svn status foo
?      foo

$ svn add foo
A         foo

$ svn revert foo
Reverted 'foo'

$ svn status foo
?      foo

注意

svn revert ITEM は、作業コピーから ITEMを削除し、それからsvn update -r BASE ITEMを実行したのとまったく同じ効果があります。 しかし、もしファイルをもとに戻そうとしているのなら、 svn revertには一つ重要な違いがあります—それはファイル を元に戻すにあたってリポジトリと通信する必要がないのです。

あるいは間違ってバージョン管理からファイルを消して しまったのかも知れません:

$ svn status README 
       README

$ svn delete README 
D         README

$ svn revert README
Reverted 'README'

$ svn status README
       README

衝突の解消(他の人の変更点のマージ)

いままでで、svn status -uがどうやって衝突を 予告できたかを知っています。svn update を実行して、面白いことが起こったとします:

$ svn update
U  INSTALL
G  README
C  bar.c
Updated to revision 46.

UG のコードは考える ことはありません。この二つはリポジトリからの変更を きれいに吸収することができました。 U でマークされたファイルは ローカルでは何の変更もありませんでしたが、リポジトリからの 修正分で更新(Updated)されました。 Gはマージ( merGed)されたことを意味して いますが、これは、ファイルはローカルで変更されていたが、 リポジトリからの変更部分とまったく重ならなかったことを意味 しています。

しかし C は衝突を あらわしています。これはサーバからの変更場所があなた自身の ものと重なっていることを意味していて、あなたは手で どちらかを選択しなくてはなりません。

衝突が起こると、普通はその衝突を知らせて解決することができるように 三つのことが起こります:

  • そのファイルがマージ可能なタイプのときには Subversion は更新処理中にC を 表示して、そのファイルが「衝突している」ことを知らせます。 (行番号に基づいた文脈マージ可能なファイルかどうかは svn:mime-type属性によって決まります。 詳しくはsvn:mime-typeを見てください。)

  • Subversion は衝突マーカ —衝突を 起こした「両方」の内容を区切る特別なテキスト文字列 のことです—を重なっている場所に置き、衝突内容を見てわかるように します。

  • 衝突しているファイルのそれぞれについて、Subversionは最大で三つの バージョン管理対象にはならない特殊なファイルを作業コピーに置きます:

    filename.mine

    これは作業コピーを更新する前に作業コピー中にあったファイル です—つまり、衝突マーカを含んでいません。このファイルは 自分のやった最後の変更が含まれているだけのものです。(Subversion がこのファイルがマージ可能なものではないとみなした場合には .mineファイルは作成されませんが、それは 作業ファイルと同一の内容になってしまうだろうからです。)

    filename.rOLDREV

    これは、作業コピーを更新する前のBASEリビジョンにあったファイル の内容です。つまり、そのファイルは最後にした編集の直前にした チェックアウト時点でのファイルです。

    filename.rNEWREV

    これは Subversionクライアントプログラムが作業コピーを更新したときに サーバから受け取ったファイルです。これは、リポジトリのHEAD リビジョンに対応しています。

    ここで OLDREV.svn ディレクトリにあるファイルのリビジョン番号で、NEWREVHEAD リポジトリのリビジョン番号です。

たとえば Sally がリポジトリにあるsandwich.txt に変更を加えるとします。たった今、Harryは自分の作業コピーのそのファイルを変更 してコミットしました。Sally は自分が加えた変更をコミットする前に 作業コピーを更新しますが、そのとき衝突の報告を受けます:

$ svn update
C  sandwich.txt
Updated to revision 2.
$ ls -1
sandwich.txt                       
sandwich.txt.mine
sandwich.txt.r1
sandwich.txt.r2

このときSubversionは三つの一時ファイルが削除されるまで sandwich.txtのコミットを許可 しません

$ svn commit --message "Add a few more things"
svn: commit failed (details follow):
svn: Aborting commit: '/home/sally/svn-work/sandwich.txt' remains in conflict

もし衝突があった場合は、三つのうちのどれかを する必要があります:

  • 手で」 衝突テキストをマージします。( ファイル中の衝突マーカを調べ編集することによって)。

  • 作業ファイルに、一時ファイルのどれかを上書きします。

  • svn revert <filename>を 実行して、ローカルでしたすべての変更を捨てます。

ひとたび衝突を解消したら、svn resolvedを実行 してSubversionにそのことを伝えます。これは三つの一時ファイルを 削除して、Subversionはもうそのファイルが衝突の状態にあるとは 考えなくなります。 [5]

$ svn resolved sandwich.txt
Resolved conflicted state of 'sandwich.txt'

衝突を手でマージすること

手で衝突をマージするのは最初とても嫌なものですが、 少し練習すればバイクから降りるのと同じくらい簡単に できるようになります。

例をあげます。コミュニケーション不足により、あなたとあなたの同僚 である Sally の両方がsandwich.txtというファイルを同時に 編集したとします。Sallyは自分の変更をコミットし、それからあなた が作業コピーを更新しようとすると、衝突を受け取ります。それで sandwich.txt を編集しなくてはなりません。 最初にファイルを見てみます:

$ cat sandwich.txt
Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
<<<<<<< .mine
Salami
Mortadella
Prosciutto
=======
Sauerkraut
Grilled Chicken
>>>>>>> .r2
Creole Mustard
Bottom piece of bread

小なり記号の文字列、イコールサイン、そして 大なり記号の文字列を衝突マーカと呼びますが、これは実際の 衝突を起こしたデータの一部ではありません。一般的には次のコミットの 前に取り除く必要があります。最初の二つのマーカの間のテキストは衝突領域に あなた自身がした変更です:

<<<<<<< .mine
Salami
Mortadella
Prosciutto
=======

二番目と三番目の衝突マーカの間のテキストは、 Sallyのコミットからのテキストです:

=======
Sauerkraut
Grilled Chicken
>>>>>>> .r2

通常、衝突マーカとSally の変更部分を単に削除するわけには いきません—そのようなことをするとSallyはsandwichを 受け取ったときにびっくりしますし、それは彼女が望んでいる ものではないでしょう。あなたは電話をかけるか、オフィスを またいで、Sallyに、二人の変更が衝突していることを説明 します。 [6] ひとたびコミットする変更内容について合意がとれたら、 ファイルを編集し衝突マーカを削除します。

Top piece of bread
Mayonnaise
Lettuce
Tomato
Provolone
Salami
Mortadella
Prosciutto
Creole Mustard
Bottom piece of bread

これで、svn resolved を実行し 自分の変更をコミットする用意ができました:

$ svn resolved sandwich.txt
$ svn commit -m "Go ahead and use my sandwich, discarding Sally's edits."

衝突ファイルを編集中に混乱したら、Subversionがあなたのために作った、 作業コピーにある三つの一時ファイルを見てどうするかを考えることができます —その中には更新前にあなたが修正したバージョンのファイルもありま す。この三つのファイルを確認するためにサードパーティー製の対話的な マージツールを使うこともできます。

作業ファイルの上にファイルをコピーすること

衝突が起こり、自分のした変更を捨てようとするときにはSubversionが作った 一時ファイルのどれかを単に作業コピー上に上書きすることができます:

$ svn update
C  sandwich.txt
Updated to revision 2.
$ ls sandwich.*
sandwich.txt  sandwich.txt.mine  sandwich.txt.r2  sandwich.txt.r1
$ cp sandwich.txt.r2 sandwich.txt
$ svn resolved sandwich.txt

Punting: svn revertの利用

衝突が起こり、調査の結果、自分の変更を捨てて編集をやり直す場合は 単に変更を revert することができます:

$ svn revert sandwich.txt
Reverted 'sandwich.txt'
$ ls sandwich.*
sandwich.txt

衝突ファイルを元に戻すときはsvn resolvedを 実行する必要はないことに注意してください。

これで自分の変更をコミットする用意ができました。 svn resolvedはこの章であつかう ほかのほとんどのコマンドとは違って、引数を必要とします。 どのような場合でも十分注意して、ファイル中の衝突を 解消したことが確かな場合だけsvn resolved を実行してください—一時ファイルが削除されてしまうと、 Subversion はファイルが衝突マーカを含んでいたとしてもコミット します。

変更点のコミット

やっとここまできました。編集は終了し、サーバからの変更を すべてマージしました。これで自分の変更をリポジトリにコミット する準備ができました。

svn commit コマンドは自分の変更点の すべてをリポジトリに送ります。変更をコミットするときには 変更点を説明するログメッセージを 与えてやる必要があります。ログメッセージは自分が作った 新しいリビジョンに付けられます。ログメッセージが簡単な 場合は--message (あるいは-m) オプションを使ってコマンドライン上で指定することができます:

$ svn commit --message "Corrected number of cheese slices."
Sending        sandwich.txt
Transmitting file data .
Committed revision 3.

しかし、既にログメッセージを作ってある場合は、 --file スイッチでファイル名称を指定することで、Subversionに そのファイルの内容を使うように指示できます:

$ svn commit --file logmsg 
Sending        sandwich.txt
Transmitting file data .
Comitted revision 4.

--message--file も 指定しなかった場合は、Subversionは自動的にエディタを 起動し、(config項editor-cmdセクションを見てください) ログメッセージを作成しようとします。

ティップ

もしコミットメッセージをエディタを起動して書いて いて、そのコミットを中止したいと思った場合には、単に保存せずに そのエディタを抜けてください。既にコミットメッセージを保存して しまった場合であれば、テキストを削除してもう一度保存してください。

$ svn commit
Waiting for Emacs...Done

Log message unchanged or not specified
a)bort, c)ontinue, e)dit
a
$

リポジトリは、変更点の内容に意味があるかどうかはまったく 気にしません。Subversionはあなたが見ていないところで、同じファイルに 他の人が修正していないことだけを確認します。もし他の人がそのような 変更を していたら 、コミットはあなたの変更 したファイルのどれかが最新ではないというメッセージを出して失敗します:

$ svn commit --message "Add another rule"
Sending        rules.txt
svn: commit failed (details follow):
svn: Out of date: 'rules.txt' in transaction 'g'

このような場合は、svn updateを実行し その結果のマージや衝突を解消し、もう一度コミットしてください。

これでSubversionを使う基本的な作業サイクルを説明しました。 Subversionにはこのほかにもたくさんのリポジトリや作業コピーを管理するための 機能がありますが、この章でいままで説明してきたコマンドだけを使っても、 非常に多くのことができます。



[3] もちろんリポジトリから完全に削除されてしまうわけではありません— 単に、リポジトリのHEADから削除されるだけです。削除したリビジョンより 前のリビジョンを指定してチェックアウトすれば(あるいは作業コピーを 更新すれば)削除前の状態に戻ることができます。

[4] Subversion は内部 diff エンジンを利用し、デフォルトでは unified diff 形式を生成します。もし別の形式の diff 出力がほしい場合には、 --diff-cmdで外部diffプログラムを指定し、 --extensionsスイッチを使ってフラグを渡して ください。たとえばファイルfoo.cのローカルな 変更点を context 出力形式で見たいが、空白の変更は無視したい場合、 svn diff --diff-cmd /usr/bin/diff --extensions '-bc' foo.c のように実行することができます。

[5] 一時的なファイルは常に自分で削除することができます が、Subversionがせっかくコマンドを用意しているのに本当にそうしたい のでしょうか? そうは思えませんが。

[6] そして、あなたが頼めば、彼らは電車で町の外まであなたを つれていってくれるかも知れませんよ。