Exemple #1
0
        internal static string Merge3Inputs(SlyceMergeResult merge, string userText, string prevGenText, string nextGenText)
        {
            //StringBuilder sb = new StringBuilder(1000);	// DMW_Changed: this is not used
            bool newlineAppended = false;

            newlineAppended = AppendNewLine(ref userText, newlineAppended);
            newlineAppended = AppendNewLine(ref prevGenText, newlineAppended);
            newlineAppended = AppendNewLine(ref nextGenText, newlineAppended);

            // DMW_Changed: remove all CrLfs
            const string pilcrowEth = "¶Ð";
            const char   ethChar    = 'Ð';

            // standardise linebreaks
            userText    = Common.Utility.StandardizeLineBreaks(userText, Common.Utility.LineBreaks.Windows);
            nextGenText = Common.Utility.StandardizeLineBreaks(nextGenText, Common.Utility.LineBreaks.Windows);
            prevGenText = Common.Utility.StandardizeLineBreaks(prevGenText, Common.Utility.LineBreaks.Windows);

            string[] userLines    = userText.Replace("\r\n", pilcrowEth).Split(ethChar);
            string[] nextGenLines = nextGenText.Replace("\r\n", pilcrowEth).Split(ethChar);
            string[] prevGenLines = prevGenText.Replace("\r\n", pilcrowEth).Split(ethChar);

            //string[] userLines = Slyce.Common.Utility.StandardizeLineBreaks(userText, Slyce.Common.Utility.LineBreaks.Windows).Split('\r\n');
            //string[] nextGenLines = Slyce.Common.Utility.StandardizeLineBreaks(nextGenText, Slyce.Common.Utility.LineBreaks.Windows).Split('\n');
            //string[] prevGenLines = Slyce.Common.Utility.StandardizeLineBreaks(prevGenText, Slyce.Common.Utility.LineBreaks.Windows).Split('\n');
            GetMergedOutput(merge, prevGenLines, userLines, nextGenLines);
            return(WriteLineTextArrayToList(merge.Lines, newlineAppended));
        }
Exemple #2
0
        /// <summary>
        /// Merge three text files
        /// </summary>
        /// <param name="userText">File with user changes</param>
        /// <param name="prevGenText">Previously generated file</param>
        /// <param name="newGenText">Newly generated file</param>
        /// <param name="mergedText">Merged file</param>
        /// <returns></returns>
        /// <param name="compareWhitespace">True if the whitespace should be counted as a change.</param>
        public static SlyceMergeResult Perform3wayDiff(string userText, string prevGenText, string newGenText, out string mergedText, bool compareWhitespace)
        {
            SlyceMergeResult slyceMerge = new SlyceMergeResult();

            mergedText = Merge3Inputs(slyceMerge, userText, prevGenText, newGenText);

            if (slyceMerge.DiffType == TypeOfDiff.ExactCopy)
            {
                // Successfully merged text (with no conflicts) always gets returned as 'EXACT_COPY',
                // so we need to perform a further test to see if it really is different.
                bool userFileIsIdentical   = FilesAreTheSame(userText, mergedText, true, compareWhitespace);
                bool newGenFileIsIdentical = FilesAreTheSame(newGenText, mergedText, true, compareWhitespace);

                if (!userFileIsIdentical || !newGenFileIsIdentical)
                {
                    if (!userFileIsIdentical && !newGenFileIsIdentical)
                    {
                        slyceMerge.DiffType = TypeOfDiff.UserAndTemplateChange;
                    }
                    else if (userFileIsIdentical)
                    {
                        slyceMerge.DiffType = TypeOfDiff.UserChangeOnly;
                    }
                    else                     // newGenFileIsIdentical
                    {
                        slyceMerge.DiffType = TypeOfDiff.TemplateChangeOnly;
                    }
                }
            }
            return(slyceMerge);
        }
