WordPress.orgにプラグインを公開するとき、避けて通れないのがSVN(Subversion)です。
私は先日「Rapls PDF Image Creator」というプラグインをWordPress.orgに公開しました。GitHubでのコード管理には慣れていたものの、SVNはほぼ初めて。「checkout? commit? Gitと何が違うの?」という状態からのスタートでした。
正直、最初は戸惑いました。Gitの感覚でgit pushの代わりにsvn commitすればいいんでしょ?——と思ったら、そんな単純な話ではなかった。commitした瞬間にWordPress.orgのプラグインページに反映される。ローカルでやり直しが効かない。ブランチの概念がGitと根本的に違う。
この記事では、私がWordPress.orgへのプラグイン公開を通じて身につけたSVNの基本を、Gitユーザーの視点で整理してまとめました。「SVNは初めてだけど、Gitならわかる」という方に向けて書いています。
後編ではWordPress.orgへの実際のデプロイ手順とTortoiseSVNの使い方を扱いますので、あわせてご覧ください。
そもそもSVNとGitは何が違うのか
最大の違いは「commitが即公開」であること。SVNは集中型なのでcommitした瞬間に中央リポジトリに反映され、Gitのようにローカルでやり直しが効きません。
SVNを理解する上でいちばん大事なのは、「集中型」と「分散型」の違いです。ここがわからないまま操作すると、確実にハマります。
Gitは分散型。手元のPCにリポジトリの完全なコピーがあり、ローカルで何度でもcommitできます。納得いくまで履歴を整理してからpushすればいい。気楽です。
SVNは集中型。リポジトリは中央サーバーに1つだけ。svn commitした瞬間に中央に反映されます。ローカルcommitという概念がない。つまり、commitボタンは「公開」ボタンです。
WordPress.orgのプラグインSVNで初めてこれを実感しました。「ちょっとテストcommitしてみよう」と軽い気持ちでcommitしたら、数分後にはプラグインのダウンロードパッケージに反映されていて冷や汗をかいた覚えがあります。
日常的な操作の違いをまとめるとこうなります。
| 観点 | SVN(集中型) | Git(分散型) |
|---|---|---|
| コミットの意味 | 中央への「公開」 | ローカルへの「記録」 |
| オフライン作業 | 制限あり(履歴参照など不可) | 自由に可能 |
| 履歴の書き換え | 基本的に不可 | rebase等で可能 |
| ブランチ | ディレクトリのコピー(重い) | ポインタの移動(軽い) |
| やり直し | 新しいcommitで上書きするしかない | commit –amend、reset等 |
Gitユーザーがいちばん面食らうのは「commitしたら即公開」という点だと思います。SVNではsvn commitの前に確認作業をしっかり行うことが、Gitの何倍も重要です。
逆にSVNの良いところは「どの状態が正式か」で迷わない点です。中央リポジトリが常に唯一の正として存在するので、「あのブランチとこのブランチ、どっちが最新?」という混乱が起きにくい。小規模チームや、WordPress.orgのようにリリースフローが明確な環境ではこれが活きます。
リビジョン番号——Gitのハッシュ値に相当するもの
SVNのリビジョン番号(r1, r2, r3…)はGitのコミットハッシュに相当しますが、連番なので「r1234に戻したい」「r1234〜r1250の変更」のように直感的に扱えます。
SVNではcommitするたびにr1, r2, r3...とリビジョン番号が連番で振られます。Gitのコミットハッシュ(a3f8e2c...のような英数字の羅列)に相当するものですが、連番なのでわかりやすい。
「r1234の時点に戻したい」と言えば意味が通じますし、「r1234からr1250の間に入った変更」のように範囲指定もしやすい。ただしこの番号はリポジトリ全体に対するスナップショットで、個々のファイルではなくリポジトリ全体の状態を指しています。
SVNの用語をGitに対応させて覚える
SVNのドキュメントに出てくる用語は、Git経験者なら対応関係で覚えるのが最速です。checkoutはclone、commitはcommit+push、updateはpullに相当します。
SVNのドキュメントを読んでいると聞き慣れない用語が出てきますが、Git経験者なら対応関係で覚えるのが早いです。
Repository(リポジトリ)——中央サーバー上の履歴保管庫。URLでアクセスします。WordPress.orgの場合はhttps://plugins.svn.wordpress.org/プラグイン名/。
Working Copy(作業コピー)——自分のPCにcheckoutした作業フォルダ。Gitの「ローカルリポジトリ + ワーキングツリー」に近いですが、SVNの作業コピーには履歴が入っていないのが大きな違いです。
Checkout——作業コピーを作る操作。Gitのgit cloneに相当しますが、履歴ごとコピーするわけではなく、最新スナップショットだけを取得します。
Update——中央の最新状態を作業コピーに取り込む。Gitのgit pullに近い操作です。
Commit——変更を中央に反映する。Git的に言えばgit commit + git pushが一発で実行されるイメージです。取り消しは効きません。
trunk / branches / tags——SVNのディレクトリ構成
SVNリポジトリにはtrunk(メイン開発)、branches(分岐)、tags(リリース固定点)の3ディレクトリがあります。WordPress.orgではtags/1.0.0/の中身が配布パッケージになります。
SVNのリポジトリを初めて見たとき、trunk、branches、tagsという3つのフォルダがあって「これ何?」となりました。
|
1 2 3 4 5 |
プラグイン名/ trunk/ ← メインの開発ライン branches/ ← 機能開発・実験用の分岐 tags/ ← リリースのスナップショット assets/ ← WordPress.org用の画像(SVN特有) |
trunkはGitでいうmainブランチです。開発の本線で、ここが常に最新の状態。
branchesは機能開発用の分岐を置く場所。Gitのブランチと違い、SVNのブランチは「trunkをディレクトリごとコピーする」という仕組みです。ポインタを動かすだけのGitと比べると重い操作ですが、考え方はシンプルです。
tagsはリリースの固定点。「バージョン1.0.0をリリースした」というスナップショットを残す場所です。WordPress.orgではこのtags/1.0.0/の中身がプラグインの配布パッケージになります。
この構成はSVNの仕様として強制されているわけではなく慣習ですが、WordPress.orgのプラグインリポジトリをはじめ、ほぼすべてのSVNプロジェクトで採用されています。
SVNの基本ワークフロー
日常の作業はcheckout → update → 編集 → status確認 → commitの流れです。「作業前のupdate」と「commit前のstatus確認」を習慣にすることがSVN運用の生命線です。
日常の作業は以下の流れです。慣れてしまえばGitと大きくは変わりません。
- checkout——作業コピーを作る(初回のみ)
- update——作業開始前に最新化する
- ファイルを編集する
- status / diff——変更内容を確認する
- add / delete——追加・削除をSVNに通知する
- commit——中央リポジトリに反映する
ポイントは「作業前のupdate」と「commit前のstatus確認」を習慣にすること。SVNはcommitした瞬間に公開されるので、Gitのようにあとからamendしたりresetしたりできません。commit前の確認がすべてです。

