Reference

基本的な使い方

リポジトリの作成

repos=リポジトリを作るdirectory。 例えば

repos=/home/usrname/workspace/svn/cmb

とか(例:cmbプロジェクト)。リポジトリの作成:

mkdir -p ${repos}
svnadmin create ${repos}
ls ${repos}
README.txt conf dav db format hooks locks

標準directory(trunk, tags, branchesそれぞれの意味)の作成:

svn mkdir file:///${repos}/trunk -m "make trunk"
svn mkdir file:///${repos}/tags -m "make tags"
svn mkdir file:///${repos}/branches -m "make branches"

リポジトリに(ソースを)インポートする

ls tmp/
hoge.cc
svn import tmp file:///${repos}/trunk -m "import tmp/"

tmpの中にあるhoge.ccを、リポジトリのtrunkにインポートする。

リポジトリからcheck outし、開発を始める

work=作業を行なうdirectory。 例えば

work=/home/usrname/workspace/cmb

とか。リポジトリからcheck outする:

mkdir -p ${work}
cd ${work}
svn co file:///${repos}/trunk
ls
trunk
ls trunk
hoge.cc

statusの確認

cd trunk
ls
hoge.cc
svn status

編集/commit

hoge.ccを編集。その後commit

svn commit -m "add new function" hoge.cc

コマンド

参考

[svnadmin create] リポジトリの作成

mkdir -p /PATH/repos
svnadmin create /PATH/repos

最初だけに行なう。

[svn import] リポジトリにモジュールをインポートする

ls
myproject
svn import myproject file:///PATH/repos/

[svn list] リポジトリにどんなディレクトリがあるかを表示する

svn list file://PTAH/repos

コマンドはローカルマシンに 実際にファイルをダウンロードすることなしに、リポジトリ にどんなディレクトリがあるかを表示する。

[svn checkout][svn co] リポジトリから作業コピーをとってくる(始めの一回)

svn checkout file:///PATH/repos/trunk
ls
trunk

名前を指定する場合:

svn checkout file:///PATH/repos/trunk work
ls
work

[svn status] 作業コピーの状態

svn status

作業コピーに加えられた変更点を検出。 引数なしで実行するとツリー全体の変更が検出。

[svn log] 履歴の確認

svn log

ファイルやディレクトリの履歴に関する情報を得る。

svn log [file OR directory]

And

svn log --diff

is equivalent of "git log -p"

[svn update][svn up] 作業コピーの更新

svn update

[svn diff][svn di] 変更点の差分を見る

svn diff

svn diff は .svn 領域にある「修正元リビジョンのコピー」に対して作業コピー中のファイルとの比較を行う。

日本語への対応
ラッパーで回避
#!/usr/bin/perl -w

use strict;

my $c = '/usr/bin/svn';
foreach (@ARGV)
{
        $c .= " $_";
}

if ($c =~ /^[^\s]+\s+diff/)
{
        # svn diff の出力のみ nkf で euc/unix に統一する。
        print `$c | nkf --unix --euc`;
}
else
{
        print `$c`;
}

参考にしたサイト

[svn switch] repositoryの場所を変更する

repositoryの場所を変更する:

svn relocate TO-URL [PATH]

OR

svn switch --relocate FROM TO [PATH...]
  • If the working copy needs to reflect a new directory within the repository, use svn switch.
  • If the working copy still reflects the same repository directory, but the location of the repository itself has changed, use svn relocate.

ツリーの変更

ファイルやディレクトリを削除 / 追加 / コピー / 移動する場合には、まず add/delete/copy/move などのコマンドを用いて「マーク」を設定する。 しかるのち commit コマンドを実行し、変更をリポジトリに反映させるという手順が必要である。

[svn add] ファイルやディレクトリを新たにリポジトリに登録する

svn add [file OR directory]
svn add testdir
A         testdir
A         testdir/a
A         testdir/b
A         testdir/c
A         testdir/d

ディレクトリを追加する際、svn add のデフォルト動作は再帰的である。 内部にあるファイルを追加せずに、ディレクトリのみを追加する場合:

svn add --non-recursive testdir
A         testdir

[svn mkdir] directoryの作成

svn mkdir /PATH/repos/trunk -m "make tunk"
mkdir hoge
svn add hoge

[svn commit][svn ci] 設定を反映させる

svn commit -m "add hoge.cc" hoge.cc

[svn delete][svn del][svn remove][svn rm] アイテムの削除

svn delete [file OR directory]

