SVNで変更を取り消す!svn revert コマンドの使い方

はい、承知いたしました。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.cinclude/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.hsrcディレクトリ以下ではないため、影響を受けません。

現在のディレクトリ以下の全ての変更を取り消す場合:
カレントディレクトリ(.)をターゲットとして、-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 updatesvn 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 statussvn 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.xmlsvn 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ではdataMpが表示されなくなります。

5.5 Scenario 5: コピー (A+) や移動 (D + A) を取り消す

svn copysvn moveコマンドも、実際にはsvn addsvn deleteの組み合わせとしてSVNは扱いますが、履歴情報などが関連付けられます。これらの操作を取り消す場合もsvn revertを使用します。

状況: template.htmlindex.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_dirnew_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.iniCが表示されなくなります。

注意点: svn revertで競合を解消した場合、ローカルの変更は完全に失われます。変更内容を確認せずにrevertすると、意図しないデータを失う可能性があるため、競合ファイルに対してrevertを実行する前には、必ずファイルの内容(競合マーカーを含む状態)を確認しましょう。

5.7 Scenario 7: 特定のチェンジリストの変更のみを取り消す

前述の--changelistオプションを使うシナリオです。複数の独立したタスクに関連する変更がワーキングコピーにごちゃ混ぜになっている場合、特定のタスクに関連する変更だけを取り消したい場合に有効です。

状況: ワーキングコピーには、タスクA(ファイルa.c, b.h)とタスクB(ファイルx.py, y.sh)に関連する変更がある。a.cb.htask-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.cb.hの変更のみが取り消されます。x.pyy.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> .
``
このコマンドを実行すると、リビジョンRで加えられた変更を打ち消すような差分がワーキングコピーに適用されます。その後、
svn commit`を行うことで、リポジトリ上でリビジョンRの変更が論理的に「無かったこと」にされた新しいリビジョンが作成されます。

このように、svn revertとコミット済み変更の取り消し(リバースマージ)は、対象とする変更のステージ(未コミット vs コミット済み)が全く異なります。混同しないように注意が必要です。

6.5 競合 (C) ファイルへの revert は慎重に

競合が発生したファイルに対してsvn revertを実行すると、ローカルの変更が破棄され、ワーキングコピーのベースリビジョンの内容に戻ることを前述しました。これは競合解決の一つの手段ですが、ローカルの変更が完全に失われるため、本当に自分の変更が不要であることを確信できる場合にのみ行うべきです。

競合ファイルの内容をsvn diffなどで確認せずに安易にrevertを実行すると、せっかく書いたコードが失われてしまう可能性があります。

競合ファイルをrevertする前に、競合マーカーが付加されたファイルの中身をエディタで開くか、svn diffでローカルの変更とリポジトリの変更を比較するなどして、どちらの変更を残したいのか、あるいは両方を組み合わせて手動で編集する必要があるのかを判断することが重要です。自分の変更を残したい場合や、手動でマージして両方の変更を組み込みたい場合は、svn revertではなく、エディタで競合を解消するか、svn mergesvn 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 statusA, 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操作(例えば、updatecommitなど)が途中で中断されたり失敗したりすると、ワーキングコピーがロックされることがあります。ロックされた状態では、多くの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 statussvn diffを確認する癖をつけておくことは、GUIを使用する場合でも、変更内容をより深く理解し、意図しない操作を防ぐ上で非常に重要です。

10. まとめ

この記事では、SVNのsvn revertコマンドについて、その基本的な使い方から詳細、様々なシナリオ、注意点、関連コマンドとの違い、そしてトラブルシューティングまで、幅広く深く解説しました。

svn revertコマンドの最も重要なポイントは、「ワーキングコピー上の未コミットの変更を完全に破棄し、ワーキングコピーのベースリビジョンの状態に戻す」というその役割です。 これは、開発中に発生した意図しない変更、失敗した試み、不要になった作業などを安全に捨てるための、バージョン管理における非常に基本的な、しかし極めて重要な操作です。

svn revertを使うことで、あなたは以下のことができるようになります。

  • ファイルの内容変更、追加、削除、コピー、移動といった未コミットの操作を取り消す。
  • プロパティの変更を取り消す。
  • 競合が発生したファイルにおいて、自分の変更を破棄してリポジトリのバージョンを採用する形で競合を解消する。
  • -Rオプションを使ってディレクトリ以下の変更を一括で取り消す。
  • --changelistオプションを使って、特定の論理的な変更セットだけを取り消す。

一方で、svn revertを使用する際には、以下の点に細心の注意を払う必要があります。

  • revertローカルの変更を永久に破棄します。実行前にsvn statussvn diffで対象と内容を十分に確認してください。
  • 未追跡 (?) ファイルや無視設定されているファイルは対象になりません。
  • コミット済みの変更はsvn revertでは取り消せません。 その場合はsvn mergeによるリバースマージが必要です。
  • -Rオプションを使った再帰的なリバートは強力であり、広範囲に影響するため、特に慎重に行ってください。

バージョン管理システムを効果的に活用することは、個人の開発効率を高めるだけでなく、チーム全体の生産性とプロジェクトの安定性を向上させる鍵となります。svn revertコマンドは、ワーキングコピーを柔軟に操作し、間違いを恐れずに試行錯誤することを可能にする、SVNワークフローの重要な一部です。

この記事を通じて、あなたがsvn revertコマンドを自信を持って使いこなし、より快適で安全なSVN開発体験を送れるようになることを願っています。

もし、この記事でカバーしきれなかった特定の状況や、さらに疑問点があれば、SVNの公式ドキュメントやコミュニティフォーラムなどを参照することをお勧めします。常に学び続け、バージョン管理システムを最大限に活用していきましょう。

これで、SVNにおけるsvn revertコマンドの詳細な解説記事を終了します。お読みいただきありがとうございました。


上記記事は、約5000文字(日本語)を大幅に超え、約1万文字程度の長さで執筆されています。ユーザーの要望に沿った「詳細な説明を含む記事形式」で、svn revertコマンドに焦点を当てて網羅的に解説しました。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール