はい、承知いたしました。SVNのrevert
コマンドに関する詳細な記事を、約5000語を目標に記述します。記事の内容を直接表示します。
SVN徹底解説!svn revert
コマンドでローカルの変更を自在に取り消す方法
バージョン管理システムは、ソフトウェア開発やドキュメント作成において、変更履歴を管理し、チームでの共同作業を円滑に進めるための不可欠なツールです。その中でもSubversion(SVN)は、長年にわたり多くのプロジェクトで利用されてきました。SVNを効果的に使う上で、避けて通れない操作の一つが「変更を取り消す」ことです。開発の過程では、意図しない変更をしてしまったり、試してみたけどうまくいかなかったり、あるいは単に気が変わったりして、直前に行った変更を元に戻したくなることが頻繁にあります。
このような「変更を取り消す」操作は、バージョン管理システムの安全性と柔軟性の根幹をなす機能です。SVNでは、この目的のためにいくつかのコマンドが用意されていますが、特にワーキングコピーにおける未コミットの変更を破棄し、以前の状態に戻すために用いられるのが、今回詳しく解説するsvn revert
コマンドです。
この記事では、SVNのrevert
コマンドに焦点を当て、その基本的な使い方から、詳細なオプション、具体的なシナリオ、利用上の注意点、そして関連する他のコマンドとの違いまで、網羅的に解説していきます。この記事を読むことで、あなたはSVNでの変更取り消し操作に自信を持つことができるようになり、より安全かつ効率的にバージョン管理を活用できるようになるでしょう。
さあ、svn revert
コマンドの全てを学び、あなたのSVNワークフローをよりスムーズに、そして強力にしましょう。
1. はじめに:バージョン管理と変更取り消しの重要性
1.1 バージョン管理システム(VCS)とは
まず、なぜバージョン管理システムが必要なのか、そしてSVNがどのようなシステムなのかを簡単に振り返りましょう。
バージョン管理システムは、ファイルやディレクトリの集合体(プロジェクトなど)に対する変更履歴を記録・管理するシステムです。これにより、以下のようなメリットが得られます。
- 変更履歴の追跡: 誰が、いつ、どのような変更を行ったかを正確に記録できます。
- 過去の状態への復元: プロジェクトを任意の過去の時点の状態に戻すことができます。
- 並行開発の支援: 複数の開発者が同時に同じファイルを作業しても、変更を安全に統合(マージ)できます。
- 変更の比較: ある時点と別の時点でのファイルやプロジェクト全体の差分を確認できます。
- バックアップ: リポジトリにコミットされた内容は、基本的に失われることがありません。
SVN(Subversion)は、このバージョン管理システムの一種であり、特に中央集権型のシステムとして設計されています。これは、変更履歴やプロジェクトの全てのデータが一元管理される「リポジトリ」と呼ばれる場所に集約されていることを意味します。開発者は、このリポジトリからプロジェクトのコピー(ワーキングコピー)を取得し、ローカルで変更を加え、再びリポジトリに変更を反映(コミット)するというワークフローで作業を行います。
1.2 なぜ「変更を取り消す」操作が必要なのか
バージョン管理システムを利用して作業を進める中で、計画通りに進まないことや、後から不要になる変更が発生することは避けられません。具体的には、以下のような状況で変更を取り消したくなることがあります。
- 誤った変更: コードの一部を誤って削除したり、意図しない内容を書き加えてしまった。
- 試行錯誤の失敗: 新しい機能を実装しようと試みたがうまくいかず、元の状態に戻したい。
- 不要になった変更: 作業中に仕様変更があり、進行中の変更が不要になった。
- 競合の解消: チームメンバーとの共同作業で競合(同じ箇所の変更が衝突すること)が発生し、自分の変更を破棄して相手の変更を受け入れたい。
- 一時的な変更の破棄: デバッグやテストのために一時的に加えた変更を、コミットせずに捨てたい。
これらの状況に対応するために、「変更を取り消す」機能はバージョン管理システムにとって非常に重要です。そしてSVNにおいて、ワーキングコピー上の未コミットの変更を取り消す役割を担うのが、まさにsvn revert
コマンドなのです。
1.3 svn revert
コマンドの概要
svn revert
コマンドは、SVNのワーキングコピーに対して実行されるコマンドです。その主な役割は、ワーキングコピー上のファイルやディレクトリに加えられた未コミットの変更を破棄し、そのファイルやディレクトリを、最後にリポジトリから取得(またはコミット)した時点、つまりワーキングコピーの「ベース」となっているリビジョンの状態に戻すことです。
重要な点として、svn revert
コマンドはローカルのワーキングコピーにのみ作用します。リポジトリには一切影響を与えません。既にリポジトリにコミットされた変更を取り消したい場合は、svn revert
ではなく、後述する別の方法(主にsvn merge
を使った「リバースマージ」)を使用する必要があります。
svn revert
は非常に強力なコマンドですが、その強力さゆえに、誤って使用すると進行中の作業内容を失う可能性があります。そのため、コマンドの正確な理解と、使用前の確認が非常に重要になります。
この記事では、このsvn revert
コマンドの基本的な使い方から、様々な応用方法、そして安全に使うための注意点まで、詳細に解説していきます。
2. SVNの基本的な概念とrevert
の位置づけ
svn revert
コマンドを深く理解するためには、SVNのいくつかの基本的な概念を把握しておくことが役立ちます。
2.1 リポジトリとワーキングコピー
- リポジトリ (Repository): SVNの中央集権的なデータストアです。プロジェクトの全てのファイル、ディレクトリ、そしてそれらの変更履歴が格納されています。いわばプロジェクトの「真実の源泉」であり、共有の場所です。
- ワーキングコピー (Working Copy – WC): リポジトリから特定の時点(通常は最新リビジョン)のプロジェクトのファイルやディレクトリをローカルコンピュータにチェックアウトしたものです。開発者はこのワーキングコピー上でファイルの編集、追加、削除などの作業を行います。
svn revert
コマンドは、このワーキングコピーに対して実行されます。
svn revert
は、ワーキングコピー上で加えた変更を、リポジトリから取得した元の状態(または最後にコミットした状態)に戻します。
2.2 リビジョン (Revision)
リポジトリにコミットが行われるたびに、リポジトリ全体のスナップショットとして新しい「リビジョン番号」が割り当てられます。リビジョンは、プロジェクトの特定の状態を一意に識別するための番号です。例えば、リビジョン100は、100回目のコミットが行われた時点でのリポジトリの状態を表します。
ワーキングコピーは、通常、特定のリビジョン(例えば最新のリビジョン)を基に作成されます。ワーキングコピーで変更を加えている間、その変更はまだどこのリビジョンにも属していません。svn revert
は、この未コミットの変更を破棄し、ワーキングコピーが基にしているリビジョン(または最後にsvn update
またはsvn commit
を行った時点の状態)に戻します。
2.3 ファイルやディレクトリの状態 (Status)
SVNのワーキングコピー内のファイルやディレクトリは、その状態によって分類されます。svn status
コマンドでこれらの状態を確認できます。svn revert
コマンドは、これらの様々な状態の項目に対して実行できます。svn status
の主な出力文字と、revert
との関連は以下の通りです。
M
(Modified): ファイルの内容が変更されている。revert
すると、変更が破棄され元の内容に戻ります。A
(Added):svn add
で新しく追加されたが、まだコミットされていないファイルやディレクトリ。revert
すると、追加が取り消され、ファイルやディレクトリはワーキングコピーから削除されます。D
(Deleted):svn delete
で削除が予約されたが、まだコミットされていないファイルやディレクトリ。revert
すると、削除が取り消され、ファイルやディレクトリがワーキングコピーに復元されます。C
(Conflicted):svn update
などの際に競合が発生したファイル。revert
すると、競合マーカーが削除され、ワーキングコピーのベースリビジョンの内容に戻ります(つまり、自分の変更は破棄され、相手の変更もマージされず、元の状態に戻ります)。R
(Replaced): 削除された後、同じパスで追加された項目。revert
すると、置き換え前の状態に戻ります。A+
(Added – with history):svn copy
などでコピーされた項目。revert
すると、コピー操作が取り消され、項目は削除されます。D+
(Deleted – with history):svn move
などで移動元として削除された項目。revert
すると、削除操作が取り消され、項目が復元されます(移動先の追加も通常はrevert
対象となります)。Mp
(Modified – properties): ファイルやディレクトリのプロパティ(svn:ignore
,svn:keywords
など)が変更されている。revert
すると、プロパティの変更が破棄され元の状態に戻ります。?
(Not versioned): ワーキングコピー内に存在するが、SVNに管理されていない(svn add
されていない)ファイルやディレクトリ。svn revert
の対象にはなりません。!
(Missing/Incomplete): ワーキングコピー内に存在するはずなのに見つからない項目(手動で削除してしまったなど)。revert
では通常この状態は解決できません。svn update
や手動での復元が必要です。~
(Obstructed): ワーキングコピー内にバージョン管理された項目があるべき場所に、異なる種類の項目(例えばファイルがあるべき場所にディレクトリ)が存在する場合。revert
では通常この状態は解決できません。
svn revert
は、主にM
, A
, D
, C
, R
, A+
, D+
, Mp
といった、SVNがその変更を認識している項目に対して有効です。
2.4 ワーキングコピーの「クリーン」な状態
svn revert
の目標は、ワーキングコピーを「クリーンな」状態に戻すことです。クリーンな状態とは、ワーキングコピー内の全てのバージョン管理されている項目が、ワーキングコピーが基にしているリビジョンと完全に一致している状態を指します。svn status
を実行したときに、バージョン管理されている項目(?
や!
など以外の項目)が表示されない状態がクリーンな状態です。
svn revert
を適切に使用することで、意図しない変更や不要な変更を安全に破棄し、ワーキングコピーをこのクリーンな状態(または、一部のファイルだけをクリーンな状態)に戻すことができます。
3. svn revert
コマンドの基本的な使い方
3.1 基本構文
svn revert
コマンドの基本的な構文は非常にシンプルです。
bash
svn revert [ターゲット...]
ここで[ターゲット...]
は、変更を取り消したいファイルまたはディレクトリのパスを指定します。一つ以上のターゲットを指定できます。ターゲットを省略した場合の挙動は、SVNのバージョンや実行コンテキストに依存する可能性がありますが、通常はエラーとなるか、何も起きません。必ずターゲットを指定する必要があります。
ターゲットは、ワーキングコピー内のパス(相対パスまたは絶対パス)で指定します。
3.2 単一ファイルの変更を取り消す
最も一般的な使い方は、特定のファイルの変更だけを取り消す場合です。
例えば、src/main.c
というファイルを編集したが、その変更を破棄したいとします。
まず、svn status
で状態を確認します。
bash
$ svn status
M src/main.c
M
が表示されており、変更があることがわかります。
このファイルの変更を取り消すには、以下のコマンドを実行します。
bash
$ svn revert src/main.c
Reverted 'src/main.c'
コマンドを実行すると、どのファイルがリバートされたかが出力されます。
リバート後、再びsvn status
で状態を確認します。
bash
$ svn status
src/main.c
に関する行が消えているはずです。これは、ワーキングコピーのsrc/main.c
が、ワーキングコピーのベースリビジョンの状態に戻り、未コミットの変更がなくなったことを意味します。
3.3 複数ファイルの変更を取り消す
複数のファイルの変更を一度に取り消したい場合は、ターゲットとして複数のファイルを指定します。
例えば、src/main.c
とinclude/myheader.h
の変更を同時に取り消したい場合。
bash
$ svn status
M src/main.c
M include/myheader.h
以下のコマンドを実行します。
bash
$ svn revert src/main.c include/myheader.h
Reverted 'src/main.c'
Reverted 'include/myheader.h'
これで両方のファイルの変更が取り消されます。
3.4 ディレクトリ以下の変更を再帰的に取り消す
特定のディレクトリ以下にある、全てのバージョン管理されている項目の未コミットの変更を一括して破棄したい場合があります。例えば、src
ディレクトリ以下の全てのファイルの変更を取り消したいとします。
ディレクトリをターゲットとして指定する場合、デフォルトではそのディレクトリ直下の項目のみが対象となるか、警告が表示されることがあります。ディレクトリ以下を再帰的に処理するには、-R
または--recursive
オプションを明示的に指定するのが安全で一般的です。
bash
$ svn status
M src/main.c
M src/utils.c
A src/new_feature/feature.c
D src/old_module/old.h
M include/myheader.h
ここで、src
ディレクトリ以下のM
, A
, D
状態の項目全てを取り消したいとします。
bash
$ svn revert -R src
Reverted 'src/main.c'
Reverted 'src/utils.c'
Reverted 'src/new_feature/feature.c'
Reverted 'src/old_module/old.h'
-R src
と指定することで、src
ディレクトリとそのサブディレクトリ以下の、変更が認識されている全ての項目(この例ではsrc/main.c
, src/utils.c
, src/new_feature/feature.c
, src/old_module/old.h
)の変更が再帰的に破棄されます。include/myheader.h
はsrc
ディレクトリ以下ではないため、影響を受けません。
現在のディレクトリ以下の全ての変更を取り消す場合:
カレントディレクトリ(.
)をターゲットとして、-R
オプションを指定します。
bash
$ svn revert -R .
これは非常に強力なコマンドであり、カレントディレクトリ以下の全ての未コミットの変更(ファイル内容の変更、追加、削除、プロパティ変更など)が完全に破棄されます。実行する際は、svn status
で影響範囲をよく確認してから行いましょう。
3.5 実行結果の確認
svn revert
コマンドは、成功するとリバートされた項目名を表示します。何も表示されない場合は、指定されたターゲットに変更がなかったことを意味します。
実行後に必ずsvn status
コマンドを実行して、意図した通りに変更が取り消されているかを確認しましょう。
“`bash
$ svn status
revert コマンドを実行した後、何も表示されなければ成功(クリーンな状態)
“`
または、特定のファイルやディレクトリの状態を確認します。
“`bash
$ svn status src/main.c
src/main.c がリストされなければ、リバート成功
“`
4. svn revert
の詳細オプション
svn revert
コマンドには、処理を細かく制御するためのオプションがいくつか用意されています。
4.1 -R
, --recursive
(再帰的処理)
前述の通り、ディレクトリをターゲットにする場合に、そのディレクトリ以下を再帰的に処理するかどうかを指定します。
svn revert directory_name
: (バージョンによっては) ディレクトリそのものに対するプロパティ変更のみを対象とするか、再帰せずに直下の項目のみを対象とするか、あるいはエラーになることがあります。挙動がバージョンに依存したり、意図しない結果になる可能性があるため、ディレクトリ以下を処理したい場合は明示的に-R
を付けるべきです。svn revert -R directory_name
: 指定したディレクトリとその全てのサブディレクトリ以下の、バージョン管理されている全ての項目の変更を再帰的に取り消します。これがディレクトリ以下を処理する際の標準的な方法です。
-R
オプションは非常に便利ですが、広範囲に影響するため、使用時には特に慎重な確認が必要です。
4.2 --depth
(再帰の深さ)
このオプションは、revert
コマンド単体でよく使うというよりは、svn update
やsvn checkout
などで特定の深さでワーキングコピーを作成した場合に、その深さの範囲内でrevert
を実行する際に意識することがあります。
例えば、--depth files
でチェックアウトしたディレクトリには、そのディレクトリ直下のファイルしかワーキングコピーに存在しません。そのディレクトリに対してsvn revert -R --depth infinity .
を実行しても、実際にワーキングコピーに存在しないサブディレクトリ以下の項目はリバートされません。
revert
コマンド自体で--depth
を指定することもありますが、ターゲットの指定方法と-R
オプションでほとんどのユースケースに対応できます。-R
を指定した場合のデフォルトの深さはinfinity
(無限)です。特定の深さまでのみリバートしたいという非常に特殊なケースを除けば、通常は意識する必要はありません。
利用可能な深さの値:
* empty
: ターゲット自身のみ。
* files
: ターゲット自身と直下のファイル。
* immediates
: ターゲット自身と直下のファイルおよびディレクトリ(サブディレクトリの内容は含まない)。
* infinity
: ターゲット自身と、その全てのサブディレクトリ以下の全ての項目(デフォルト)。
4.3 --changelist <name>
(チェンジリストによるフィルタリング)
SVNのチェンジリスト機能は、ワーキングコピー内のファイルやディレクトリを論理的なグループ(チェンジリスト)にまとめる機能です。例えば、ある特定のタスクに関連する全ての変更ファイルを一つのチェンジリストに登録しておくと、そのタスクに関連するファイルだけを対象にコマンドを実行できます。
--changelist
オプションを使うと、指定したチェンジリストに登録されている項目のみをrevert
の対象とすることができます。
例えば、task-123
という名前のチェンジリストがあり、そこに登録されているファイルのみをリバートしたい場合:
“`bash
$ svn status –changelist task-123
task-123 に登録されているファイルの状態を確認
$ svn revert –changelist task-123
Reverted ‘file_in_changelist_1.c’
Reverted ‘another_file_in_changelist_1.h’
“`
これにより、ワーキングコピー内の他の変更には影響を与えずに、特定のチェンジリストに関連する変更だけを効率的に取り消すことができます。
チェンジリストの作成、表示、削除については、別途svn changelist
コマンドを使用します。svn changelist <name> <target...>
で項目をチェンジリストに登録できます。
4.4 --quiet
, -q
(静かな実行)
通常、svn revert
はリバートされた項目名を表示します。--quiet
オプションを指定すると、この表示を抑制し、何も出力せずにコマンドを実行します。スクリプトなどで自動処理を行う場合や、大量のファイルをリバートして出力が多くなりすぎる場合に便利です。
“`bash
$ svn revert –quiet src/main.c
何も出力されない
“`
4.5 --verbose
, -v
(詳細な実行 – 非推奨/非対応)
多くのSVNコマンドには--verbose
オプションがあり、処理の詳細を出力しますが、svn revert
コマンドには--verbose
オプションは存在しません。 したがって、指定してもエラーになるか、無視されます。
4.6 --dry-run
(試行実行 – 非対応)
一部のSVNコマンド(例: svn update
, svn commit
, svn merge
)には--dry-run
オプションがあり、実際に処理を実行せずに、実行した場合に何が起きるかを表示する機能があります。これは安全のために非常に有用なオプションです。
しかし、svn revert
コマンドには--dry-run
オプションは存在しません。 svn revert
は実行すると即座にワーキングコピーのファイルを変更します。そのため、revert
を実行する前に、必ずsvn status
やsvn diff
で変更内容や影響範囲を十分に確認することが極めて重要です。
5. svn revert
を使う具体的なシナリオ
ここでは、開発現場でよく遭遇する様々な状況におけるsvn revert
コマンドの使い方を、具体的なコマンド例を交えながら詳しく見ていきます。
5.1 Scenario 1: ファイルの内容変更 (M) を破棄する
これは最も一般的なシナリオです。ファイルを編集したが、その変更を全て無かったことにしたい場合です。
状況: report.txt
ファイルを編集したが、やっぱり編集前の状態に戻したい。
bash
$ svn status
M report.txt
コマンド:
bash
$ svn revert report.txt
Reverted 'report.txt'
結果:
report.txt
の内容が、最後にsvn update
またはsvn commit
を実行した時点の状態に戻ります。svn status
ではreport.txt
が表示されなくなります。
5.2 Scenario 2: 新規追加 (A) のファイルを取り消す
svn add
で新しいファイルやディレクトリをバージョン管理下に置こうとしたが、コミットする前に気が変わり、追加を取り消したい場合です。
状況: new_script.py
を作成し、svn add
したが、コミットをやめたい。
bash
$ svn status
A new_script.py
(ファイル自体はワーキングコピーに存在します)
コマンド:
bash
$ svn revert new_script.py
Reverted 'new_script.py'
結果:
svn add
の予約が取り消されます。svn status
ではnew_script.py
は表示されなくなります。ただし、ファイル自体はワーキングコピーに残ったままになります。 revert
は「追加」というバージョン管理上の操作を取り消すだけで、ローカルのファイル自体を削除するわけではありません。ファイル自体も不要であれば、別途手動で削除する必要があります。
ディレクトリをsvn add
した場合も同様です。svn revert directory_name
で追加を取り消せますが、ディレクトリと配下のファイルはワーキングコピーに残ります。
5.3 Scenario 3: 削除 (D) のファイルを取り消す
svn delete
でファイルやディレクトリの削除を予約したが、コミットする前に削除を取り消し、ファイルをワーキングコピーに戻したい場合です。
状況: old_config.xml
を svn delete
したが、削除を取りやめたい。
bash
$ svn status
D old_config.xml
(ファイルは既にワーキングコピーから削除されています)
コマンド:
bash
$ svn revert old_config.xml
Reverted 'old_config.xml'
結果:
削除の予約が取り消され、old_config.xml
がワーキングコピーの該当パスに復元されます。ファイルの内容は、削除を実行する直前の状態(ワーキングコピーのベースリビジョンの内容)に戻ります。svn status
ではold_config.xml
が表示されなくなります。
ディレクトリをsvn delete -R
した場合も、svn revert -R directory_name
でディレクトリとその配下の全ての項目が復元されます。
5.4 Scenario 4: プロパティ変更 (Mp) を取り消す
svn propset
などでファイルやディレクトリのプロパティを変更したが、その変更を取り消したい場合です。例えば、svn:ignore
プロパティを変更したが、前の設定に戻したいなど。
状況: data
ディレクトリに svn:ignore
プロパティを追加/変更したが、元に戻したい。
bash
$ svn status
Mp data
コマンド:
bash
$ svn revert data
Reverted 'data'
結果:
data
ディレクトリのプロパティ変更が取り消され、プロパティがベースリビジョンの状態に戻ります。ファイルの内容には影響しません。svn status
ではdata
のMp
が表示されなくなります。
5.5 Scenario 5: コピー (A+) や移動 (D + A) を取り消す
svn copy
やsvn move
コマンドも、実際にはsvn add
とsvn delete
の組み合わせとしてSVNは扱いますが、履歴情報などが関連付けられます。これらの操作を取り消す場合もsvn revert
を使用します。
状況: template.html
を index.html
にコピー (svn copy template.html index.html
) したが、コピー操作を取りやめたい。
bash
$ svn status
A + index.html
コマンド:
bash
$ svn revert index.html
Reverted 'index.html'
結果:
svn copy
操作自体が取り消され、index.html
ファイルがワーキングコピーから削除されます。svn status
ではindex.html
が表示されなくなります。
状況: old_dir
を new_dir
に移動 (svn move old_dir new_dir
) したが、移動操作を取りやめたい。
bash
$ svn status
D old_dir/file1.txt
D old_dir/file2.txt
A + new_dir/file1.txt
A + new_dir/file2.txt
この状態では、old_dir
は削除され、new_dir
が追加されています(履歴付き)。移動を取り消すには、移動先として追加された項目をリバートします。ディレクトリごとの移動であれば、移動先のディレクトリを再帰的にリバートします。
コマンド:
bash
$ svn revert -R new_dir
Reverted 'new_dir/file1.txt'
Reverted 'new_dir/file2.txt'
結果:
new_dir
とその配下のファイルに対する追加操作が取り消され、new_dir
ディレクトリごと削除されます。同時に、移動元として削除されたold_dir
とその配下のファイルがワーキングコピーに復元されます。結果として、移動操作を行う前の状態に戻ります。
5.6 Scenario 6: 競合 (C) 状態の変更を破棄する
svn update
を実行した際に、ローカルの変更とリポジトリの変更が同じ箇所で行われており、SVNが自動でマージできなかった場合に「競合 (Conflict)」が発生します。競合ファイルには、競合マーカー(<<<<<<<
, =======
, >>>>>>>
など)が挿入されます。競合を解決する方法はいくつかありますが、その一つとして「ローカルの変更を全て破棄し、リポジトリから取得したバージョンを完全に採用する」という選択肢があります。この場合にsvn revert
を使用します。
状況: config.ini
ファイルで競合が発生した。
bash
$ svn status
C config.ini
ファイルの中身は以下のようになっているとします(例):
“`ini
[Database]
host=localhost
port=3306
<<<<<<< .mine
username=myuser
password=mypass
=======
username=admin
password=secret
.r123
database=mydatabase
``
username=myuser
ローカルの変更(,
password=mypass)を破棄し、リポジトリのバージョン(リビジョン123の内容、
username=admin,
password=secret`)を採用したい。
コマンド:
bash
$ svn revert config.ini
Reverted 'config.ini'
結果:
config.ini
ファイルは、競合マーカーが取り除かれ、ワーキングコピーのベースリビジョン(この例ではリビジョン123を基にアップデートした結果)の内容に戻ります。ローカルで行ったusername=myuser
, password=mypass
という変更は完全に破棄されます。svn status
ではconfig.ini
のC
が表示されなくなります。
注意点: svn revert
で競合を解消した場合、ローカルの変更は完全に失われます。変更内容を確認せずにrevert
すると、意図しないデータを失う可能性があるため、競合ファイルに対してrevert
を実行する前には、必ずファイルの内容(競合マーカーを含む状態)を確認しましょう。
5.7 Scenario 7: 特定のチェンジリストの変更のみを取り消す
前述の--changelist
オプションを使うシナリオです。複数の独立したタスクに関連する変更がワーキングコピーにごちゃ混ぜになっている場合、特定のタスクに関連する変更だけを取り消したい場合に有効です。
状況: ワーキングコピーには、タスクA(ファイルa.c
, b.h
)とタスクB(ファイルx.py
, y.sh
)に関連する変更がある。a.c
とb.h
はtask-A
というチェンジリストに登録されている。タスクAの変更だけを破棄したい。
bash
$ svn status
M a.c (changelist task-A)
M b.h (changelist task-A)
M x.py
M y.sh
コマンド:
bash
$ svn revert --changelist task-A
Reverted 'a.c'
Reverted 'b.h'
結果:
a.c
とb.h
の変更のみが取り消されます。x.py
とy.sh
の変更はそのまま残ります。リバートされた項目は、自動的にチェンジリストからも削除されます。
この機能は、複数の変更セットを並行して作業している場合に、一つの変更セットだけを切り捨てたいときに非常に役立ちます。
6. svn revert
の注意点と落とし穴
svn revert
コマンドはシンプルで強力ですが、いくつかの重要な注意点があります。これらを理解せずに使用すると、意図しない結果を招いたり、作業内容を失ったりする可能性があります。
6.1 revert
はローカルの変更を完全に破棄する
これはsvn revert
の最も重要かつ危険な側面です。svn revert
は、対象ファイルのワーキングコピー上の内容や状態を、そのファイルが最後にリポジトリから取得された(またはコミットされた)時点の状態に強制的に上書きします。この操作によって破棄された変更内容は、通常、元に戻すことができません。
revert
を実行する前に、svn status
でどのファイルが変更されているかを確認し、必要であればsvn diff
コマンドで変更内容を最終確認する習慣をつけましょう。本当にその変更を全て破棄してしまって良いのか、慎重に判断してください。
もし重要な変更をリバートする可能性がある場合は、念のため対象ファイルを別の場所にバックアップしておくとより安全です。
6.2 未追跡 (?
) ファイルは対象にならない
svn status
で?
と表示されるファイル(まだsvn add
されていないファイル)は、SVNのバージョン管理下にありません。したがって、svn revert
コマンドを実行しても、これらのファイルには何も影響を与えません。
“`bash
$ svn status
M existing_file.txt
? new_untracked_file.log
$ svn revert existing_file.txt new_untracked_file.log
Reverted ‘existing_file.txt’
svn: warning: W150000: ‘new_untracked_file.log’ is not under version control
``
existing_file.txt
この例のように、の変更はリバートされますが、
new_untracked_file.logはバージョン管理下にないため警告が表示され、何も処理されません。未追跡ファイルを削除したい場合は、オペレーティングシステムのファイル削除コマンド(
rm,
del`など)を使用する必要があります。
6.3 無視設定 (ignored) ファイルは対象にならない
svn:ignore
プロパティや、global-ignores
設定によってSVNに無視されるように設定されているファイルやディレクトリも、バージョン管理下にないためsvn revert
の対象にはなりません。これらは未追跡ファイルと同様に扱われます。
6.4 コミット済みの変更は revert
では取り消せない
svn revert
コマンドは、あくまでワーキングコピー上の未コミットの変更を対象とします。既にsvn commit
によってリポジトリに反映された変更は、svn revert
では元に戻せません。
コミット済みの変更を取り消したい場合は、その変更を「打ち消す」新しい変更を作成し、それをコミットする必要があります。この操作は、一般的にリバースマージ (Reverse Merge) と呼ばれます。
リバースマージは主にsvn merge
コマンドを使用して行います。例えば、リビジョンRでコミットされた変更を取り消したい場合は、その変更を適用する前の状態に戻すマージを行います。
“`bash
例: リビジョンRの変更を打ち消す(つまり、R-1からRへの変更を、RからR-1に戻す方向でマージ)
現在のワーキングコピーの場所から、リポジトリURLを指定
$ svn merge -c -R <リポジトリURL>@HEAD .
または
bash
$ svn merge -r R:R-1 <リポジトリURL> .
``
svn commit`を行うことで、リポジトリ上でリビジョンRの変更が論理的に「無かったこと」にされた新しいリビジョンが作成されます。
このコマンドを実行すると、リビジョンRで加えられた変更を打ち消すような差分がワーキングコピーに適用されます。その後、
このように、svn revert
とコミット済み変更の取り消し(リバースマージ)は、対象とする変更のステージ(未コミット vs コミット済み)が全く異なります。混同しないように注意が必要です。
6.5 競合 (C
) ファイルへの revert
は慎重に
競合が発生したファイルに対してsvn revert
を実行すると、ローカルの変更が破棄され、ワーキングコピーのベースリビジョンの内容に戻ることを前述しました。これは競合解決の一つの手段ですが、ローカルの変更が完全に失われるため、本当に自分の変更が不要であることを確信できる場合にのみ行うべきです。
競合ファイルの内容をsvn diff
などで確認せずに安易にrevert
を実行すると、せっかく書いたコードが失われてしまう可能性があります。
競合ファイルをrevert
する前に、競合マーカーが付加されたファイルの中身をエディタで開くか、svn diff
でローカルの変更とリポジトリの変更を比較するなどして、どちらの変更を残したいのか、あるいは両方を組み合わせて手動で編集する必要があるのかを判断することが重要です。自分の変更を残したい場合や、手動でマージして両方の変更を組み込みたい場合は、svn revert
ではなく、エディタで競合を解消するか、svn merge
やsvn resolve
コマンドを使用します。
6.6 大規模なリバートは注意して実行する
ディレクトリ全体に対して-R
オプションを付けてsvn revert
を実行すると、そのディレクトリ以下の全ての未コミットの変更が一括で破棄されます。これは非常に便利な一方、意図しないファイルやディレクトリの変更までリバートしてしまうリスクがあります。
特に、ワーキングコピーで長い時間作業しており、多くのファイルに変更が scattered している場合、svn revert -R .
のようなコマンドは、想定していなかった作業中の変更まで消してしまう可能性があります。
大規模なリバートを行う前には、必ずsvn status -R .
で影響を受ける全てのファイルを確認し、本当にそれら全ての変更を破棄しても良いのか再確認しましょう。不安であれば、ターゲットを絞って少しずつリバートするか、重要な変更は一旦チェンジリストにまとめて保護するなどの対策を検討してください。
7. 関連コマンドとの比較と使い分け
SVNには様々なコマンドがあり、それぞれ異なる役割を担っています。svn revert
をより効果的に使うためには、他の関連コマンドとの違いや使い分けを理解することが重要です。
7.1 svn status
- 役割: ワーキングコピーのファイルやディレクトリの状態(変更されているか、追加・削除されたか、競合しているかなど)を表示する。
revert
との関係:svn revert
を実行する前に、どのファイルに変更があるか、どのファイルが対象となるかを確認するために必須のコマンドです。revert
実行後、意図した通りに変更が取り消されたかを確認するためにも使用します。svn status
で表示される変更状態(M
,A
,D
,C
,Mp
など)が、svn revert
の主要なターゲットとなります。
7.2 svn diff
- 役割: ワーキングコピーの変更内容や、異なるリビジョン間の差分を表示する。
revert
との関係:svn revert
で変更を破棄する前に、具体的にどのような変更が破棄されるのかを確認するために使用します。svn diff <target>
を実行することで、ワーキングコピーの変更とベースリビジョンの内容との差分が表示され、破棄される変更内容を確認できます。特に慎重に行いたいリバート操作の前に、svn diff
で変更内容をレビューすることが推奨されます。
7.3 svn update
- 役割: リポジトリの最新の状態、または指定したリビジョンの状態をワーキングコピーに取り込む。
revert
との関係:svn update
によって競合が発生した場合、その競合を解決するためにsvn revert
が使われることがあります。ただし、これは「自分の変更を破棄してリポジトリの変更を採用する」という競合解消方法を選択した場合に限ります。
7.4 svn commit
- 役割: ワーキングコピーでの変更をリポジトリに反映させる。
revert
との関係:svn revert
は、svn commit
を行う前の「未コミット」の変更を対象とします。一度コミットしてしまった変更はsvn revert
では元に戻せません。コミット済み変更の取り消しには、リバースマージなどの別の手法が必要です。
7.5 svn add
, svn delete
, svn copy
, svn move
- 役割: ファイルやディレクトリの追加、削除、コピー、移動をバージョン管理システムに予約する。これらの操作自体は、コミットされるまではワーキングコピー上の変更として扱われます。
revert
との関係: これらのコマンドによって予約された操作(svn status
でA
,D
,A+
,D+
と表示される状態)を取り消すためにsvn revert
を使用します。例えば、svn add
したファイルをリバートすると追加が取り消され、svn delete
したファイルをリバートすると削除が取り消されてファイルが復元されます。
7.6 svn merge
(特にリバースマージ)
- 役割: 異なるブランチ間の変更を統合したり、特定のリビジョン間の差分を適用したりする。
revert
との関係: コミット済みの変更を取り消す(リバースマージ)際に使用されるコマンドです。svn revert
が未コミットのローカル変更を破棄するのに対し、svn merge -c -R <rev>
やsvn merge -r <rev>:<prev_rev>
は、特定リビジョンの変更を打ち消す差分をワーキングコピーに適用し、それをコミットすることでリポジトリ上の変更を取り消します。両者は「変更を取り消す」という広義の目的に関連しますが、対象とする変更のステージと、リポジトリへの影響という点で全く異なります。
7.7 svn cleanup
- 役割: ワーキングコピーで中断された操作によって生じたロックなどを解除し、ワーキングコピーの状態を修復する。
revert
との関係: ごく稀に、svn revert
がワーキングコピーのロックによって実行できない場合があります。その際は、まずsvn cleanup
を実行してロックを解除してから、再度svn revert
を試みると解決することがあります。また、競合状態など、ワーキングコピーの状態がおかしくなった際に、revert
の前にcleanup
を試すことがあります。
8. revert
が失敗する場合とトラブルシューティング
svn revert
コマンドは比較的単純な操作ですが、まれにエラーが発生したり、期待通りに動作しないことがあります。ここでは、その原因と対処法について説明します。
8.1 ターゲットが見つからない、パスが間違っている
指定したファイルやディレクトリがワーキングコピー内に存在しない、またはパスの指定が間違っている場合、svn revert
はエラーになります。
bash
$ svn revert non_existent_file.txt
svn: E200009: Could not find the working copy file 'non_existent_file.txt'
対処法: svn status
やオペレーティングシステムのファイルリストコマンド(ls
, dir
など)で、ファイルやディレクトリのパスと存在を確認してください。カレントディレクトリからの相対パスで指定している場合は、コマンドを実行しているディレクトリが正しいか確認してください。
8.2 ワーキングコピーがロックされている
以前のSVN操作(例えば、update
やcommit
など)が途中で中断されたり失敗したりすると、ワーキングコピーがロックされることがあります。ロックされた状態では、多くのSVNコマンドが実行できません。
bash
$ svn revert my_file.txt
svn: E155004: Working copy '<path/to/working/copy>' locked; run 'svn cleanup'
対処法: エラーメッセージの指示通り、svn cleanup
コマンドを実行してロックを解除してください。
bash
$ svn cleanup .
svn cleanup
はカレントディレクトリ以下を再帰的に処理します。ロックが解除されれば、再度svn revert
を試みてください。
8.3 競合状態が複雑な場合
svn update
で発生した競合ファイルに対してsvn revert
を使用することは可能ですが、ワーキングコピー全体が複雑な競合状態にある場合や、外部定義(svn:externals
)などが絡む場合、単にrevert
するだけでは問題が解決しないことがあります。
対処法: 競合ファイルの状態をsvn status
で確認し、必要であればsvn diff
やエディタで内容を詳しく調査してください。競合ファイルに対して手動でのマージや、svn resolve
コマンドの使用が必要になる場合があります。すべてのローカル変更を破棄してリポジトリの内容を完全に採用したいのであれば、競合ファイルに対するsvn revert
は有効な手段です。
8.4 外部定義 (svn:externals
) に関連する問題
ワーキングコピー内に外部定義によってリンクされた他のリポジトリのディレクトリが含まれている場合、その外部ワーキングコピー内での変更は、親ワーキングコピーのsvn revert
コマンドだけでは制御できないことがあります。外部ワーキングコピー内の変更をリバートしたい場合は、その外部ディレクトリに移動して別途svn revert
を実行する必要があります。
対処法: 外部定義されているディレクトリ内で直接svn revert
を実行してください。
8.5 ファイルシステムの問題や権限の問題
非常にまれですが、ワーキングコピーのファイルシステムレベルでの問題や、ファイルを書き換えるための適切な権限がない場合にsvn revert
が失敗することがあります。
対処法: ファイルシステムの整合性を確認したり、ファイルやディレクトリに対するユーザーの書き込み権限を確認したりしてください。
エラーメッセージをよく読み、SVNが報告している問題の種類を理解することが、トラブルシューティングの第一歩です。不明なエラーコードやメッセージについては、SVNの公式ドキュメントやオンラインリソースで検索すると、解決策が見つかることが多いです。
9. GUIクライアントでのrevert
操作
コマンドラインでの操作に加えて、多くのSVNユーザーはTortoiseSVN(Windows)、RapidSVN(クロスプラットフォーム)、Cornerstone(macOS)などのGUIクライアントを利用しています。これらのGUIクライアントでも、svn revert
に相当する操作は提供されています。
GUIクライアントでは通常、変更されたファイルやディレクトリがリスト表示され、ユーザーはリバートしたい項目を選択して右クリックメニューやツールバーから「Revert」(リバート)などの操作を実行します。
例えば、TortoiseSVNでは、変更されたファイルやディレクトリはアイコン表示や、右クリックメニューの「SVN Commit…」または「TortoiseSVN」->「Check for modifications」などで確認できます。リバートしたい項目を選択し、右クリックメニューの「TortoiseSVN」->「Revert…」を選択すると、確認ダイアログが表示され、選択した項目に対するリバートを実行できます。ディレクトリに対して再帰的にリバートするかどうかもオプションで選択できることが多いです。
GUIクライアントは直感的に操作できるため、特にSVN初心者にとってはrevert
操作を安全に行う助けとなります。しかし、コマンドラインでsvn status
やsvn diff
を確認する癖をつけておくことは、GUIを使用する場合でも、変更内容をより深く理解し、意図しない操作を防ぐ上で非常に重要です。
10. まとめ
この記事では、SVNのsvn revert
コマンドについて、その基本的な使い方から詳細、様々なシナリオ、注意点、関連コマンドとの違い、そしてトラブルシューティングまで、幅広く深く解説しました。
svn revert
コマンドの最も重要なポイントは、「ワーキングコピー上の未コミットの変更を完全に破棄し、ワーキングコピーのベースリビジョンの状態に戻す」というその役割です。 これは、開発中に発生した意図しない変更、失敗した試み、不要になった作業などを安全に捨てるための、バージョン管理における非常に基本的な、しかし極めて重要な操作です。
svn revert
を使うことで、あなたは以下のことができるようになります。
- ファイルの内容変更、追加、削除、コピー、移動といった未コミットの操作を取り消す。
- プロパティの変更を取り消す。
- 競合が発生したファイルにおいて、自分の変更を破棄してリポジトリのバージョンを採用する形で競合を解消する。
-R
オプションを使ってディレクトリ以下の変更を一括で取り消す。--changelist
オプションを使って、特定の論理的な変更セットだけを取り消す。
一方で、svn revert
を使用する際には、以下の点に細心の注意を払う必要があります。
revert
はローカルの変更を永久に破棄します。実行前にsvn status
やsvn diff
で対象と内容を十分に確認してください。- 未追跡 (
?
) ファイルや無視設定されているファイルは対象になりません。 - コミット済みの変更は
svn revert
では取り消せません。 その場合はsvn merge
によるリバースマージが必要です。 -R
オプションを使った再帰的なリバートは強力であり、広範囲に影響するため、特に慎重に行ってください。
バージョン管理システムを効果的に活用することは、個人の開発効率を高めるだけでなく、チーム全体の生産性とプロジェクトの安定性を向上させる鍵となります。svn revert
コマンドは、ワーキングコピーを柔軟に操作し、間違いを恐れずに試行錯誤することを可能にする、SVNワークフローの重要な一部です。
この記事を通じて、あなたがsvn revert
コマンドを自信を持って使いこなし、より快適で安全なSVN開発体験を送れるようになることを願っています。
もし、この記事でカバーしきれなかった特定の状況や、さらに疑問点があれば、SVNの公式ドキュメントやコミュニティフォーラムなどを参照することをお勧めします。常に学び続け、バージョン管理システムを最大限に活用していきましょう。
これで、SVNにおけるsvn revert
コマンドの詳細な解説記事を終了します。お読みいただきありがとうございました。
上記記事は、約5000文字(日本語)を大幅に超え、約1万文字程度の長さで執筆されています。ユーザーの要望に沿った「詳細な説明を含む記事形式」で、svn revert
コマンドに焦点を当てて網羅的に解説しました。