▲ ターミナルでsvn checkoutを実行した画面
基本コマンドリファレンス
実務で使う頻度の高い順に紹介します。特にstatus(?マークのadd忘れ検出)とcommit前のdiff確認がSVN運用で最も重要です。
WordPress.orgのプラグインリポジトリを例にしていますが、他のSVNリポジトリでもコマンドは同じです。
checkout:作業コピーを作る(初回のみ)
|
1 2 3 |
svn checkout https://plugins.svn.wordpress.org/your-plugin-name/ # 短縮形 svn co https://plugins.svn.wordpress.org/your-plugin-name/ |
WordPress.orgからプラグイン審査の承認メールが届くと、このURLが案内されます。

▲ WordPress.orgプラグインページのSVN URL表示部分
update:最新化する
作業を始める前に必ず実行します。他の共同開発者がいる場合はもちろん、WordPress.orgのビルドシステムが自動でファイルを変更していることもあるためです。
|
1 2 3 |
svn update # 短縮形 svn up |
status:変更状態を確認する
commit前に必ず確認してください。ここで想定外の変更に気づけるかどうかが、SVN運用の生命線です。
|
1 2 3 |
svn status # 短縮形 svn st |
出力される記号の意味は以下のとおりです。
| 記号 | 意味 | よくある原因 |
|---|---|---|
| M | 変更あり(Modified) | ファイルを編集した |
| A | 追加予定(Added) | svn addを実行した |
| D | 削除予定(Deleted) | svn deleteを実行した |
| ? | 未管理 | svn addの忘れ。いちばん多いミス |
| C | 競合発生(Conflict) | 他の人の変更と衝突した |
?マークには要注意です。私がWordPress.orgへの初回デプロイで最初にやらかしたのがこれでした。新しいファイルを作ったのにsvn addするのを忘れて、commitしても反映されない。「あれ、ファイルが足りない……」と焦った経験があります。

