スポンサーリンク

C#からSubversionを使う

TortoiseSVNやAnkhSVNは優れたGUIツールですが、バッチ的な処理を行う場合にはスクリプト言語やプログラミングコードで処理できた方が便利な場合がありますよね。

ということで、C# Advent Calendat 2011 12/10分はそのようなお話です。

C#をはじめとする.NET Fxの言語からSubversionを使うためのライブラリがCOLLABNETから公開されていて、実際にAnkhSVNでも使用されているようです。

以下のCOLLABNETのサイトからダウンロードが可能です。

公開サイト:sharpsvn: Subversion Library for .Net 2.0+

また、Nugetを使ってインストールすることもできます。

では、実際に動く物を作ってみましょう。

適当なコンソールアプリケーションのプロジェクトを作って、Nugetを起動したら、”SVN”で検索してみましょう。sharpSVNは現状.NET Fx 4.0では動作しないので、プロジェクトのターゲットは.NET Fx 3.5としてください。

検索後以下のようにsharpsvnが見つかるはずです。

image

通常ではとりあえずx86版を選んでおけば良いと思います。

ただし、通常のダウンロード、NuGetで入手できるのはSVN 1.6に対応した安定版で、SVN1.6までとは互換性の無いSVN 1.7のワーキングディレクトリ形式に対応した物ではありません。

Tortoise SVNは既にSVN 1.7に対応していることもあり、今から何かを作るのであれば、1.7以降に対応したライブラリを使用した方が良いでしょう。

残念ながら1.7に対応したsharpSVNはNuGetでは入手できず、SVN 1.7に対応したsharpSVNは現状Daily Buildとしてのみ公開されているので、以下よりダウンロードして使用します。(最新版のダウンロードで問題ないはずです)

Documents & files: Daily-1.7

http://sharpsvn.open.collab.net/daily/1.7.x

ダウンロードしたら適当なフォルダに解凍し、プロジェクトにSharpSvn.dllへの参照を追加します。

image

では実際にコードを見ていきましょう。とは言ってもコードを見れば一目瞭然ですね。

