CVS/Subversionを使ったバージョン管理(後編:SVNを使ったバージョン管理) 4ページ
競合の解消
もし自分がコミットしたファイルがすでに他人によって変更され、かつ先にコミットされていた場合、コミット時にメッセージが表示され、コミットに失敗する。この場合、まずアップデートを実行して他人による変更点を取り込み、競合を解消させた上で再度コミットを行う必要がある。
下記は、コミット時に競合が明らかになり、コミットに失敗した例だ。この例では、「echo.pl」というファイルに競合が発生し、そのためにコミットに失敗した、というメッセージが表示されている。この場合、コミット時に入力したメッセージは「svn-commit.tmp」という一時ファイルに保存される。
$ svn ci Sending echo.pl Transmitting file data .svn: Commit failed (details follow): svn: Out of date: '/echoes/echo.pl' in transaction '2-1' svn: Your commit message was left in a temporary file: svn: '/home/john/Dev/echoes/svn-commit.tmp'
このように競合が発生したら、まずは「svn update」コマンドを実行し、アップデートを行う。すると、自動的に変更点がチェックされ、可能な限り自動でその変更点がマージされる。ただし、同一の個所に異なる変更が加えられた場合など、自動でのマージに失敗する場合も多数ある。その場合、競合を解決する方法を選択し、場合によっては手動で競合している個所を修正する必要がある。
たとえば、下記の例は「echo.pl」というファイルに競合が発生している場合の例だ。
$ svn update
Conflict discovered in 'echo.pl'.
Select: (p) postpone, (df) diff-full, (e) edit,
(h) help for more options:
ここでキーボードから「df」と入力してEnterキーを押すと変更点の差分が表示される。また、「p」と入力してEnterキーを押すと、競合したファイルがまずリポジトリ内の最新バージョンに更新され、さらに自分が変更を加えた個所をマークアップしてくれる。たとえば、ファイル内で下記のようなマークアップが行われていた場合、「<<<<<<< .mine」から「=======」までの行が自分が変更を加えた内容、「=======」から「>>>>>>> .r<リビジョン番号>」までが最新リビジョンの内容だ。この情報を元にファイルを編集して競合を解消した上で、再度コミットを行えばよい。
my $form_data = {
'next_url' => '/home.pl',
<<<<<<< .mine
'email' => '',
'password' => '',
=======
'email' => 'hogehoge@foobar.com',
'password' => 'qwerty',
>>>>>>> .r2
'stickey' => '1',
};
なお、update時に競合が発生した場合、競合が発生したファイルごとに「<ファイル名>.mine」および「<ファイル名>.r<変更前リビジョン>」、「<ファイル名>.r<変更後リビジョン>」という3つのファイルが作成される。これらは、それぞれ下記のファイルを内容を含んでいる。
| ファイル名 | 説明 |
|---|---|
| <ファイル名>.mine | 自分が変更を加えてコミットを行おうとしたファイル |
| <ファイル名>.r<変更前リビジョン> | 変更を加える前のファイル |
| <ファイル名>.r<変更後リビジョン> | リポジトリ内にある最新リビジョンのファイル |
もし自分が加えた変更をすべて反映させたい場合は、「<ファイル名>.mine」を「<ファイル名>」にリネームすればよい。また、リポジトリにある最新版のファイルを優先し、競合する変更をすべて無かったことにするには「<ファイル名>.r<変更後リビジョン>」を「<ファイル名>」にリネームすればよい。
競合を解消したら、「svn resolved <ファイル名>」コマンドを実行する。これにより、「<ファイル名>.mine」および「<ファイル名>.r<変更前リビジョン>」、「<ファイル名>.r<変更後リビジョン>」が削除され、コミットが実行できる状態になる。