I am trying to write a program in C# which can list out all conflicted files in a selected branch. The program will list out the username who committed last in conflicted file.
Actually we have multiple projects and a centralized project where multiple branch code merge using python AutoMerge server.
https://github.com/LivePersonInc/Auto-Merger
branch A Branch B Branch C Branch D Branch E Branch F
\ \ \ / / /
\ \ \ / / /
\ \ \ / / /
------------------------------------------
| AutoMerge Branch |
------------------------------------------
Currently I am facing lots of issue while finding the conflicts because even VS don't show all conflicted files on build. So I am looking for a solution how to start with. Any help will be appreciated.
I have written following method that will scan for all files having conflicted SVN keywords:
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;
}
private async Task<bool> TakeSVNUpdate(string Path)
{
?????????
return boolean;
}
private string CheckSVNLog(string FilePath)
{
??????????
return LastCommitedByUserNameANDRevision ;
}
Replace the following methods in your code:
The following method will create a batch file that accepts the Path of your branch as a parameter. and later execute that batch file to take SVN Update.
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;
}
Following method will check for the username who committed last in given file path:
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;
}