程序获取给定 SVN 分支的更新并获取在冲突文件中最后提交的用户名

Program to take the update of given SVN branch and get username who committed last in the conflicted file

我正在尝试用 C# 编写一个程序,它可以列出选定分支中的所有冲突文件。该程序将列出冲突文件中最后提交的用户名。

实际上我们有多个项目和一个集中项目,其中多个分支代码使用 python AutoMerge 服务器合并。

https://github.com/LivePersonInc/Auto-Merger

branch A  Branch B  Branch C Branch D  Branch E Branch F   

       \      \      \            /       /        /
        \      \      \          /       /        /
         \      \      \        /       /        /
        ------------------------------------------
      |              AutoMerge Branch             |
        ------------------------------------------    

目前我在发现冲突时遇到了很多问题,因为即使 VS 也不会在构建时显示所有冲突的文件。所以我正在寻找一个解决方案如何开始。任何帮助将不胜感激。

我已经编写了以下方法来扫描所有具有冲突 SVN 关键字的文件:

private async Task<bool> StartScan(string FolderPath)
    {
        try
        {
            if (string.IsNullOrEmpty(FolderPath))
            {
                MessageBox.Show("Please select path first");
                return false;
            }
            if (!System.IO.Directory.Exists(FolderPath))
            {
                MessageBox.Show("Invalid Path.");
                return false;
            }

            ConflictedFiles.Clear();

            bool isUpdateSuccess = false;


            //Here I want to take update of SVN Programatically
            //?????????????????????????????????????????????????????
             isUpdateSuccess = await TakeSVNUpdate(FolderPath);
            //?????????????????????????????????????????????????????
            //?????????????????????????????????????????????????????

            if (!isUpdateSuccess)
                return false;

            buttonScan.Enabled = false;
            buttonBrowse.Enabled = false;
            txtPath.Enabled = false;
            int validFilesScanCount = 0;
            int irrelaventExtensions = 0;
            int conflictedFilesCount = 0;
            string[] ValidExtensions = { ".cs", ".csproj" };
            string[] ConflictKeywords = { "<<<<<<< .mine", ">>>>>>>", "|||||||" };
            string FileName = "";
            string[] files = Directory.GetFiles(FolderPath, ".", SearchOption.AllDirectories).Where(d => !d.Contains(".svn")).Where(d => !d.Contains("\bin\Debug")).Where(d => !d.Contains("\obj\Debug")).Where(d => !d.Contains("\.vs")).ToArray();
            textBoxConflictedFiles.AppendText("==============================Conflicted Files Scan Start==============================\n" + Environment.NewLine);
            foreach (var file in files)
            {
                lblScanningFiles.Text = file;
                await Task.Delay(10);
                string extension = Path.GetExtension(file);
                if (!ValidExtensions.Contains(extension))
                {
                    irrelaventExtensions++;
                    continue;
                }
                else
                {
                    validFilesScanCount++;
                    string readText = File.ReadAllText(file);
                    var Isconflict = ConflictKeywords.Any(w => readText.Contains(w));
                    if (Isconflict)
                    {
                        FileName = file + Environment.NewLine;
                        conflictedFilesCount++;
                        textBoxConflictedFiles.AppendText(FileName + Environment.NewLine);

                        string LastCommitedBy_Revision = "";

                        //Here I want to check SVN Log Programatically
                        //?????????????????????????????????????????????????????
                        LastCommitedBy_Revision = CheckSVNLog(file);
                        //?????????????????????????????????????????????????????

                        if (!string.IsNullOrEmpty(LastCommitedBy_Revision))
                            ConflictedFiles.Add(file + " [ Last Commited By - " + LastCommitedBy_Revision + " ]");
                    }
                }
            }
            if (conflictedFilesCount == 0)
            {
                textBoxConflictedFiles.AppendText("No Conflicts Found." + Environment.NewLine);
            }
            else
            {
                textBoxConflictedFiles.AppendText("==============================Conflicted Files Scan End==============================" + Environment.NewLine);
                textBoxConflictedFiles.AppendText("======Conflicted Files Details======" + Environment.NewLine + Environment.NewLine);
                foreach (string conflictedfile in ConflictedFiles)
                {
                    textBoxConflictedFiles.AppendText(conflictedfile + Environment.NewLine + Environment.NewLine);
                }
                textBoxConflictedFiles.AppendText("Total Conflicted Files." + conflictedFilesCount + Environment.NewLine);
            }

            lblScanningFiles.Text = "Total Files Scanned " + validFilesScanCount;

        }
        catch (Exception ex)
        {
            textBoxConflictedFiles.AppendText(Environment.NewLine + "Scan Error.." + Environment.NewLine + ex.Message);
            return false;
        }
        finally
        {
            buttonScan.Enabled = true;
            buttonBrowse.Enabled = true;
            txtPath.Enabled = true;
        }
        return true;
    }