通常ファイルまたはシンボリックリンクの場合は、 作業コピーから直ちに削除される。 ディレクトリの場合は削除されないが、 Subversionはそれを削除予告の状態に設定する。 変更をコミットすると、作業コピーとリポジトリから削除される。

ディレクトリを削除するためには、 あらかじめそのディレクトリに含まれるファイルを削除し、 ディレクトリを空にしておく必要がある。

[svn delete][svn del][svn remove][svn rm] ローカルのファイルを残したままアイテムの削除

svn delete --keep-local [file OR directory]

[svn copy][svn cp] アイテムのコピー

svn copy foo bar

bar が次のコミットでリポジトリに追加される時点でコピーの履歴が記録される (それが foo のコピーであるという履歴)。

[svn move] アイテムの移動

svn move foo bar

これは以下のコマンドを実行することとまったく同等である。

svn copy foo bar
svn delete foo

(当然だが、コミットしないと反映されない。)

[svn revert] addしたファイルやディレクトリをcommitする前に取り消す

svn revert [file OR directory]

Subversion は指定されたファイルを .svn 領域にある「修正元リビジョン」のコピーで上書きすることよって修正以前の状態に戻す。 svn revert コマンドはどのような予告操作も取り消すことに注意すること。

ディレクトリに対して誤ってaddしてしまった場合:

svn revert --depth infinity dir_target

以前のリビジョンに戻す

[svn up] 一時的に昔のリビジョンに戻す

svn up -r 123 // リビジョン123に戻す
svn up        // 最新版に戻す

[svn cat] 以前のリビジョンを見る

svn cat --revision 2 hoge.cc > hoge.cc.v2

[svn merge] 以前のリビジョンに戻す

反対向きの差分を指定して作業コピーの変更を「取り消す」ことができる。 以下はリビジョン 303 を破棄して 302 に戻す例。

svn merge -r 303:302 svn+ssh://hoge.com/workspace
svn commit -m "undoing change commited in r303"

あるファイルだけを以前のリビジョンに戻す

svn merge -r 7:6 hoge.cc
svn commit -m "reverted to 6" hoge.cc

ファイルの属性(property)を編集する

[svn propedit]

環境変数「$EDITOR」を使って指定した属性を編集する:

svn propedit PROPNAME PATH...
  • svn:ignore
    • ディレクトリ単位で無視するファイルを管理できる
      svn propedit svn:ignore test ./

リポジトリの「場所」

今までfile:///と書いてきた。これは以下のものが使える:

file:///リポジトリへの直接アクセス (ローカルディスク上)
http://Apacheサーバ への WebDAV プロトコル経由でのアクセス
https://http:// と同じだが、SSL による暗号化
svn://svnserve サーバに対する独自 TCP/IP プロトコル経由でのアクセス
svn+ssh://svn:// と同じだが、SSH トンネルを利用する

svn+ssh

sshでポートフォワード等でポート番号が標準でない場合は、環境変数を

export SVN_SSH="ssh -q -p 9022"

の様に設定しておく。

#!/bin/sh

export SVN_SSH="ssh -q -p 9022"
export SVNPATH=svn/MyAnalysisTool
export SVNROOT=svn+ssh://usrname@localhost/home/usrname/workspace/$SVNPATH

ssh -f  -L 9022:svn_server:22 usrname@login_server sleep 0
sleep 0
svn co $SVNROOT/trunk

status記号の意味

1桁目(追加 / 削除 / 変更など)

no modifications
Aファイルが新規追加された
Cローカルの修正とリポジトリの更新が競合している
Dファイルが削除された
Gローカルの修正とリポジトリの更新がマージされた
IIgnored
MModified
Rファイルが置き換えられた(同じ名前だが履歴上は別物)
Uファイルがリポジトリの最新版に更新された
Xitem is unversioned, but is used by an externals definition
?item is not under version control
!item is missing (removed by non-svn command) or incomplete
versioned item obstructed by some item of a different kind

2桁目(ファイルやディレクトリの属性)

no modifications
CConflicted
MModified

3桁目(作業コピーのロック)

not locked
Llocked

4桁目(履歴付きの追加予告)

no history scheduled with commit
+history scheduled with commit

5桁目(作業コピーからブランチへのスイッチ (svn switch コマンド) )

normal
Sswitched

作業の流れ

Subversionを用いた開発の流れ

  • 最初に一度だけcheckout
  • 日々の作業
    1. update(他人の変更点を、手元に反映させる)
    2. edit
    3. commit(自分の変更を、リポジトリに反映させる)
    4. i.へ戻る

