private static DiffBlock AddWhitespace(DiffBlock oDiffBlock, List <string> cWhitespace, int iWhitespace, bool bDeletion = false, int iMode = 3) { //iMode 1 = Only Top //iMode 2 = Only Bottom //iMode 3 = Both if (iMode == 1 || iMode == 3) { //Top Whitespace int iNewLine = oDiffBlock.iStartLine; //When it's a deletion, then the "Startline" is the first line that we need as whitespace, where in any other case we would go for the line above that. //Keep in mind that the corresponding whitespace list index is always - 1. for (int j = oDiffBlock.iStartLine - ((bDeletion) ? 1 : 2); j >= oDiffBlock.iStartLine + ((bDeletion) ? 1 : 0) - iWhitespace - 1; j--) { if (j >= 0) { oDiffBlock.cLines.Insert(0, new DiffBlock.LineChange() { sAction = "*", sLine = cWhitespace[j] }); iNewLine = j + 1; } else { break; } } oDiffBlock.iStartLine = iNewLine; } if (iMode == 2 || iMode == 3) { //Bottom Whitespace int iNewLine = oDiffBlock.iEndLine; for (int j = oDiffBlock.iEndLine; j <= oDiffBlock.iEndLine + iWhitespace - 1; j++) { if (j <= cWhitespace.Count - 1) { oDiffBlock.cLines.Add(new DiffBlock.LineChange() { sAction = "*", sLine = cWhitespace[j] }); iNewLine = j + 1; } else { break; } } oDiffBlock.iEndLine = iNewLine; } return(oDiffBlock); }
private static Revision GetBaseVersion(Revision oRevision) { List <string> cLines = new List <string>(); if (oRevision.sState != "dead") { cLines = CVSCalls.RunCommand(oRevision.oFile.sPath, $"cvs co -r {oRevision.sRevision} -p \"{oRevision.oFile.sCVSPath}/{oRevision.oFile.sName}\""); } else { int iPrevRevision = int.Parse(oRevision.sRevision.Substring(oRevision.sRevision.LastIndexOf('.') + 1)) - 1; string sPrevRevision = oRevision.sRevision.Substring(0, oRevision.sRevision.LastIndexOf('.') + 1) + iPrevRevision.ToString(); cLines = CVSCalls.RunCommand(oRevision.oFile.sPath, $"cvs co -r {sPrevRevision} -p \"{oRevision.oFile.sCVSPath}/{oRevision.oFile.sName}\""); } DiffBlock oDiffBlock = new DiffBlock(); oDiffBlock.iStartLine = (cLines.Count == 0) ? 0 : 1; oDiffBlock.iEndLine = cLines.Count; List <DiffBlock.LineChange> cChanges = new List <DiffBlock.LineChange>(); for (int i = 0; i < cLines.Count; i++) { DiffBlock.LineChange oLineChange = new DiffBlock.LineChange() { sAction = (oRevision.sState != "dead")? "+" : "-", sLine = cLines[i] }; cChanges.Add(oLineChange); } oDiffBlock.cLines = cChanges; oRevision.cDiffBlocks.Add(oDiffBlock); oRevision.sLinesChanged = (oRevision.sState != "dead") ? $"+{cLines.Count} -0" : $"+0 -{cLines.Count}"; return(oRevision); }
private static Revision GetDiffPrevious(Revision oRevision, int iWhitespace) { int iPrevRevision = int.Parse(oRevision.sRevision.Substring(oRevision.sRevision.LastIndexOf('.') + 1)) - 1; string sPrevRevision = oRevision.sRevision.Substring(0, oRevision.sRevision.LastIndexOf('.') + 1) + iPrevRevision.ToString(); List <string> cWhitespace = CVSCalls.RunCommand(oRevision.oFile.sPath, $"cvs co -r {oRevision.sRevision} -p \"{oRevision.oFile.sCVSPath}/{oRevision.oFile.sName}\""); List <string> cLines = CVSCalls.RunCommand(oRevision.oFile.sPath, $"cvs diff -r {oRevision.sRevision} -r {sPrevRevision} \"{oRevision.oFile.sName}\""); DiffBlock oDiffBlock = new DiffBlock(); string sBlockKind = ""; for (int i = 6; i < cLines.Count; i++) { DiffBlock.LineChange oChange = new DiffBlock.LineChange(); if (string.IsNullOrEmpty(cLines[i])) { //Do nothing. } else if (cLines[i].Substring(0, 1) == "<") { oChange.sAction = "+"; oChange.sLine = cLines[i].Substring(2, cLines[i].Length - 2); oDiffBlock.cLines.Add(oChange); } else if (cLines[i].Substring(0, 1) == ">") { switch (sBlockKind) { case "a": oChange.sAction = "-"; break; case "d": oChange.sAction = "+"; break; default: oChange.sAction = "-"; break; } oChange.sLine = cLines[i].Substring(2, cLines[i].Length - 2); oDiffBlock.cLines.Add(oChange); } else if (cLines[i] == "---" || cLines[i].Substring(0, 1) == "\\") { //Do Nothing } else { Match oMatch = new Regex("([0-9]+),{0,1}([0-9]*)([adc]){1}").Match(cLines[i]); if (oDiffBlock.cLines.Count != 0) { oDiffBlock.sBlockKind = sBlockKind; oRevision.cDiffBlocks.Add(oDiffBlock); } oDiffBlock = new DiffBlock(); oDiffBlock.iStartLine = int.Parse(oMatch.Groups[1].Value); oDiffBlock.iEndLine = int.Parse((!string.IsNullOrWhiteSpace(oMatch.Groups[2].Value))? oMatch.Groups[2].Value : oMatch.Groups[1].Value); sBlockKind = oMatch.Groups[3].Value; } } oDiffBlock.sBlockKind = sBlockKind; oRevision.cDiffBlocks.Add(oDiffBlock); //Combine blocks that are close to each other and add whitespace as needed. bool bMergeRequired = false; DiffBlock oMergeInto = oRevision.cDiffBlocks[oRevision.cDiffBlocks.Count - 1]; for (int i = oRevision.cDiffBlocks.Count - 1; i >= 0; i--) { if (bMergeRequired) { foreach (DiffBlock.LineChange oLineChange in oRevision.cDiffBlocks[i].cLines) { oMergeInto.cLines.Insert(0, oLineChange); } oMergeInto.iStartLine = oRevision.cDiffBlocks[i].iStartLine; oMergeInto.sBlockKind = oRevision.cDiffBlocks[i].sBlockKind; oRevision.cDiffBlocks.RemoveAt(i); } else { //No merge means that the block needs bottom whitespace. oRevision.cDiffBlocks[i] = AddWhitespace(oRevision.cDiffBlocks[i], cWhitespace, iWhitespace, (oRevision.cDiffBlocks[i].sBlockKind == "a") ? true : false, 2); } if (i - 1 >= 0) { int iDiff = oRevision.cDiffBlocks[i].iStartLine - oRevision.cDiffBlocks[i - 1].iEndLine - 1; if (iDiff < iWhitespace * 2) { bMergeRequired = true; oMergeInto = oRevision.cDiffBlocks[i]; oMergeInto = AddWhitespace(oMergeInto, cWhitespace, iDiff, (oMergeInto.sBlockKind == "a") ? true : false, 1); } else { //it seems that the next block is far enough to treat them separately. Add max top whitespace. bMergeRequired = false; oRevision.cDiffBlocks[i] = AddWhitespace(oRevision.cDiffBlocks[i], cWhitespace, iWhitespace, (oRevision.cDiffBlocks[i].sBlockKind == "a") ? true : false, 1); } } else { //This is the top-most block in the list, so we need to add max top whitespace. oRevision.cDiffBlocks[i] = AddWhitespace(oRevision.cDiffBlocks[i], cWhitespace, iWhitespace, (oRevision.cDiffBlocks[i].sBlockKind == "a") ? true : false, 1); break; } } return(oRevision); }
public List <Commit> GetCommits(string sRootDirectory, string sFilter, string sLimit, List <CommitTag> cCommitTags) { List <Commit> cCommits = new List <Commit>(); using (SQLiteConnection oSQLiteConnection = SQLConnection()) { oSQLiteConnection.Open(); string sSQL = $@"SELECT Commits.*, Files.Name FileName, Files.Path FilePath, Files.LastUpdated FileLastUpdated, Files.CVSPath FileCVSPath, (SELECT IFNULL(count(TagID),0) FROM CommitTags WHERE CommitID = Commits.ID) HasTags FROM Commits LEFT JOIN Files ON Files.ID = Commits.FileID WHERE Commits.HASH IN ( SELECT DISTINCT Commits.HASH FROM Commits LEFT JOIN Files ON Files.ID = Commits.FileID WHERE Path LIKE '{sRootDirectory.Replace("'", @"''")}%' {sFilter} ORDER BY Date DESC, HASH ASC {sLimit} ) ORDER BY Date DESC, HASH ASC;"; Commit oCommit; Revision oRevision; string sPrevHash = null; using (SQLiteCommand oCmd = new SQLiteCommand(sSQL, oSQLiteConnection)) { using (SQLiteDataReader oReader = oCmd.ExecuteReader()) { while (oReader.Read()) { if (sPrevHash != oReader["HASH"].ToString()) { oCommit = new Commit { iID = int.Parse(oReader["ID"].ToString()), dDate = (DateTime)oReader["Date"], sAuthor = oReader["Author"].ToString(), sDescription = oReader["Description"].ToString(), sHASH = oReader["HASH"].ToString(), sShortHASH = oReader["HASH"].ToString().Substring(0, 7), sDescriptionTable = new System.IO.StringReader(oReader["Description"].ToString()).ReadLine() }; } else { oCommit = cCommits[cCommits.Count - 1]; } oRevision = new Revision { iCommitID = int.Parse(oReader["ID"].ToString()), sLinesChanged = oReader["LinesChanged"].ToString(), sRevision = oReader["Revision"].ToString(), sState = oReader["State"].ToString(), bReAdded = (int.Parse(oReader["ReAdded"].ToString()) == 1) ? true : false, oFile = new CVSFile() { iID = int.Parse(oReader["FileID"].ToString()), sName = oReader["FileName"].ToString(), sPath = oReader["FilePath"].ToString(), sCVSPath = oReader["FileCVSPath"].ToString(), dLastUpdated = (DateTime)oReader["FileLastUpdated"] }, iWhitespace = int.Parse(oReader["Whitespace"].ToString()) }; string sSQL2 = $@"SELECT DiffBlocks.*, DiffLines.'Action', DiffLines.Line FROM DiffBlocks LEFT JOIN DiffLines ON DiffLines.DiffBlockID = DiffBlocks.ID WHERE DiffBlocks.CommitID = {oReader["ID"].ToString()} ORDER BY DiffBlocks.ID, DiffLines.ID;"; using (SQLiteCommand oCmd2 = new SQLiteCommand(sSQL2, oSQLiteConnection)) { string sPrevBlockID = null; DiffBlock oDiffBlock = new DiffBlock(); DiffBlock.LineChange oLineChange; using (SQLiteDataReader oReader2 = oCmd2.ExecuteReader()) { while (oReader2.Read()) { if (sPrevBlockID != oReader2["ID"].ToString()) { oDiffBlock = new DiffBlock { iStartLine = int.Parse(oReader2["StartLine"].ToString()), iEndLine = int.Parse(oReader2["EndLine"].ToString()) }; sPrevBlockID = oReader2["ID"].ToString(); oRevision.cDiffBlocks.Add(oDiffBlock); } if (!string.IsNullOrWhiteSpace(oReader2["Action"].ToString())) { oLineChange = new DiffBlock.LineChange { sAction = oReader2["Action"].ToString(), sLine = oReader2["Line"].ToString() }; oDiffBlock.cLines.Add(oLineChange); } } } } if (oReader["HasTags"].ToString() != "0") { oRevision.cTags = GetTagsForCommit(int.Parse(oReader["ID"].ToString()), cCommitTags); } oCommit.cRevisions.Add(oRevision); if (sPrevHash != oReader["HASH"].ToString()) { cCommits.Add(oCommit); sPrevHash = oReader["HASH"].ToString(); } } } } oSQLiteConnection.Close(); } return(cCommits); }