我需要帮助来实施 TakeSVNUpdate 和 CheckSVNLog 方法。
private async Task<bool> TakeSVNUpdate(string Path)
{
     ?????????
     return boolean;
}    
private string CheckSVNLog(string FilePath)
{
     ??????????
     return LastCommitedByUserNameANDRevision ;
}

任何帮助将不胜感激。

在您的代码中替换以下方法:

以下方法将创建一个批处理文件,该文件接受分支的路径作为参数。然后执行该批处理文件以进行 SVN 更新。

  private async Task<bool> TakeSVNUpdate(string Path)
        {
            try
            {
                using (StreamWriter sw = new StreamWriter("SVNUpdate.bat"))
                {
                    string parameter = "\"%1\"";
                    sw.WriteLine(@"CD C:\Program Files\TortoiseSVN\bin\");
                    sw.WriteLine(@"START TortoiseProc.exe /command:update /path:" + parameter + " /closeonend:0");
                    sw.WriteLine("exit");
                    sw.Close();
                }
               
                if (File.Exists("SVNUpdate.bat"))
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo();
                    startInfo.FileName = "SVNUpdate.bat";
                    startInfo.RedirectStandardInput = true;
                    startInfo.RedirectStandardOutput = true;
                    startInfo.RedirectStandardError = true;
                    startInfo.UseShellExecute = false;
                    startInfo.CreateNoWindow = true;
                    startInfo.Arguments = Path;
                    using (Process process = new Process())
                    {
                        process.StartInfo = startInfo;
                        process.Start();
                        process.WaitForExit();
                    }
                }
                MessageBox.show("SVN update Successfull.")
            }
            catch (Exception ex)
            {
                Messagebox.show(ex.Message);
                return false;
            }
            return true;
        }

以下方法将检查给定文件路径中最后提交的用户名:

  private string CheckSVNLog(string FilePath)
        {
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.FileName = "cmd.exe";
            startInfo.RedirectStandardInput = true;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;

            var SourcePath = FilePath;  // URL link
            var cmd1 = "cd c:\";
            var cmd2 = string.Format("svn log {0}", SourcePath);

            string result = string.Empty; // for storing the svn commit log
            bool AddtoLog = false;
            char logStart = 'r'; //SVN revision info start with this character
            string logEnd = "------------------------------------------------------------------------"; //End of Log symbol
            string LastCommitBy = "";
            string Date = "";
            string Revision = "";
            List<string> SVNLog = new List<string>();
            try
            {
                using (Process process = new Process())
                {
                    process.StartInfo = startInfo;

                    process.Start();
                    process.StandardInput.WriteLine(cmd1);
                    process.StandardInput.WriteLine(cmd2);

                    // It's always a good idea to close your standard input when you're not gonna need it anymore,
                    // otherwise the process will wait indefinitely for any input and your while condition will never
                    // be true or in other words, it will become an infinite loop...
                    process.StandardInput.Close();

                    while (!process.StandardOutput.EndOfStream)
                    {
                        string line = process.StandardOutput.ReadLine();
                        if (!AddtoLog && !string.IsNullOrEmpty(line) && line[0] == logStart)
                        {
                            //Skip additional Microsoft Lines returned by StandardOutput.Readline()
                            AddtoLog = true; 
                        }
                        if (!string.IsNullOrEmpty(line))
                        {
                            if (!process.HasExited)
                            {
                                if (AddtoLog)
                                {
                                    SVNLog.Add(line);//Collecting all SVN Log here
                                }
                            }
                        }
                    }
                }
                
                string Details = "";
                //Checking if log exists
                if (SVNLog.Any(str => str.StartsWith(logStart.ToString())))
                {   //Getting details of Last user who commits
                    Details = SVNLog.Where(str => str.StartsWith(logStart.ToString())).LastOrDefault();
                    string[] LogDetails = Details.Split('|');
                    LastCommitBy = LogDetails[1];
                    Revision = ": Revision : " + LogDetails[0].TrimStart('r');
                    Date = ": Date : " + LogDetails[2].Split('+')[0];
                }
               
                }
            }
            catch (Exception ex)
            {
               MessageBox.Show(ex.Message);
            }
            return LastCommitBy + Revision + Date;
        }