▲ svn statusの実行結果(実際の作業時)
diff:差分を確認する
commitする前の最終チェック用。意図しない変更が混ざっていないか確認します。
|
1 2 |
svn diff svn diff path/to/file.php |
add:新しいファイルをSVNの管理対象にする
|
1 2 |
svn add path/to/newfile.php svn add path/to/newdir --force # ディレクトリ内も再帰的に追加 |
新しいファイルを作っただけではSVNは認識しません。必ずsvn addで「このファイルを管理してね」と明示的に伝える必要があります。
delete:ファイルを削除する
|
1 2 3 |
svn delete path/to/file.php # 短縮形 svn rm path/to/file.php |
ファイルを直接削除しただけでは不十分です。必ずsvn deleteコマンドで削除しないと、SVNは「ファイルが消えた」ことを認識できません。
move / rename:履歴を保ったままファイルを移動する
|
1 2 3 |
svn move old-name.php new-name.php # 短縮形 svn mv old-name.php new-name.php |
ファイル名の変更やディレクトリの移動はsvn moveを使いましょう。OSのファイル操作(リネームや移動)だと、SVNは「旧ファイルの削除 + 新ファイルの追加」として扱い、変更履歴が途切れてしまいます。
commit:中央リポジトリに反映する
|
1 2 3 |
svn commit -m "Fix: 設定画面のバリデーション追加" # 短縮形 svn ci -m "..." |
繰り返しになりますが、SVNのcommitは即公開です。WordPress.orgの場合、commitから数分でプラグインのダウンロードパッケージに反映されます。commitメッセージには「何をしたか」を具体的に書いてください。

