using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using System.Xml.Linq;
namespace SvnPkg
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 3)
{
Console.WriteLine("snvlog: 將指定的SVN變更集整理到指定的目錄下。");
Console.WriteLine("用法:svnpkg [專案根目錄] [輸出目錄] [版本變更集]");
Console.WriteLine(@"例如:svnlog D:\SVN\XXXXXX D:\Temp 228,230:231");
return;
}
String SvnPath = @"C:\Program Files\TortoiseSVN\bin\svn.exe";
String ProjectPathArg = args[0];
String OutputPathArg = args[1];
String ChangesetArg = args[2];
if (!File.Exists(SvnPath))
{
Console.WriteLine("找不到svn:" + SvnPath);
}
//解析revision
List<int> Changesets = new List<int>();
foreach (String sub in ChangesetArg.Split(','))
{
if (sub.Contains(':'))
{
int start = Convert.ToInt32(sub.Split(':')[0]);
int end = Convert.ToInt32(sub.Split(':')[1]);
for (int i = start; i <= end; i++)
{
if (!Changesets.Contains(i))
{
Changesets.Add(i);
}
}
}
else
{
if (!Changesets.Contains(Convert.ToInt32(sub)))
{
Changesets.Add(Convert.ToInt32(sub));
}
}
}
//依據變更集的先後順序排列
Changesets.Sort();
//Console.WriteLine(args[0]);
Process svnProcess = new Process();
svnProcess.StartInfo.FileName = SvnPath;
svnProcess.StartInfo.CreateNoWindow = true;
svnProcess.StartInfo.UseShellExecute = false;
svnProcess.StartInfo.StandardErrorEncoding = Encoding.UTF8;
svnProcess.StartInfo.StandardOutputEncoding = Encoding.UTF8;
svnProcess.StartInfo.RedirectStandardError = true;
svnProcess.StartInfo.RedirectStandardInput = true;
svnProcess.StartInfo.RedirectStandardOutput = true;
XDocument doc;
foreach (int cs in Changesets)
{
svnProcess.StartInfo.Arguments = "log " + ProjectPathArg + " -v -r " + cs.ToString() + " --xml";
svnProcess.Start();
doc = XDocument.Load(svnProcess.StandardOutput);
//String revision = doc.Document.Descendants("logentry").First().Attribute("revision").Value;
//String msg = doc.Document.Descendants("msg").First().Value;
//String date = doc.Document.Descendants("date").First().Value;
//Console.WriteLine("revision:" + revision + " " + msg);
foreach (XElement elem in doc.Document.Descendants("path"))
{
String basePath = elem.Value.Replace('/', '\\');
if (basePath.StartsWith("\\"))
{
basePath = basePath.Substring(1);
}
if (elem.Attribute("kind").Value == "file")
{
switch (elem.Attribute("action").Value)
{
case "A": //Add
case "M": //Modify
String srcFile = Path.Combine(ProjectPathArg, basePath);
String descFile = Path.Combine(OutputPathArg, basePath);
String descDir = descFile.Substring(0, descFile.LastIndexOf('\\'));
if (!Directory.Exists(descDir))
{
Directory.CreateDirectory(descDir);
}
File.Copy(srcFile, descFile,true);
break;
default:
Console.WriteLine("未處理的動作:" + elem.Attribute("action").Value);
break;
}
}
else if (elem.Attribute("kind").Value == "dir")
{
;
}
else
{
Console.WriteLine("未處理的種類:" + elem.Attribute("kind").Value);
}
}
//顯示目前處理的revision(使用big5才不會有亂碼)
svnProcess.StartInfo.Arguments = "log " + ProjectPathArg + " -v -r " + cs.ToString();
svnProcess.StartInfo.StandardOutputEncoding = Encoding.GetEncoding("big5");
svnProcess.Start();
Console.WriteLine(svnProcess.StandardOutput.ReadToEnd());
//回覆解析XML需要使用的UTF8編碼
svnProcess.StartInfo.StandardOutputEncoding = Encoding.UTF8;
}
Console.WriteLine("Done!");
}
}
}