2012年5月13日 星期日

[SVN]將已簽入SVN的變更集重新打包為資料夾

可以很方便的對客製的同一工作項目進行覆蓋式的修改。

因為不是每一個客戶都有SVN的Patch可用,也不適合對不透明的系統使用SVN的Patch指令。

 

限制:

這裡只有做新增的部分,保留刪除與修改功能,有需要的人也可以依據自己的工作來最對應的修改。

需要安裝SVN客戶端 – TortoiseSVN

只適用於台灣地區,其他地區可能在顯示上會有亂碼,但不影響功能。

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!");
        }
    }
}

沒有留言:

張貼留言