程序获取给定 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;
}
我正在尝试用 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;
}