示例#1
0
        public void DiffWorkers_DoWork(object sender, DoWorkEventArgs e)
        {
            Revision oRevision = (Revision)e.Argument;

            //Check if it was canceled a few moments after being started.
            if (((BackgroundWorker)sender).CancellationPending)
            {
                return;
            }

            while (cDiffWorkers.Count > 3)
            {
                if (sender == cDiffWorkers[0])
                {
                    break;
                }
                //There are already 3 works busy, so wait a moment to give them time to finish.
                System.Threading.Thread.Sleep(400);
            }

            oRevision = CVSCalls.GetDiff(oRevision);
            e.Result  = oRevision;

            oDatabase.SaveDiff(oRevision);
        }
示例#2
0
        public static Revision GetDiff(Revision oRevision)
        {
            if (oRevision.sRevision.EndsWith(".1") || oRevision.bReAdded || oRevision.sState == "dead")
            {
                oRevision = CVSCalls.GetBaseVersion(oRevision);
            }
            else
            {
                oRevision = CVSCalls.GetDiffPrevious(oRevision, oRevision.iWhitespace);
            }

            return(oRevision);
        }
示例#3
0
        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);
        }
示例#4
0
        public static List <Commit> GetCommits(CVSFile oFile, List <Tag> cTags)
        {
            List <Commit> cCommits = new List <Commit>();

            //Check if it's an CVS related File; those can be ignored.
            string sTest = oFile.sPath + "\\" + oFile.sName;

            if (sTest.Contains("CVS\\Repository") || sTest.Contains("CVS\\Root") || sTest.Contains("CVS\\Entries") || sTest.Contains("CVS\\Baserev"))
            {
                Console.WriteLine($"Ignored: {oFile.sPath}\\{oFile.sName}");
                oFile.bIgnored = true;
                return(cCommits);
            }

            List <string> cLines = CVSCalls.RunCommand(oFile.sPath, $"cvs log \"{oFile.sName}\"");

            //If output is just 5 line, it probably means the file is not known in cvs (yet) or some other error.
            if (cLines.Count <= 5)
            {
                Console.WriteLine($"No Data: {oFile.sPath}\\{oFile.sName}");
                return(cCommits);
            }

            int iLine = 0;
            List <KeyValuePair <string, string> > cRawTags = new List <KeyValuePair <string, string> >();
            string sRCS = null;

            if (oFile.iID == 0)
            {
                if (cLines[1].Contains("RCS file:"))
                {
                    sRCS = cLines[1].Replace("RCS file: ", "").Replace("/" + oFile.sName + ",v", "");
                }
            }

            //Find begin of symbolic names.
            for (int i = iLine; i < cLines.Count; i++)
            {
                if (cLines[i].Contains("symbolic names:"))
                {
                    iLine = i + 1;
                    break;
                }
            }

            //Process symbolic names (aka tags).
            for (int i = iLine; i < cLines.Count; i++)
            {
                if (cLines[i].Contains("keyword substitution:"))
                {
                    iLine = i + 1;
                    break;
                }

                string[] aRawTag = cLines[i].Split(':');

                KeyValuePair <string, string> oRawTag = new KeyValuePair <string, string>(
                    aRawTag[0].Trim(new char[] { ' ', (char)9 }),
                    aRawTag[1].TrimStart(' ')
                    );

                cRawTags.Add(oRawTag);
            }

            //Find begin of commits
            for (int i = iLine; i < cLines.Count; i++)
            {
                if (cLines[i].Contains("description:"))
                {
                    iLine = i + 1;
                    break;
                }
            }

            //Process commits
            for (int i = iLine; i < cLines.Count; i++)
            {
                Commit   oCommit   = new Commit();
                Revision oRevision = new Revision();

                oRevision.sRevision = cLines[i + 1].Replace("revision ", "");

                Match oMatch;

                oMatch = new Regex("date: (.*?);").Match(cLines[i + 2]);

                oCommit.dDate = GlobalFunctions.ParseDateTime(oMatch.Groups[1].ToString());

                oCommit.sAuthor         = new Regex("author: (.*?);").Match(cLines[i + 2]).Groups[1].ToString();
                oRevision.sState        = new Regex("state: (.*?);").Match(cLines[i + 2]).Groups[1].ToString();
                oRevision.sLinesChanged = new Regex("lines: (.*)").Match(cLines[i + 2]).Groups[1].ToString();

                int iDescriptionStart = 3;

                if (cLines[i + 3].Contains("branches:"))
                {
                    iDescriptionStart = 4;
                }

                oCommit.sDescription = cLines[i + iDescriptionStart];

                //Collect additional description lines
                for (int j = i + iDescriptionStart + 1; j < cLines.Count; j++)
                {
                    if (cLines[j] == "----------------------------" ||
                        cLines[j] == "=============================================================================")
                    {
                        i = j - 1;
                        break;
                    }
                    else
                    {
                        oCommit.sDescription += Environment.NewLine + cLines[j];
                    }
                }

                oCommit.sDescription = oCommit.sDescription.Trim();

                //Tags
                foreach (KeyValuePair <string, string> oRawTag in cRawTags)
                {
                    if (oRawTag.Value == oRevision.sRevision)
                    {
                        bool bFound = false;
                        foreach (Tag oTag in cTags)
                        {
                            if (oTag.sLabel == oRawTag.Key)
                            {
                                bFound = true;
                                oRevision.cTags.Add(oTag);
                                break;
                            }
                        }

                        if (!bFound)
                        {
                            Tag oNewTag = new Tag {
                                iID = 0, sLabel = oRawTag.Key
                            };

                            oRevision.cTags.Add(oNewTag);
                            cTags.Add(oNewTag);
                        }
                    }
                }

                //HASH
                using (SHA1Managed sha1 = new SHA1Managed())
                {
                    byte[]        aHash = sha1.ComputeHash(Encoding.UTF8.GetBytes(oCommit.sAuthor + oCommit.dDate.ToString() + oCommit.sDescription));
                    StringBuilder oSB   = new StringBuilder(aHash.Length * 2);

                    foreach (byte b in aHash)
                    {
                        //X2 = Upper Case
                        oSB.Append(b.ToString("X2"));
                    }

                    oCommit.sHASH = oSB.ToString();
                }

                oRevision.oFile = oFile;

                //Check if this file was re-added to the repository.
                if (cCommits.Count > 0 && !oRevision.bReAdded)
                {
                    if (cCommits[cCommits.Count - 1].cRevisions[0].sState != "dead" && oRevision.sState == "dead")
                    {
                        cCommits[cCommits.Count - 1].cRevisions[0].bReAdded = true;
                    }
                }

                //Finally
                oCommit.cRevisions.Add(oRevision);
                cCommits.Add(oCommit);

                //Check if there is another commit coming or not.
                if (cLines.Count - 1 - i < 5)
                {
                    break;
                }
            }

            //Set CVS Path for File Object
            if (oFile.iID == 0 && !string.IsNullOrWhiteSpace(sRCS))
            {
                if (cCommits[0].cRevisions[0].sState == "dead")
                {
                    sRCS = sRCS.Replace("/Attic", "");
                }

                string[] aSplitTempRCS = sRCS.Split('/');

                List <string> cSplitRCS = new List <string>();
                foreach (string sPart in aSplitTempRCS)
                {
                    if (!string.IsNullOrWhiteSpace(sPart))
                    {
                        string[] aSplitTemp2RCS = sPart.Split('\\');
                        foreach (string sPart2 in aSplitTemp2RCS)
                        {
                            if (!string.IsNullOrWhiteSpace(sPart2))
                            {
                                cSplitRCS.Add(sPart2);
                            }
                        }
                    }
                }

                List <string> cSplitFile = new List <string>(oFile.sPath.Split('\\'));

                int iCount = 0;
                if (cSplitRCS.Count < cSplitFile.Count)
                {
                    iCount = cSplitRCS.Count;
                }
                else
                {
                    iCount = cSplitFile.Count;
                }

                int iRCSIndex  = cSplitRCS.Count - 1;
                int iFileIndex = cSplitFile.Count - 1;

                List <string> cMatches = new List <string>();
                for (int g = iCount - 1; g >= 0; g--)
                {
                    if (cSplitRCS[iRCSIndex] == cSplitFile[iFileIndex--])
                    {
                        cMatches.Add(cSplitRCS[iRCSIndex--]);
                    }
                    else
                    {
                        break;
                    }
                }

                for (int g = cMatches.Count - 1; g >= 0; g--)
                {
                    oFile.sCVSPath += cMatches[g] + ((g != 0) ? "/" : "");
                }
            }

            return(cCommits);
        }
示例#5
0
        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);
        }