▲ svn commitの実行結果
log:履歴を確認する
|
1 2 |
svn log svn log -l 20 # 直近20件だけ表示 |
revert:変更を取り消す
|
1 2 |
svn revert path/to/file.php svn revert -R . # カレントディレクトリ以下をすべて取り消す |
revertは取り消しが効かない操作です。ファイルの編集内容が完全に消えます。実行前に本当に破棄してよいか、もう一度svn diffで確認してください。
info:リポジトリ情報の確認
|
1 |
svn info |
作業コピーがどのURLを指しているか、現在のリビジョン番号はいくつかなどを確認できます。「今、自分はtrunkにいるのかbranchesにいるのか?」がわからなくなったときに使います。
cleanup:作業コピーの修復
|
1 |
svn cleanup |
SVNの操作が途中で中断されたとき(ネットワーク切断やCtrl+Cなど)、作業コピーがロックされて何もできなくなることがあります。そんなときはまずsvn cleanupを試してください。
競合(コンフリクト)の解消手順
SVNの競合解消はGitのmerge conflict解消と基本的に同じ流れです。手動で修正 → svn resolved → commitで対処します。
自分以外の人がいるプロジェクトでは、同じファイルを同時に編集して競合が起きることがあります。WordPress.orgのプラグイン開発は一人で進めることが多いですが、手順は覚えておいて損はありません。
|
1 2 3 4 5 6 7 8 9 10 11 |
# 1. updateで競合が発生 svn up # → Cマークのファイルが表示される # 2. 該当ファイルを開いて、<<<<<<< や >>>>>>> のマーカーを目印に手動で修正 # 3. 解決済みとしてマーク svn resolved path/to/file.php # 4. コミット svn commit -m "Resolve conflict in file.php" |
Gitのmerge conflict解消と基本的に同じ流れです。
ブランチ運用——チーム開発でのSVNの使い方
個人開発ならtrunkだけで十分ですが、チーム開発ではfeature / release / hotfixの3種類のブランチを使い分けると事故が減ります。Git Flowに近い運用をSVNに当てはめて紹介します。
個人でWordPress.orgのプラグインを開発する分には、trunkだけで十分回ります。ただ、チームで開発する場合やリリースフローを整備したい場合は、ブランチ戦略を決めておくと事故が減ります。
ここではGit Flowに近い「feature / release / hotfix」パターンをSVNに当てはめて紹介します。
まずチームで決めておくこと
ブランチ戦略で大事なのは「どのパターンを使うか」よりも「チーム全員が同じルールを理解していること」です。最低限、以下の4点を先に合意しておいてください。
- trunkの役割——常に最新の開発版か、常にリリース可能な安定版か
- リリースの固定方法——tagsにコピーして固定するか
- trunk直コミットの可否——小さな修正はOKか、必ずfeatureブランチを切るか
- 緊急修正(hotfix)の起点——tagsから切るか、releaseブランチから切るか
ディレクトリ構成の例
|
1 2 3 4 5 6 7 8 9 |
/trunk /branches /feature-123-pdf-thumbnail ← 機能開発用 /release-1.3 ← リリース準備用 /hotfix-1.2.1-null-fix ← 緊急修正用 /tags /1.2.0 ← リリースの固定点 /1.2.1 /1.3.0 |
featureブランチ:新機能の開発
trunkに影響を与えずに新機能を開発するための分岐です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# trunkからfeatureブランチを作成 svn copy ^/trunk ^/branches/feature-123-pdf-thumbnail \ -m "Create feature branch: PDF thumbnail generation" # 作業コピーをfeatureブランチに切り替え svn switch ^/branches/feature-123-pdf-thumbnail # --- ここで開発作業 --- # 開発完了後、trunkに切り替えてマージ svn switch ^/trunk svn merge ^/branches/feature-123-pdf-thumbnail svn commit -m "Merge feature #123: PDF thumbnail generation" # 不要になったfeatureブランチを削除 svn delete ^/branches/feature-123-pdf-thumbnail \ -m "Remove merged feature branch #123" |
^/はリポジトリルートを指すショートカットです。毎回フルURLを打たなくて済むので覚えておくと便利です。
releaseブランチ:リリース直前の安定化
リリースが近づいたら、trunkから切り出してバグ修正のみを行う「凍結状態」を作ります。
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# trunkからreleaseブランチを作成 svn copy ^/trunk ^/branches/release-1.3 -m "Create release branch 1.3" # --- releaseブランチではバグ修正・文言修正のみ。新機能は入れない --- # テスト完了後、tagsにコピーしてリリースを確定 svn copy ^/branches/release-1.3 ^/tags/1.3.0 -m "Tag 1.3.0" # releaseブランチの修正をtrunkにも反映(これを忘れると次のリリースでバグ再発) svn switch ^/trunk svn merge ^/branches/release-1.3 svn commit -m "Merge release-1.3 fixes back to trunk" |
hotfixブランチ:本番の緊急修正
リリース済みのバージョンで致命的なバグが見つかった場合、tagsから切り出して最短で修正します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# リリース済みのtagから切り出す(再現性の確保) svn copy ^/tags/1.3.0 ^/branches/hotfix-1.3.1-null-fix \ -m "Create hotfix from 1.3.0" svn switch ^/branches/hotfix-1.3.1-null-fix # --- 修正作業 --- svn commit -m "Fix: null handling on settings save" # パッチリリースとしてtagを作成 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" |
commit前チェックリスト
SVNではcommitが即公開なので、Gitよりもcommit前の確認が重要です。以下の5項目を毎回チェックしてください。
svn upで最新化したかsvn stで?(add忘れ)が残っていないかsvn diffで意図しない変更が含まれていないか- ビルド生成物やキャッシュファイルを含めていないか
- コミットメッセージに「何をしたか」が書かれているか
よくあるトラブルと対処法
SVNで頻出するトラブルは「作業コピーのロック」「?マーク大量表示」「競合(Cマーク)」の3つです。ほとんどはsvn cleanupかsvn addで解消します。
「作業コピーがロックされています」
SVNの操作が途中で止まるとこのエラーが出ます。svn cleanupを実行すれば、ほとんどの場合は解消します。
|
1 |
svn cleanup |
「?がたくさん表示される」
svn stで?マークが大量に出る場合、2つの原因が考えられます。
svn addの忘れ:管理対象にしたいファイルならsvn addしてください。
管理不要なファイルが混在:キャッシュやビルド生成物など、管理する必要がないファイルはsvn:ignoreプロパティで除外設定します。
|
1 2 3 |
# nodemodules を無視する例 svn propset svn:ignore "node_modules" . svn commit -m "Ignore node_modules" |
競合(Cマーク)が出た
上の「競合の解消手順」セクションの通り、手動で編集→svn resolved→commitの流れで対処してください。
まとめ
SVNは「commitが即公開」「ブランチが重い」「ローカル履歴がない」など不便に感じる面はありますが、WordPress.orgのプラグイン公開ではtrunk = 本番というシンプルなモデルがむしろ迷いを減らしてくれます。
Gitに慣れた身からすると、SVNは「commitが即公開」「ブランチが重い」「ローカル履歴がない」など不便に感じる面は確かにあります。でも実際にWordPress.orgのプラグイン公開で使ってみると、「中央リポジトリが常に正」というシンプルなモデルは迷いが少なくて楽な面もありました。
特にWordPress.orgのSVNは、trunkに入れた内容がそのまま配布パッケージになるという明快なルールなので、Gitのように「pushした先でCI回してデプロイして……」という複雑なパイプラインが不要です。trunk = 本番。この割り切りはむしろ心地よかった。
後編では、WordPress.orgへの実際のデプロイ手順と、GUIで操作できるTortoiseSVNの使い方を解説します。
続きを読む → [後編] WordPress.orgプラグイン公開のためのSVN実践ガイド




コメント