「Gitは使えるけど、SVNは触ったことがない」
そんなエンジニアが増えています。GitHubやGitLabが主流となった今、SVNに触れる機会は確かに減りました。しかし、WordPress.orgのプラグイン配布、エンタープライズ環境のレガシーシステム、一部の大規模プロジェクトでは、今もSVNが現役で使われています。
この記事では、SVNの基本概念から実践的なブランチ戦略まで、Gitユーザーの視点で体系的に解説します。後編ではWordPress.orgへのプラグイン公開手順とTortoiseSVNの使い方を扱いますので、あわせてご覧ください。
SVNとは何か
SVN(Subversion)は、ソースコードやドキュメントの変更履歴を管理するバージョン管理システムです。2000年にCVS(Concurrent Versions System)の後継として開発され、長らく業界標準として使われてきました。
SVNを一言で表すなら「中央にあるリポジトリが正史」というモデルです。すべての開発者は中央サーバーにあるリポジトリに対して更新(update)と反映(commit)を行います。この「集中型」という特性が、GitとSVNの最大の違いであり、運用感が大きく異なるポイントです。
集中型と分散型:SVNとGitの根本的な違い
バージョン管理システムは大きく「集中型(Centralized)」と「分散型(Distributed)」に分かれます。
SVNは集中型です。1つの「中央リポジトリ」だけが正式な履歴を持ち、開発者はそこから「作業コピー(Working Copy)」を取得して作業します。コミットすれば即座に中央に反映され、他の開発者もその変更を参照できます。
Gitは分散型です。各開発者のローカルマシンに完全なリポジトリのクローンがあり、ローカルでコミットを重ねてから、必要なタイミングでリモートにpushします。
この違いは、日常の開発フローに大きな影響を与えます。
| 観点 | SVN(集中型) | Git(分散型) |
|---|---|---|
| コミットの意味 | 中央への「公開」 | ローカルへの「記録」 |
| オフライン作業 | 制限あり | 自由に可能 |
| 履歴の書き換え | 基本的に不可 | rebase等で可能 |
| ブランチ | 重め(ディレクトリコピー) | 軽量(ポインタ移動のみ) |
Gitが便利とされる理由の多くは「ローカルで履歴を操作できる」点にあります。一方でSVNは中央が常に正なので、「どの状態が正式か」が常に明確であり、運用ルールがシンプルになりやすいというメリットがあります。
リビジョン番号という世界観
SVNでは、コミットするたびに r1, r2, r3... というリビジョン番号が自動的に振られます。この番号は特定のファイルではなく、リポジトリ全体の状態(スナップショット)に対して付与されます。
「r1234の時点に戻したい」と言えば、リポジトリ全体をその状態に復元できます。これはGitのコミットハッシュと似ていますが、連番で分かりやすいという利点があります。
SVNの基本用語
SVNを使う上で押さえておくべき用語を整理します。
Repository(リポジトリ) — 履歴を保存する本体。URLでアクセスします(例:https://svn.example.com/project)。
Working Copy(作業コピー) — 自分のPC上にチェックアウトした作業フォルダ。この中で編集作業を行います。
Revision(リビジョン) — コミットごとに増える番号。r102のように表記します。
Commit(コミット) — 変更を中央リポジトリに反映し、新しいリビジョンを作成する操作。
Update(更新) — 中央リポジトリの最新状態を作業コピーに取り込む操作。
Checkout(チェックアウト) — リポジトリから作業コピーを作成する操作(初回のみ)。
trunk / branches / tags:SVNのディレクトリ構成
SVNには「ブランチ」という概念がGitほど軽量ではありません。代わりに、ディレクトリをコピーして分岐を作るという発想で運用します。
慣習として、以下の3つのディレクトリ構成が広く使われています。
repo/
trunk/
branches/
tags/
trunk — メインの開発ライン。Gitでいうmainやmasterに相当します。
branches — 機能開発や実験用の分岐を格納するディレクトリ。
tags — リリースのスナップショット。「このバージョンを出荷した」という固定点を記録します。
この構成は強制ではなく慣習ですが、ほとんどのSVNプロジェクトで採用されており、WordPress.orgのプラグインリポジトリもこの形式です。
SVNの基本ワークフロー
SVNでの作業は、基本的に以下の流れで進みます。
- checkout — 作業コピーを作成(初回のみ)
- update — 作業開始前に最新化
- ファイルを編集
- status / diff — 変更内容を確認
- add / delete / move — 追加・削除・移動をSVNに通知
- commit — 中央リポジトリへ反映
この流れを守れば、ほとんどのトラブルを回避できます。特に「作業前のupdate」と「コミット前のstatus確認」は習慣づけてください。
基本コマンドリファレンス
ここでは、実務で頻繁に使うコマンドを使用頻度順に紹介します。
checkout:作業コピーを作る(初回)
svn checkout https://example.com/svn/project/trunk
# 短縮形
svn co https://example.com/svn/project/trunk
update:最新化する
作業を始める前、コミットする前に必ず実行します。
svn update
# 短縮形
svn up
status:変更状態を確認する
svn status
# 短縮形
svn st
出力される記号の意味は以下の通りです。
| 記号 | 意味 |
|---|---|
| M | 変更あり(Modified) |
| A | 追加予定(Added) |
| D | 削除予定(Deleted) |
| ? | 未管理(add忘れ) |
| C | 競合発生(Conflict) |
diff:差分を確認する
コミット前の最終確認に使います。
svn diff
svn diff path/to/file.php
add:新規ファイルを管理対象に追加
svn add path/to/newfile.php
svn add path/to/dir --force
--forceオプションを付けると、ディレクトリ内のファイルも再帰的に追加されます。
delete:ファイルを削除
svn delete path/to/file.php
# 短縮形
svn rm path/to/file.php
ファイルシステム上の削除だけでなく、SVNにも削除を通知する必要があります。
move / rename:履歴を保って移動
svn move old.php new.php
# 短縮形
svn mv old.php new.php
単にファイル名を変更するのではなく、svn moveを使うことで履歴が引き継がれます。
commit:中央へ反映
svn commit -m "Fix: validate input on settings page"
# 短縮形
svn ci -m "..."
log:履歴を確認
svn log
svn log -l 20 # 直近20件
revert:変更を取り消す
svn revert path/to/file.php
svn revert -R . # カレントディレクトリ以下すべて
注意:revertは取り消しが効きません。実行前に本当に破棄してよいか確認してください。
info:リポジトリ情報を表示
svn info
現在の作業コピーが指しているURL、リビジョン番号などを確認できます。
cleanup:作業コピーの修復
作業コピーがロックされたり、不整合が起きた場合に使います。
svn cleanup
競合の解決
競合(Conflict)が発生した場合の対処手順です。
# 1. 状況確認
svn st
# 2. 該当ファイルを手動で編集し、競合を解消
# 3. 解決済みとしてマーク
svn resolved path/to/file.php
# 4. コミット
svn commit -m "Resolve conflict in file.php"
SVNのブランチ戦略
チーム開発では、ブランチ戦略を事前に決めておくことが重要です。ここでは、SVNで実践的に使える「feature / release / hotfix」パターンを紹介します。
最初に決めるべきルール
ブランチ戦略を導入する前に、チームで以下を合意しておきます。
- trunkには何を置くか? — 常に最新の開発版か、常にリリース可能な安定版か
- リリースはtagsに固定するか? — 基本的にはYES
- hotfixはどこから切るか? — tagsから切る(再現性が高い)か、releaseブランチから切るか
- trunk直コミットを許す範囲は? — 小さな修正はOKか、必ずfeatureブランチを切るか
正解は一つではありません。「チームが迷わない」ことが最優先です。
ディレクトリ構成テンプレート
以下の構成をおすすめします。
/trunk
/branches
/feature-<ticket>-<short>
/release-<major>.<minor>
/hotfix-<version>-<short>
/tags
/<version>
命名例:
- feature:
feature-123-login-rate-limit - release:
release-1.3 - hotfix:
hotfix-1.2.1-null-fix - tag:
1.2.0(セマンティックバージョニング推奨)
featureブランチ:機能開発用
新機能をtrunkから切り離して安全に開発するためのブランチです。
ブランチの作成
svn copy ^/trunk ^/branches/feature-123-login-rate-limit -m "Create feature branch #123"
^/はリポジトリルートへのショートカットです。
作業コピーの切り替え
svn switch ^/branches/feature-123-login-rate-limit
trunkへのマージ
開発が完了したら、trunkの作業コピーに移動し、featureブランチの差分を取り込みます。
# trunkに切り替え
svn switch ^/trunk
# featureブランチをマージ
svn merge ^/branches/feature-123-login-rate-limit
# 確認
svn st
svn diff
# コミット
svn commit -m "Merge feature #123: login rate limit"
ブランチの削除
マージ後、不要になったブランチは削除します。
svn delete ^/branches/feature-123-login-rate-limit -m "Remove merged feature branch #123"
releaseブランチ:リリース準備用
リリース直前の「凍結状態」を作り、バグ修正のみを安全に行うためのブランチです。
いつ切るか
リリースが1〜2週間後に見えてきたタイミングで、trunkから切り出します。
svn copy ^/trunk ^/branches/release-1.3 -m "Create release branch 1.3"
releaseブランチでやること
- ✅ バグ修正
- ✅ 文言修正
- ✅ ドキュメント修正
- ❌ 新機能の追加(原則禁止)
リリース確定:tagsへ固定
テストが完了したら、tagsにコピーしてリリースを確定します。
svn copy ^/branches/release-1.3 ^/tags/1.3.0 -m "Tag 1.3.0"
trunkへの反映
releaseブランチで行ったバグ修正は、trunkにも戻す必要があります。これを忘れると、次のリリースで同じバグが復活します。
svn switch ^/trunk
svn merge ^/branches/release-1.3
svn commit -m "Sync: merge release-1.3 fixes back to trunk"
hotfixブランチ:緊急修正用
本番環境で致命的な不具合が発覚した場合に、最短でパッチをリリースするためのブランチです。
tagsからの切り出しを推奨
再現性を確保するため、リリース済みのtagsから切り出すことをおすすめします。
svn copy ^/tags/1.3.0 ^/branches/hotfix-1.3.1-null-fix -m "Create hotfix branch from 1.3.0"
svn switch ^/branches/hotfix-1.3.1-null-fix
修正とリリース
# 修正を加えてコミット
svn commit -m "Fix: null handling on settings save"
# パッチリリースとしてタグを切る
svn copy ^/branches/hotfix-1.3.1-null-fix ^/tags/1.3.1 -m "Tag 1.3.1 hotfix"
trunkへの反映を忘れずに
svn switch ^/trunk
svn merge ^/branches/hotfix-1.3.1-null-fix
svn commit -m "Merge hotfix 1.3.1 back to trunk"
運用ルールのテンプレート
チームで共有できる運用ルールをまとめます。
- trunkは「次リリース候補」とし、常に動作する状態を維持する
- featureは必ず
branches/feature-*に作成する(trunk直コミットは例外のみ許可) - releaseブランチは凍結状態とし、バグ修正と文言修正のみ許可
- リリース時は必ず
tags/<version>を作成して固定する - hotfixは
tagsから切り出し、修正後に新しいtagsを作成する - release/hotfixで入れた修正は、必ずtrunkにもマージする
コミットメッセージ例
Fix: sanitize option values
Add: support RTL banner
Docs: update readme for 1.3.0
Merge: feature #123
Tag: 1.3.0
コミット前チェックリスト
コミットする前に、以下を確認する習慣をつけてください。
svn upで最新化したかsvn stで?(add忘れ)がないかsvn diffで想定外の変更がないか- 不要ファイル(ビルド生成物、キャッシュ)を含めていないか
- コミットメッセージは「何をしたか」が明確か
よくあるトラブルと対処法
「作業コピーがロックされています」
svn cleanup
「?がたくさん出る」
svn addのし忘れか、不要な生成物が混ざっています。必要なものだけaddし、不要なものはsvn:ignoreプロパティで除外設定をしてください。
競合(C)が発生
svn stで競合ファイルを確認- 手動で編集して解消
svn resolvedで解決済みをマーク- コミット
まとめ
SVNは「集中型」のバージョン管理システムであり、Gitとは異なる運用感があります。中央リポジトリが正史となるシンプルなモデルは、明確なルールを設けやすく、特定の環境では今も有効な選択肢です。
次回の後編では、WordPress.orgへのプラグイン公開手順と、Windows向けGUIクライアント「TortoiseSVN」の使い方を詳しく解説します。
続きを読む → [後編] WordPress.orgプラグイン公開のためのSVN実践ガイド



コメント