ローカルでのコミットを1つにまとめてSubversionにコミットする方法

個人のリポジトリならいいんですが、共有しているリポジトリではコミットはある程度"意味のある単位"で行った方が親切です。
「もう帰るけど作業は途中。とりあえずコミット」をされて、そうとは知らずに、中途半端な動かないソースでアップデートしちゃったもんだからアプリが動かないとか悲しすぎます。

だから、ローカルに自分専用のミラー(ローカルリポジトリ)を作成し、そこにはガンガンコミットしておいて、タスクが終わったらまとめてサーバー側にコミットするという作業に意味があります。

また、ネットワークにつながっていなくてもガッツリと開発が行うことができるのも魅力です。

イメージとしては以下のような感じです。

<これまでの管理>
コミット => (サーバーのリポジトリ)

<分散管理>
コミット => (ローカルのリポジトリ) => コミット => (サーバーのリポジトリ)

ツールとしては分散リビジョンシステムとして有名な svkとgitがあります。
これらを使ってSubversionリポジトリに綺麗にコミット?する方法をメモ。

インストール

ローカルの環境はmacbookです。基本portで管理してるのですが、SVNPerlのライブラリでエラーがでてしまうので、それぞれdmgからインストールしました。

svk

以下のサイトで勉強し参考にさせていただきました。
ref: http://mono.kmc.gr.jp/~yhara/w/?SvkTutorial

構成

構成は以下のとおり。ローカルにミラーを作ります。
サーバーとミラーを同期とるのがsync。ミラーからブランチに更新内容をとってくるのがpull。あとはsvnのときと同じでupdateで更新。
また、最後のまとめてコミット(smerge or push)はローカルのミラーに対して行えばよく、通常はローカルのブランチにコミット(commit)を繰り返します。

つまり、ブランチに行う作業はSubversionの管理となんらかわりません。
サーバー側と同期をとったり、まとめてコミットする部分(sync, pull, smerge, push)を理解すれば良いということになります。

svn+ssh://hogehoge@example.com/home/svn/repos/prj/trunk (サーバー側本番)
 ↓(sync)     ↑
//mirror/prj/trunk (ローカルのミラー)
 ↓(pull)     ↑(svk smerge)(svk push -l --verbatim)
//prj/branches/hogehoge (ローカルの作業用ブランチ)
 ↓(update)    ↑(svk commit)
準備
  • svkの初期化
$ svk depotmap --init
  • ミラー(//mirror/prj/trunk)の準備
$ svk mirror //mirror/prj/trunk svn+ssh://hogehoge@example.com/home/svn/repos/prj/trunk
  • ミラーをサーバーと同期させる
$ svk sync //mirror/prj/trunk
  • 作業用のブランチ(//prj/branches/user)を作る
$ svk copy -p //mirror/prj/trunk //prj/branches/hogehoge
  • ブランチ(//prj/branches/hogehoge)から作業領域(/Users/hogehoge/prj)にcoする
$ svk co //prj/branches/hogehoge /Users/hogehoge/prj
通常作業
  • ミラーとブランチを最新の状態にする
$ svk sync //mirror/prj/trunk
$ svk pull //prj/branches/hogehoge
  • 作業領域を最新の状態にアップデートする
$ svk update
  • ブランチにコミット
$ svk ci -m "commit!"
まとめてコミット

smergeかpushで行う。詳しくは svk helpで。
コメントをつける事ができるsmergeのほうが便利?

  • smerge (sm)
$ svk sm //prj/branches/hogehoge //mirror/prj/trunk -m 'new commit log'
  • push
$ svk push -l --verbatim //prj/branches/hogehoge

git

以下のサイトで勉強し参考にさせていただきました。
ref: http://www8.atwiki.jp/git_jp/pub/Documentation.ja/user-manual.html#id2544723

構成

構成は以下のとおり。
SVKと同じようにローカルに環境を作りますが、svkではミラーと呼んでいたものがgitの場合はgitへ変換されたローカルのmasterという名前のブランチになる点でが異なります。
そして作業用のブランチを作成する点は同じです。

svn+ssh://hogehoge@example.com/home/svn/repos/prj/trunk (サーバー側本番)
 ↓(svn clone)     ↑(svn dcommit)
//master (ローカルのマスターブランチ)
 ↓(branch branch-git)↑(merge --squash, commit)
//branch-git (ローカルの作業用ブランチ)
 ↓(svn rebase)    ↑(add)
準備
  • gitの初期化(masterブランチの作成)
$ git svn clone svn+ssh://hogehoge@example.com/home/svn/prj/trunk /Users/hogehoge/prj
  • 作業用のブランチ(branch-git)を作る
$ git branch branch-git
  • 作業用のブランチ(branch-git)に移動
$ git checkout branch-git
( git branch で現在使用中のブランチに*マークがつく )
通常作業
  • 作業用ブランチを最新の状態にアップデートする
$ git svn rebase
  • 更新通知(add)と作業用ブランチ(commit)にコミット
$ git add .
$ git commit
まとめてコミット

マスターのブランチに移動し、マージ処理とローカルへのコミット、Subversionへのコミットを行う

  • マスターのブランチに移動
$ git checkout master
  • マスターのブランチに戻り作業ブランチ(branch-git)をマージ(merge)する
$ git merge --squash branch-git
  • ローカルへのコミット(commit)とサーバーへのコミット(svn dcommit)
$ git commit
$ git svn dcommit
  • 不要になったブランチ(branch-git)の削除
$ git branch -d branch-git

感想

慣れているツールを使うのが一番ですが、gitのほうがシンプルな印象を受けました。
ただし、Subversionと連携させたいという目的から考えるとsvkのほうが相性はいいかもしれません。