Conflict(競合)の解消

repositoryにコミットされたファイルと、 localに存在するファイルとの不一致が生じる場合がある。 これを競合という。

競合を起こしたファイルについて、Subversion は、 次のようなバージョン管理対象にならない特殊なファイルを三つ、作業コピーに置く:

  • filename.mine
    • これは、updateを行う前の作業コピーで編集された自分のファイル。
  • filename.rNEWREV
    • これは、作業コピーを更新する前のrevisionにあったファイル。つまり、そのファイルは最後に行った編集の直前でのチェックアウト時点でのファイルである。
  • filename.rNEWREV
    • これは Subversionクライアントプログラムが作業コピーを更新したときにサーバから受け取ったファイル。これは、リポジトリの現在のrevisionに対応しています。 filename.rNEWREV
ls -la
TODManagement.cc.mine  TODManagement.cc.r169  TODManagement.cc.r172

このときSubversionは三つの一時ファイルが削除されるまで sandwich.txtのコミットを許可しない:

[observer@upsilon1s trunk]$ svn ci -m "add"
svn: Commit failed (details follow):
svn: Aborting commit: '/home/observer/my_analysis/trunk/TODManagement.cc' remains in conflict

次の三つが最も基本的な解決方法:

  • 「手で」 (ファイル中の競合マーカを調べ編集して) 競合テキストをマージする。
  • 作業ファイルに、一時ファイルのどれかを上書きする。
  • svn revert <filename>を 実行して、ローカルでしたすべての変更を捨てる。

これで解決したなら、

svn resolved sandwich.txt
svn commit -m "Go ahead and use my edit"

を実行。

競合を手で編集

less TODManagement.cc
<<<<<<< .mine
     printf("# read from fits: %s%s%s,    %zd and AdcAnomalyCorrect applied\n",
            getModuleName().c_str(), getFieldName().c_str(), utility::getDiodeName(iDiode).c_str(),
            val_[iDiode].size()) ;
=======

       printf("# read from fits: %s%s%s,    %zd and AdcAnomalyCorrect applied\n",
              getModuleName().c_str(), getFieldName().c_str(), utility::getDiodeName(iDiode).c_str(),
              val_[iDiode].size()) ;
>>>>>>> .r172

「<<<<<< .mine」と「======」の間が、自分が編集した箇所、 「======」と「>>>>>> .r172」の間が、他の作業コピーでコミットされた箇所。

これを参考に、競合を解決する。その後

svn resolved sandwich.txt
svn commit -m "Go ahead and use my edit"

を実行。

拡張子による除外ファイルの設定

/.subversion/configの以下の箇所を編集:

### Section for configuring miscelleneous Subversion options.
[miscellany]
### Set global-ignores to a set of whitespace-delimited globs
### which Subversion will ignore in its 'status' output, and
### while importing or adding files and directories.
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store

Backup

Basic backup plan (svnadmin dump)

Use svnadmin dump command:

svnadmin dump /home/username/repos/myrepos | bzip2 > /home/username/backup/myrepos.dump.bz2

When restoring the repository, create a new repository at first, then load the repository:

svnadmin create /home/username/repos/mynewrepos
bzcat /home/username/backup/myrepos.dump.bz2 | svnadmin load /home/username/repos/mynewrepos

リポジトリの喪失、作業コピーからの復帰

(リモートの)リポジトリが喪失し、(ローカルの)作業コピーから「可能な限り」現行のデータを元に(リモートの)新しいレポジトリを作成する。 当然、喪失したリポジトリのリビジョン情報は喪失してしまうが、現行データから新しいリポジトリを作成し、以後これを運用する。

新しいレポジトリの準備

create target repository:

remote:/home/username/repo/target

as the following:

pwd
/home/
mkdir repo
cd repo
svnadmin create target

現行データからの復旧

working copy:

local:/home/username/directory/target

Remove all the ".svn" directories. If you use subversion 1.7 and more, you just delete

cd /home/username/directory/target/
rm -rf .svn

If you use subversion 1.6, you have to delete all the ".svn" in the sub-directories

cd /home/username/directory/target/
find ./ -name ".svn" -type d | xargs rm -rf

Checkout the new directory from the repository:

cd /home/username/directory
svn co svn+ssh://remote/home/username/repo/target

Then add all the files to the new repository:

cd /home/username/directory/target
svn add ./*
svn ci -m "save"

名前

subversionという単語は、sub + versionではなく、「(国家や社会秩序を)破壊・転覆する」という意味のsubvertの名詞形である