Exemple #3
0
        /// <summary>
        /// Perform 3-way merge
        /// </summary>
        /// <returns>Merged text.</returns>
        /// <param name="merge"></param>
        /// <param name="prevGenLines">Previously generated version ie: 'base version'.</param>
        /// <param name="userLines">User-modified version of 'base'.</param>
        /// <param name="nextGenLines">Latest generated version of 'base'.</param>
        internal static string GetMergedOutput(SlyceMergeResult merge, string[] prevGenLines, string[] userLines, string[] nextGenLines)
        {
            // default values and initialisation
            merge.DiffType = TypeOfDiff.ExactCopy;
            merge.Lines    = new List <LineText>(200);
            string       output        = "";
            int          lineCounter   = -1;
            const string pilcrowString = "¶";
            const char   pilcrow       = '¶';

            // diff the User version and LatestGenerated version against the PrevGenerated version
            IList res = Merge.MergeLists(prevGenLines, new[] { userLines, nextGenLines });

            // handle empty input
            if (res.Count == 1 && res[0].Equals(string.Empty))
            {
                return(string.Empty);
            }
            string conflictTypeName = typeof(Merge.Conflict).FullName;

            // process each line from the diff
            foreach (object line in res)
            {
                lineCounter++;
                string lineTypeName = line.GetType().ToString();

                if (lineTypeName == "System.String")
                {
                    string thisLine = (string)line;
                    merge.Lines.Add(new LineText(thisLine.Replace(pilcrowString, ""), lineCounter, TypeOfLine.Normal));
                }
                else if (lineTypeName == conflictTypeName)
                {
                    Merge.Conflict conf        = (Merge.Conflict)line;
                    Range[]        ranges      = conf.Ranges;
                    Range          rangeUser   = ranges[0];
                    Range          rangeNewGen = ranges[1];

                    string[] conflictUserLines   = GetLinesFromRange(userLines, rangeUser);
                    string[] conflictNewGenLines = GetLinesFromRange(nextGenLines, rangeNewGen);

                    // Get diff of the conflicts
                    Diff diff = new Diff(conflictUserLines, conflictNewGenLines, true, false);

                    foreach (Diff.Hunk hunk in diff)
                    {
                        if (hunk.Same)
                        {
                            string same = GetPortionOfString(conflictUserLines, hunk.Left.Start, hunk.Left.End);
                            same    = RemoveTrailingCharacter(pilcrowString, same);
                            same    = same.Replace(pilcrowString, "\r\n");
                            output += same;
                            merge.Lines.Add(new LineText(same, lineCounter, TypeOfLine.Normal));
                        }
                        else
                        {
                            // Get the user modified lines
                            string userPortion = GetPortionOfString(conflictUserLines, hunk.Left.Start, hunk.Left.End);
                            userPortion = RemoveTrailingCharacter(pilcrowString, userPortion);

                            // Get the newly generated lines
                            string newGenPortion = GetPortionOfString(conflictNewGenLines, hunk.Right.Start, hunk.Right.End);
                            newGenPortion = RemoveTrailingCharacter(pilcrowString, newGenPortion);

                            merge.SetDiffType(TypeOfDiff.Conflict);
                            TypeOfLine lineType = newGenPortion.Length > 0 ? TypeOfLine.User : TypeOfLine.Normal;

                            string[] userSplitLines = userPortion.Split(pilcrow);
                            if (userPortion.Length > 0)
                            {
                                merge.Lines.Add(new LineText(userSplitLines[0], lineCounter, lineType));
                            }
                            for (int myCount = 1; myCount < userSplitLines.Length; myCount++)
                            {
                                lineCounter++;
                                merge.Lines.Add(new LineText(userSplitLines[myCount], lineCounter, lineType));
                            }

                            lineType = userPortion.Length > 0 ? TypeOfLine.NewGen : TypeOfLine.Normal;
                            string[] newGenSplitLines = newGenPortion.Split(pilcrow);
                            if (newGenPortion.Length > 0)
                            {
                                merge.Lines.Add(new LineText(newGenSplitLines[0], lineCounter, lineType));
                            }
                            for (int myCount = 1; myCount < newGenSplitLines.Length; myCount++)
                            {
                                lineCounter++;
                                merge.Lines.Add(new LineText(newGenSplitLines[myCount], lineCounter, lineType));
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception(string.Format("Unexpected line type: {0}\nText1:{1}\n\nText2:{2}\n\nText3:{3}", line.GetType(), prevGenLines, userLines, nextGenLines));
                }
            }
            return(output);
        }
Exemple #4
0
        internal static string Merge3Inputs(SlyceMergeResult merge, string userText, string prevGenText, string nextGenText)
        {
            //StringBuilder sb = new StringBuilder(1000);	// DMW_Changed: this is not used
            bool newlineAppended = false;

            newlineAppended = AppendNewLine(ref userText, newlineAppended);
            newlineAppended = AppendNewLine(ref prevGenText, newlineAppended);
            newlineAppended = AppendNewLine(ref nextGenText, newlineAppended);

            // DMW_Changed: remove all CrLfs
            const string pilcrowEth = "¶Ð";
            const char ethChar = 'Ð';

            // standardise linebreaks
            userText = Common.Utility.StandardizeLineBreaks(userText, Common.Utility.LineBreaks.Windows);
            nextGenText = Common.Utility.StandardizeLineBreaks(nextGenText, Common.Utility.LineBreaks.Windows);
            prevGenText = Common.Utility.StandardizeLineBreaks(prevGenText, Common.Utility.LineBreaks.Windows);

            string[] userLines = userText.Replace("\r\n", pilcrowEth).Split(ethChar);
            string[] nextGenLines = nextGenText.Replace("\r\n", pilcrowEth).Split(ethChar);
            string[] prevGenLines = prevGenText.Replace("\r\n", pilcrowEth).Split(ethChar);

            //string[] userLines = Slyce.Common.Utility.StandardizeLineBreaks(userText, Slyce.Common.Utility.LineBreaks.Windows).Split('\r\n');
            //string[] nextGenLines = Slyce.Common.Utility.StandardizeLineBreaks(nextGenText, Slyce.Common.Utility.LineBreaks.Windows).Split('\n');
            //string[] prevGenLines = Slyce.Common.Utility.StandardizeLineBreaks(prevGenText, Slyce.Common.Utility.LineBreaks.Windows).Split('\n');
            GetMergedOutput(merge, prevGenLines, userLines, nextGenLines);
            return WriteLineTextArrayToList(merge.Lines, newlineAppended);
        }
Exemple #5
0
        /// <summary>
        /// Perform 3-way merge
        /// </summary>
        /// <returns>Merged text.</returns>
        /// <param name="merge"></param>
        /// <param name="prevGenLines">Previously generated version ie: 'base version'.</param>
        /// <param name="userLines">User-modified version of 'base'.</param>
        /// <param name="nextGenLines">Latest generated version of 'base'.</param>
        internal static string GetMergedOutput(SlyceMergeResult merge, string[] prevGenLines, string[] userLines, string[] nextGenLines)
        {
            // default values and initialisation
            merge.DiffType = TypeOfDiff.ExactCopy;
            merge.Lines = new List<LineText>(200);
            string output = "";
            int lineCounter = -1;
            const string pilcrowString = "¶";
            const char pilcrow = '¶';

            // diff the User version and LatestGenerated version against the PrevGenerated version
            IList res = Merge.MergeLists(prevGenLines, new[] { userLines, nextGenLines });

            // handle empty input
            if (res.Count == 1 && res[0].Equals(string.Empty))
            {
                return string.Empty;
            }
            string conflictTypeName = typeof(Merge.Conflict).FullName;

            // process each line from the diff
            foreach (object line in res)
            {
                lineCounter++;
                string lineTypeName = line.GetType().ToString();

                if (lineTypeName == "System.String")
                {
                    string thisLine = (string)line;
                    merge.Lines.Add(new LineText(thisLine.Replace(pilcrowString, ""), lineCounter, TypeOfLine.Normal));
                }
                else if (lineTypeName == conflictTypeName)
                {
                    Merge.Conflict conf = (Merge.Conflict)line;
                    Range[] ranges = conf.Ranges;
                    Range rangeUser = ranges[0];
                    Range rangeNewGen = ranges[1];

                    string[] conflictUserLines = GetLinesFromRange(userLines, rangeUser);
                    string[] conflictNewGenLines = GetLinesFromRange(nextGenLines, rangeNewGen);

                    // Get diff of the conflicts
                    Diff diff = new Diff(conflictUserLines, conflictNewGenLines, true, false);

                    foreach (Diff.Hunk hunk in diff)
                    {
                        if (hunk.Same)
                        {
                            string same = GetPortionOfString(conflictUserLines, hunk.Left.Start, hunk.Left.End);
                            same = RemoveTrailingCharacter(pilcrowString, same);
                            same = same.Replace(pilcrowString, "\r\n");
                            output += same;
                            merge.Lines.Add(new LineText(same, lineCounter, TypeOfLine.Normal));
                        }
                        else
                        {
                            // Get the user modified lines
                            string userPortion = GetPortionOfString(conflictUserLines, hunk.Left.Start, hunk.Left.End);
                            userPortion = RemoveTrailingCharacter(pilcrowString, userPortion);

                            // Get the newly generated lines
                            string newGenPortion = GetPortionOfString(conflictNewGenLines, hunk.Right.Start, hunk.Right.End);
                            newGenPortion = RemoveTrailingCharacter(pilcrowString, newGenPortion);

                            merge.SetDiffType(TypeOfDiff.Conflict);
                            TypeOfLine lineType = newGenPortion.Length > 0 ? TypeOfLine.User : TypeOfLine.Normal;

                            string[] userSplitLines = userPortion.Split(pilcrow);
                            if (userPortion.Length > 0)
                            {
                                merge.Lines.Add(new LineText(userSplitLines[0], lineCounter, lineType));
                            }
                            for (int myCount = 1; myCount < userSplitLines.Length; myCount++)
                            {
                                lineCounter++;
                                merge.Lines.Add(new LineText(userSplitLines[myCount], lineCounter, lineType));
                            }

                            lineType = userPortion.Length > 0 ? TypeOfLine.NewGen : TypeOfLine.Normal;
                            string[] newGenSplitLines = newGenPortion.Split(pilcrow);
                            if (newGenPortion.Length > 0)
                            {
                                merge.Lines.Add(new LineText(newGenSplitLines[0], lineCounter, lineType));
                            }
                            for (int myCount = 1; myCount < newGenSplitLines.Length; myCount++)
                            {
                                lineCounter++;
                                merge.Lines.Add(new LineText(newGenSplitLines[myCount], lineCounter, lineType));
                            }
                        }
                    }
                }
                else
                {
                    throw new Exception(string.Format("Unexpected line type: {0}\nText1:{1}\n\nText2:{2}\n\nText3:{3}", line.GetType(), prevGenLines, userLines, nextGenLines));
                }
            }
            return output;
        }
Exemple #6
0
        /// <summary>
        /// Merge three text files
        /// </summary>
        /// <param name="userText">File with user changes</param>
        /// <param name="prevGenText">Previously generated file</param>
        /// <param name="newGenText">Newly generated file</param>
        /// <param name="mergedText">Merged file</param>
        /// <returns></returns>
        /// <param name="compareWhitespace">True if the whitespace should be counted as a change.</param>
        public static SlyceMergeResult Perform3wayDiff(string userText, string prevGenText, string newGenText, out string mergedText, bool compareWhitespace)
        {
            SlyceMergeResult slyceMerge = new SlyceMergeResult();
            mergedText = Merge3Inputs(slyceMerge, userText, prevGenText, newGenText);

            if (slyceMerge.DiffType == TypeOfDiff.ExactCopy)
            {
                // Successfully merged text (with no conflicts) always gets returned as 'EXACT_COPY',
                // so we need to perform a further test to see if it really is different.
                bool userFileIsIdentical = FilesAreTheSame(userText, mergedText, true, compareWhitespace);
                bool newGenFileIsIdentical = FilesAreTheSame(newGenText, mergedText, true, compareWhitespace);

                if (!userFileIsIdentical || !newGenFileIsIdentical)
                {
                    if (!userFileIsIdentical && !newGenFileIsIdentical)
                    {
                        slyceMerge.DiffType = TypeOfDiff.UserAndTemplateChange;
                    }
                    else if (userFileIsIdentical)
                    {
                        slyceMerge.DiffType = TypeOfDiff.UserChangeOnly;
                    }
                    else // newGenFileIsIdentical
                    {
                        slyceMerge.DiffType = TypeOfDiff.TemplateChangeOnly;
                    }
                }
            }
            return slyceMerge;
        }