まずはクライアントの作成。Subversionクライアントのインスタンスを作って、コマンド実行時に呼び出される通知用のイベントを追加します。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
client = <span class="hljs-keyword">new</span> <span class="hljs-type">SvnClient</span>();
<span class="hljs-comment">//イベント設定</span>
client.Notify += <span class="hljs-keyword">new</span> <span class="hljs-type">EventHandler</span>(client_Notify);
client = <span class="hljs-keyword">new</span> <span class="hljs-type">SvnClient</span>(); <span class="hljs-comment">//イベント設定</span> client.Notify += <span class="hljs-keyword">new</span> <span class="hljs-type">EventHandler</span>(client_Notify);
client = new SvnClient();
//イベント設定
client.Notify += new EventHandler(client_Notify);
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> client_Notify(object sender, SvnNotifyEventArgs e)
{
<span class="hljs-keyword">switch</span> (e.CommandType)
{
<span class="hljs-comment">//チェックアウト/アップデート中のファイルを表示する</span>
<span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">CheckOut:</span>
<span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Update:</span>
<span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Add:</span>
<span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Commit:</span>
Console.WriteLine(e.FullPath + <span class="hljs-string">", Rev. "</span> + e.Revision + <span class="hljs-string">"\t : "</span> + e.Action);
<span class="hljs-keyword">break</span>;
<span class="hljs-symbol"> default:</span>
<span class="hljs-keyword">break</span>;
}
}
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> client_Notify(object sender, SvnNotifyEventArgs e) { <span class="hljs-keyword">switch</span> (e.CommandType) { <span class="hljs-comment">//チェックアウト/アップデート中のファイルを表示する</span> <span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">CheckOut:</span> <span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Update:</span> <span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Add:</span> <span class="hljs-keyword">case</span> SvnCommandType.<span class="hljs-string">Commit:</span> Console.WriteLine(e.FullPath + <span class="hljs-string">", Rev. "</span> + e.Revision + <span class="hljs-string">"\t : "</span> + e.Action); <span class="hljs-keyword">break</span>; <span class="hljs-symbol"> default:</span> <span class="hljs-keyword">break</span>; } }
private static void client_Notify(object sender, SvnNotifyEventArgs e) 
{
    switch (e.CommandType) 
    {
        //チェックアウト/アップデート中のファイルを表示する
        case SvnCommandType.CheckOut:
        case SvnCommandType.Update:
        case SvnCommandType.Add:
        case SvnCommandType.Commit:
            Console.WriteLine(e.FullPath + ", Rev. " + e.Revision + "\t : " + e.Action);
            break;
        default:
            break;
    }
}

つぎはワーキングディレクトリにチェックアウトもしくはアップデートを実行する場合のコードです。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-keyword">private</span> static void <span class="hljs-constructor">CheckoutOrUpdate(<span class="hljs-params">string</span> <span class="hljs-params">repo</span>, <span class="hljs-params">string</span> <span class="hljs-params">dir</span>)</span>
{
<span class="hljs-comment">//チェックアウト</span>
<span class="hljs-built_in">string</span> svnDir = @<span class="hljs-string">".svn"</span>;
<span class="hljs-keyword">if</span> (Directory.<span class="hljs-constructor">Exists(<span class="hljs-params">dir</span> + <span class="hljs-string">"\\"</span> + <span class="hljs-params">svnDir</span>)</span>)
{
<span class="hljs-comment">//.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。</span>
Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"++ Working Directory Update ++"</span>)</span>;
client.<span class="hljs-constructor">Update(<span class="hljs-params">dir</span>)</span>;
}
<span class="hljs-keyword">else</span>
{
<span class="hljs-comment">//チェックアウトする。</span>
Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"++ CheckOut ++"</span>)</span>;
client.<span class="hljs-constructor">CheckOut(<span class="hljs-params">new</span> Uri(<span class="hljs-params">repo</span>)</span>, dir);
}
}
<span class="hljs-keyword">private</span> static void <span class="hljs-constructor">CheckoutOrUpdate(<span class="hljs-params">string</span> <span class="hljs-params">repo</span>, <span class="hljs-params">string</span> <span class="hljs-params">dir</span>)</span> { <span class="hljs-comment">//チェックアウト</span> <span class="hljs-built_in">string</span> svnDir = @<span class="hljs-string">".svn"</span>; <span class="hljs-keyword">if</span> (Directory.<span class="hljs-constructor">Exists(<span class="hljs-params">dir</span> + <span class="hljs-string">"\\"</span> + <span class="hljs-params">svnDir</span>)</span>) { <span class="hljs-comment">//.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。</span> Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"++ Working Directory Update ++"</span>)</span>; client.<span class="hljs-constructor">Update(<span class="hljs-params">dir</span>)</span>; } <span class="hljs-keyword">else</span> { <span class="hljs-comment">//チェックアウトする。</span> Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"++ CheckOut ++"</span>)</span>; client.<span class="hljs-constructor">CheckOut(<span class="hljs-params">new</span> Uri(<span class="hljs-params">repo</span>)</span>, dir); } }
private static void CheckoutOrUpdate(string repo, string dir) 
{
    //チェックアウト
    string svnDir = @".svn";
    if (Directory.Exists(dir + "\\" + svnDir)) 
    {
         //.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。
         Console.WriteLine("++ Working Directory Update ++");
         client.Update(dir);
    }
    else 
    {
          //チェックアウトする。
          Console.WriteLine("++ CheckOut ++");
          client.CheckOut(new Uri(repo), dir);
    }
}

ファイルの追加。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-comment">//add</span>
client.<span class="hljs-constructor">Add(<span class="hljs-params">filePath</span>)</span>;
<span class="hljs-comment">//move(rename)</span>
client.<span class="hljs-constructor">Move(<span class="hljs-params">filePath</span>, <span class="hljs-params">destPath</span>)</span>;
<span class="hljs-comment">//delete</span>
client.<span class="hljs-constructor">Delete(<span class="hljs-params">filePath</span>)</span>;
<span class="hljs-comment">//add</span> client.<span class="hljs-constructor">Add(<span class="hljs-params">filePath</span>)</span>; <span class="hljs-comment">//move(rename)</span> client.<span class="hljs-constructor">Move(<span class="hljs-params">filePath</span>, <span class="hljs-params">destPath</span>)</span>; <span class="hljs-comment">//delete</span> client.<span class="hljs-constructor">Delete(<span class="hljs-params">filePath</span>)</span>;
//add
client.Add(filePath);
//move(rename)
client.Move(filePath, destPath);
//delete
client.Delete(filePath);

ワーキングディレクトリのステータスの取得。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintStatus</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span>
{
<span class="hljs-comment">//ステータスを取得する</span>
Collection stats;
client.GetStatus(workingDir, <span class="hljs-keyword">out</span> stats);
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> s <span class="hljs-keyword">in</span> stats)
{
Console.WriteLine(<span class="hljs-string">"File :{0}, Last change time :{1}, Staus :{2}"</span>,
s.FullPath, s.LastChangeTime, s.LocalContentStatus);
}
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintStatus</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span> { <span class="hljs-comment">//ステータスを取得する</span> Collection stats; client.GetStatus(workingDir, <span class="hljs-keyword">out</span> stats); <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> s <span class="hljs-keyword">in</span> stats) { Console.WriteLine(<span class="hljs-string">"File :{0}, Last change time :{1}, Staus :{2}"</span>, s.FullPath, s.LastChangeTime, s.LocalContentStatus); } }
private static void PrintStatus(string workingDir) 
{
    //ステータスを取得する
    Collection stats;
    client.GetStatus(workingDir, out stats);
    foreach (var s in stats) 
    {
        Console.WriteLine("File :{0}, Last change time :{1}, Staus :{2}",
        s.FullPath, s.LastChangeTime, s.LocalContentStatus);
    }
}

コミット。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-keyword">private</span> static void <span class="hljs-constructor">Commit(<span class="hljs-params">string</span> <span class="hljs-params">workingDir</span>)</span>
{
SvnCommitArgs ca = <span class="hljs-keyword">new</span> <span class="hljs-constructor">SvnCommitArgs()</span>;
ca.LogMessage = <span class="hljs-string">"ファイルを追加"</span>;
SvnCommitResult results;
client.<span class="hljs-constructor">Commit(<span class="hljs-params">workingDir</span>, <span class="hljs-params">ca</span>, <span class="hljs-params">out</span> <span class="hljs-params">results</span>)</span>;
Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Time :{0}"</span>, <span class="hljs-params">results</span>.Time)</span>;
Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Author :{0}"</span>, <span class="hljs-params">results</span>.Author)</span>;
Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Revision :{0}"</span>, <span class="hljs-params">results</span>.Revision)</span>;
}
<span class="hljs-keyword">private</span> static void <span class="hljs-constructor">Commit(<span class="hljs-params">string</span> <span class="hljs-params">workingDir</span>)</span> { SvnCommitArgs ca = <span class="hljs-keyword">new</span> <span class="hljs-constructor">SvnCommitArgs()</span>; ca.LogMessage = <span class="hljs-string">"ファイルを追加"</span>; SvnCommitResult results; client.<span class="hljs-constructor">Commit(<span class="hljs-params">workingDir</span>, <span class="hljs-params">ca</span>, <span class="hljs-params">out</span> <span class="hljs-params">results</span>)</span>; Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Time :{0}"</span>, <span class="hljs-params">results</span>.Time)</span>; Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Author :{0}"</span>, <span class="hljs-params">results</span>.Author)</span>; Console.<span class="hljs-constructor">WriteLine(<span class="hljs-string">"Commit Revision :{0}"</span>, <span class="hljs-params">results</span>.Revision)</span>; }
private static void Commit(string workingDir) 
{
    SvnCommitArgs ca = new SvnCommitArgs();
    ca.LogMessage = "ファイルを追加";
    SvnCommitResult results;
    client.Commit(workingDir, ca, out results);
    Console.WriteLine("Commit Time :{0}", results.Time);
    Console.WriteLine("Commit Author :{0}", results.Author);
    Console.WriteLine("Commit Revision :{0}", results.Revision);
}

全体コード。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<span class="hljs-keyword">using</span> System;
<span class="hljs-keyword">using</span> System.Collections.Generic;
<span class="hljs-keyword">using</span> System.Linq;
<span class="hljs-keyword">using</span> System.Text;
<span class="hljs-keyword">using</span> System.IO;
<span class="hljs-keyword">using</span> System.Collections.ObjectModel;
<span class="hljs-keyword">using</span> SharpSvn;
<span class="hljs-keyword">namespace</span> <span class="hljs-title">SVNSample</span>
{
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><summary></span></span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> SharpSVNのサンプル</span>
<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"></summary></span></span>
<span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> SvnClient client; <span class="hljs-comment">//Subversion Client</span>
<span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
{
<span class="hljs-keyword">if</span> (args.Length >= <span class="hljs-number">0</span>)
{
Console.WriteLine(<span class="hljs-string">"Usage: SVNSample [Repo URI] [Work Directory]"</span>);
}
client = <span class="hljs-keyword">new</span> SvnClient(); <span class="hljs-comment">//イベント設定 client.Notify += new EventHandler(client_Notify);</span>
<span class="hljs-keyword">try</span>
{
<span class="hljs-comment">//資格情報を作成してクライアントに登録する。(ネットワーク越しで認証が必要なケース)</span>
<span class="hljs-comment">//var cred = new System.Net.NetworkCredential("ishisaka", "");</span>
<span class="hljs-comment">//client.Authentication.DefaultCredentials = cred;</span>
<span class="hljs-comment">//ワーキングディレクトリの状態によってチェックアウトもしくはアップデートを行う。</span>
CheckoutOrUpdate(args[<span class="hljs-number">0</span>], args[<span class="hljs-number">1</span>]);
<span class="hljs-comment">//listコマンドの実行</span>
Console.WriteLine(<span class="hljs-string">"+++ Repo Directory / File List +++"</span>);
GetRepoList(<span class="hljs-keyword">new</span> Uri(args[<span class="hljs-number">0</span>]));
<span class="hljs-comment">//テスト用のファイルの作成</span>
Console.WriteLine(<span class="hljs-string">"+++ File Cleate \"hello[yyyymmddhhmmss].py\" +++"</span>);
<span class="hljs-keyword">var</span> contents = <span class="hljs-string">"print 'Hello py'\n"</span>;
<span class="hljs-keyword">var</span> dateStr = DateTime.Now.ToString(<span class="hljs-string">"yyyyMMddhhmmss"</span>);
<span class="hljs-keyword">var</span> filePath = args[<span class="hljs-number">1</span>] + <span class="hljs-string">"\\trunk\\hello"</span> + dateStr + <span class="hljs-string">".py"</span>;
File.WriteAllText(filePath, contents);
<span class="hljs-comment">//ADD</span>
Console.WriteLine(<span class="hljs-string">"+++ File Add +++"</span>);
client.Add(filePath);
<span class="hljs-comment">//ステータス</span>
Console.WriteLine(<span class="hljs-string">"+++ Status +++"</span>);
PrintStatus(args[<span class="hljs-number">1</span>]);
<span class="hljs-comment">//コミット</span>
Console.WriteLine(<span class="hljs-string">"+++ Commit +++"</span>);
Commit(args[<span class="hljs-number">1</span>]);
Console.Write(<span class="hljs-string">"何か入力で終了:"</span>);
Console.Read();
}
<span class="hljs-keyword">finally</span>
{
client.Dispose();
}
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Commit</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span>
{
SvnCommitArgs ca = <span class="hljs-keyword">new</span> SvnCommitArgs();
ca.LogMessage = <span class="hljs-string">"ファイルを追加"</span>;
SvnCommitResult results;
client.Commit(workingDir, ca, <span class="hljs-keyword">out</span> results);
Console.WriteLine(<span class="hljs-string">"Commit Time :{0}"</span>, results.Time);
Console.WriteLine(<span class="hljs-string">"Commit Author :{0}"</span>, results.Author);
Console.WriteLine(<span class="hljs-string">"Commit Revision :{0}"</span>, results.Revision);
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintStatus</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span>
{
<span class="hljs-comment">//ステータスを取得する</span>
Collection stats;
client.GetStatus(workingDir, <span class="hljs-keyword">out</span> stats);
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> s <span class="hljs-keyword">in</span> stats)
{
Console.WriteLine(<span class="hljs-string">"File :{0}, Last change time :{1}, Staus :{2}"</span>,
s.FullPath, s.LastChangeTime, s.LocalContentStatus);
}
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">CheckoutOrUpdate</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> repo, <span class="hljs-keyword">string</span> dir</span>)</span>
{
<span class="hljs-comment">//チェックアウト</span>
<span class="hljs-keyword">string</span> svnDir = <span class="hljs-string">@".svn"</span>;
<span class="hljs-keyword">if</span> (Directory.Exists(dir + <span class="hljs-string">"\\"</span> + svnDir))
{
<span class="hljs-comment">//.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。</span>
Console.WriteLine(<span class="hljs-string">"++ Working Directory Update ++"</span>);
client.Update(dir);
}
<span class="hljs-keyword">else</span>
{
<span class="hljs-comment">//チェックアウトする。</span>
Console.WriteLine(<span class="hljs-string">"++ CheckOut ++"</span>);
client.CheckOut(<span class="hljs-keyword">new</span> Uri(repo), dir);
}
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">GetRepoList</span>(<span class="hljs-params">Uri url</span>)</span>
{
<span class="hljs-comment">//Collectionの用意</span>
Collection list;
<span class="hljs-keyword">string</span> myPath = url.LocalPath;
<span class="hljs-comment">//ターゲットの作成</span>
SvnUriTarget repo = <span class="hljs-keyword">new</span> SvnUriTarget(url);
<span class="hljs-comment">//listコマンドの実行</span>
client.GetList(repo, <span class="hljs-keyword">out</span> list);
<span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> l <span class="hljs-keyword">in</span> list)
{
<span class="hljs-comment">//レポジトリのルートディレクトリは無視する。</span>
<span class="hljs-keyword">if</span> (l.Uri.LocalPath == l.RepositoryRoot.LocalPath) <span class="hljs-keyword">continue</span>;
<span class="hljs-keyword">switch</span> (l.Entry.NodeKind)
{
<span class="hljs-keyword">case</span> SvnNodeKind.Directory:
<span class="hljs-keyword">if</span> (l.Uri.LocalPath != myPath)
{
Console.WriteLine(<span class="hljs-string">"Folder\t:{0}"</span>, l.Uri.LocalPath);
GetRepoList(l.Uri);
}
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> SvnNodeKind.File:
Console.WriteLine(<span class="hljs-string">"\tFile\t:{0}"</span>, Path.GetFileName(l.Uri.LocalPath));
<span class="hljs-keyword">break</span>;
}
}
list.Clear();
}
<span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">client_Notify</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> sender, SvnNotifyEventArgs e</span>)</span>
{
<span class="hljs-keyword">switch</span> (e.CommandType)
{
<span class="hljs-comment">//チェックアウト/アップデート中のファイルを表示する</span>
<span class="hljs-keyword">case</span> SvnCommandType.CheckOut:
<span class="hljs-keyword">case</span> SvnCommandType.Update:
<span class="hljs-keyword">case</span> SvnCommandType.Add:
<span class="hljs-keyword">case</span> SvnCommandType.Commit:
Console.WriteLine(e.FullPath + <span class="hljs-string">", Rev. "</span>
+ e.Revision + <span class="hljs-string">"\t : "</span> + e.Action);
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">default</span>:
<span class="hljs-keyword">break</span>;
}
}
}
}
<span class="hljs-keyword">using</span> System; <span class="hljs-keyword">using</span> System.Collections.Generic; <span class="hljs-keyword">using</span> System.Linq; <span class="hljs-keyword">using</span> System.Text; <span class="hljs-keyword">using</span> System.IO; <span class="hljs-keyword">using</span> System.Collections.ObjectModel; <span class="hljs-keyword">using</span> SharpSvn; <span class="hljs-keyword">namespace</span> <span class="hljs-title">SVNSample</span> { <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"><summary></span></span> <span class="hljs-comment"><span class="hljs-doctag">///</span> SharpSVNのサンプル</span> <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag"></summary></span></span> <span class="hljs-keyword">class</span> <span class="hljs-title">Program</span> { <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> SvnClient client; <span class="hljs-comment">//Subversion Client</span> <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span> { <span class="hljs-keyword">if</span> (args.Length >= <span class="hljs-number">0</span>) { Console.WriteLine(<span class="hljs-string">"Usage: SVNSample [Repo URI] [Work Directory]"</span>); } client = <span class="hljs-keyword">new</span> SvnClient(); <span class="hljs-comment">//イベント設定 client.Notify += new EventHandler(client_Notify);</span> <span class="hljs-keyword">try</span> { <span class="hljs-comment">//資格情報を作成してクライアントに登録する。(ネットワーク越しで認証が必要なケース)</span> <span class="hljs-comment">//var cred = new System.Net.NetworkCredential("ishisaka", "");</span> <span class="hljs-comment">//client.Authentication.DefaultCredentials = cred;</span> <span class="hljs-comment">//ワーキングディレクトリの状態によってチェックアウトもしくはアップデートを行う。</span> CheckoutOrUpdate(args[<span class="hljs-number">0</span>], args[<span class="hljs-number">1</span>]); <span class="hljs-comment">//listコマンドの実行</span> Console.WriteLine(<span class="hljs-string">"+++ Repo Directory / File List +++"</span>); GetRepoList(<span class="hljs-keyword">new</span> Uri(args[<span class="hljs-number">0</span>])); <span class="hljs-comment">//テスト用のファイルの作成</span> Console.WriteLine(<span class="hljs-string">"+++ File Cleate \"hello[yyyymmddhhmmss].py\" +++"</span>); <span class="hljs-keyword">var</span> contents = <span class="hljs-string">"print 'Hello py'\n"</span>; <span class="hljs-keyword">var</span> dateStr = DateTime.Now.ToString(<span class="hljs-string">"yyyyMMddhhmmss"</span>); <span class="hljs-keyword">var</span> filePath = args[<span class="hljs-number">1</span>] + <span class="hljs-string">"\\trunk\\hello"</span> + dateStr + <span class="hljs-string">".py"</span>; File.WriteAllText(filePath, contents); <span class="hljs-comment">//ADD</span> Console.WriteLine(<span class="hljs-string">"+++ File Add +++"</span>); client.Add(filePath); <span class="hljs-comment">//ステータス</span> Console.WriteLine(<span class="hljs-string">"+++ Status +++"</span>); PrintStatus(args[<span class="hljs-number">1</span>]); <span class="hljs-comment">//コミット</span> Console.WriteLine(<span class="hljs-string">"+++ Commit +++"</span>); Commit(args[<span class="hljs-number">1</span>]); Console.Write(<span class="hljs-string">"何か入力で終了:"</span>); Console.Read(); } <span class="hljs-keyword">finally</span> { client.Dispose(); } } <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Commit</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span> { SvnCommitArgs ca = <span class="hljs-keyword">new</span> SvnCommitArgs(); ca.LogMessage = <span class="hljs-string">"ファイルを追加"</span>; SvnCommitResult results; client.Commit(workingDir, ca, <span class="hljs-keyword">out</span> results); Console.WriteLine(<span class="hljs-string">"Commit Time :{0}"</span>, results.Time); Console.WriteLine(<span class="hljs-string">"Commit Author :{0}"</span>, results.Author); Console.WriteLine(<span class="hljs-string">"Commit Revision :{0}"</span>, results.Revision); } <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintStatus</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> workingDir</span>)</span> { <span class="hljs-comment">//ステータスを取得する</span> Collection stats; client.GetStatus(workingDir, <span class="hljs-keyword">out</span> stats); <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> s <span class="hljs-keyword">in</span> stats) { Console.WriteLine(<span class="hljs-string">"File :{0}, Last change time :{1}, Staus :{2}"</span>, s.FullPath, s.LastChangeTime, s.LocalContentStatus); } } <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">CheckoutOrUpdate</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> repo, <span class="hljs-keyword">string</span> dir</span>)</span> { <span class="hljs-comment">//チェックアウト</span> <span class="hljs-keyword">string</span> svnDir = <span class="hljs-string">@".svn"</span>; <span class="hljs-keyword">if</span> (Directory.Exists(dir + <span class="hljs-string">"\\"</span> + svnDir)) { <span class="hljs-comment">//.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。</span> Console.WriteLine(<span class="hljs-string">"++ Working Directory Update ++"</span>); client.Update(dir); } <span class="hljs-keyword">else</span> { <span class="hljs-comment">//チェックアウトする。</span> Console.WriteLine(<span class="hljs-string">"++ CheckOut ++"</span>); client.CheckOut(<span class="hljs-keyword">new</span> Uri(repo), dir); } } <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">GetRepoList</span>(<span class="hljs-params">Uri url</span>)</span> { <span class="hljs-comment">//Collectionの用意</span> Collection list; <span class="hljs-keyword">string</span> myPath = url.LocalPath; <span class="hljs-comment">//ターゲットの作成</span> SvnUriTarget repo = <span class="hljs-keyword">new</span> SvnUriTarget(url); <span class="hljs-comment">//listコマンドの実行</span> client.GetList(repo, <span class="hljs-keyword">out</span> list); <span class="hljs-keyword">foreach</span> (<span class="hljs-keyword">var</span> l <span class="hljs-keyword">in</span> list) { <span class="hljs-comment">//レポジトリのルートディレクトリは無視する。</span> <span class="hljs-keyword">if</span> (l.Uri.LocalPath == l.RepositoryRoot.LocalPath) <span class="hljs-keyword">continue</span>; <span class="hljs-keyword">switch</span> (l.Entry.NodeKind) { <span class="hljs-keyword">case</span> SvnNodeKind.Directory: <span class="hljs-keyword">if</span> (l.Uri.LocalPath != myPath) { Console.WriteLine(<span class="hljs-string">"Folder\t:{0}"</span>, l.Uri.LocalPath); GetRepoList(l.Uri); } <span class="hljs-keyword">break</span>; <span class="hljs-keyword">case</span> SvnNodeKind.File: Console.WriteLine(<span class="hljs-string">"\tFile\t:{0}"</span>, Path.GetFileName(l.Uri.LocalPath)); <span class="hljs-keyword">break</span>; } } list.Clear(); } <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">client_Notify</span>(<span class="hljs-params"><span class="hljs-keyword">object</span> sender, SvnNotifyEventArgs e</span>)</span> { <span class="hljs-keyword">switch</span> (e.CommandType) { <span class="hljs-comment">//チェックアウト/アップデート中のファイルを表示する</span> <span class="hljs-keyword">case</span> SvnCommandType.CheckOut: <span class="hljs-keyword">case</span> SvnCommandType.Update: <span class="hljs-keyword">case</span> SvnCommandType.Add: <span class="hljs-keyword">case</span> SvnCommandType.Commit: Console.WriteLine(e.FullPath + <span class="hljs-string">", Rev. "</span> + e.Revision + <span class="hljs-string">"\t : "</span> + e.Action); <span class="hljs-keyword">break</span>; <span class="hljs-keyword">default</span>: <span class="hljs-keyword">break</span>; } } } }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections.ObjectModel;
using SharpSvn;

namespace SVNSample
{
    /// <summary>
    /// SharpSVNのサンプル
    /// </summary>

    class Program
    {
        private static SvnClient client; //Subversion Client

        static void Main(string[] args) 
        {
            if (args.Length >= 0) 
            { 
                Console.WriteLine("Usage: SVNSample [Repo URI] [Work Directory]"); 
            } 
            client = new SvnClient(); //イベント設定 client.Notify += new EventHandler(client_Notify);

            try
            {
                //資格情報を作成してクライアントに登録する。(ネットワーク越しで認証が必要なケース)
                //var cred = new System.Net.NetworkCredential("ishisaka", "");

                //client.Authentication.DefaultCredentials = cred;
                //ワーキングディレクトリの状態によってチェックアウトもしくはアップデートを行う。
                CheckoutOrUpdate(args[0], args[1]);
                //listコマンドの実行
                Console.WriteLine("+++ Repo Directory / File List +++");
                GetRepoList(new Uri(args[0]));
                //テスト用のファイルの作成
                Console.WriteLine("+++ File Cleate \"hello[yyyymmddhhmmss].py\" +++");
                var contents = "print 'Hello py'\n";
                var dateStr = DateTime.Now.ToString("yyyyMMddhhmmss");
                var filePath = args[1] + "\\trunk\\hello" + dateStr + ".py";
                File.WriteAllText(filePath, contents);

                //ADD
                Console.WriteLine("+++ File Add +++");
                client.Add(filePath);

                //ステータス
                Console.WriteLine("+++ Status +++");
                PrintStatus(args[1]);

                //コミット
                Console.WriteLine("+++ Commit +++");
                Commit(args[1]);

                Console.Write("何か入力で終了:");
                Console.Read();
            }
            finally
            {
                client.Dispose();
            }
        }

        private static void Commit(string workingDir)
        {
            SvnCommitArgs ca = new SvnCommitArgs();
            ca.LogMessage = "ファイルを追加";
            SvnCommitResult results;
            client.Commit(workingDir, ca, out results);
            Console.WriteLine("Commit Time :{0}", results.Time);
            Console.WriteLine("Commit Author :{0}", results.Author);
            Console.WriteLine("Commit Revision :{0}", results.Revision);
        }

        private static void PrintStatus(string workingDir) 
        {
            //ステータスを取得する
            Collection stats;
            client.GetStatus(workingDir, out stats);
            foreach (var s in stats) 
            {
                Console.WriteLine("File :{0}, Last change time :{1}, Staus :{2}",
                s.FullPath, s.LastChangeTime, s.LocalContentStatus);
            }
        }

        private static void CheckoutOrUpdate(string repo, string dir) 
        {
            //チェックアウト
            string svnDir = @".svn";
            if (Directory.Exists(dir + "\\" + svnDir)) 
            {
                //.svnディレクトリが存在したらチェックアウト済みと見なし、アップデートする。
                Console.WriteLine("++ Working Directory Update ++");
                client.Update(dir);
            }
            else 
            {
                //チェックアウトする。
                Console.WriteLine("++ CheckOut ++");
                client.CheckOut(new Uri(repo), dir);
            }
        }

        private static void GetRepoList(Uri url) 
        {
            //Collectionの用意
            Collection list;
            string myPath = url.LocalPath;
            //ターゲットの作成
            SvnUriTarget repo = new SvnUriTarget(url);
            //listコマンドの実行
            client.GetList(repo, out list);
            foreach (var l in list) 
            {
                //レポジトリのルートディレクトリは無視する。
                if (l.Uri.LocalPath == l.RepositoryRoot.LocalPath) continue;
                switch (l.Entry.NodeKind) 
                {
                    case SvnNodeKind.Directory:
                        if (l.Uri.LocalPath != myPath) 
                        {
                            Console.WriteLine("Folder\t:{0}", l.Uri.LocalPath);
                            GetRepoList(l.Uri);
                        }
                        break;
                    case SvnNodeKind.File:
                        Console.WriteLine("\tFile\t:{0}", Path.GetFileName(l.Uri.LocalPath));
                        break;
                }

            }
            list.Clear();
        }

        private static void client_Notify(object sender, SvnNotifyEventArgs e) 
        {
            switch (e.CommandType) 
            {
                //チェックアウト/アップデート中のファイルを表示する
                case SvnCommandType.CheckOut:
                case SvnCommandType.Update:
                case SvnCommandType.Add:
                case SvnCommandType.Commit:
                    Console.WriteLine(e.FullPath + ", Rev. "
                        + e.Revision + "\t : " + e.Action);
                    break;
                default:
                    break;
            }
        }
    }
}

参考:
sharpSVNサイトでのサンプルコード

この記事のサンプルコード ダウンロード

コメント

タイトルとURLをコピーしました