示例#1
0
        private void ProcessConflict(Merge.Conflict conflict)
        {
            string[] userLines = SlyceMerge.GetLinesFromRange(user, conflict.Ranges[Merge.UserIndex]);
            string[] newgenLines = SlyceMerge.GetLinesFromRange(newgen, conflict.Ranges[Merge.NewGenIndex]);

            if (userLines.Length == 0 && newgenLines.Length == 0)
            {
                // user and template have both deleted some lines. Add them in as virtual lines.
                foreach (string line in SlyceMerge.GetLinesFromRange(prevgen, conflict.Ranges[Merge.PrevGenIndex]))
                {
                    vdo.AddLineToLeft(line, ChangeType.UserAndTemplate);
                }

                return;
            }

            Diff diff = new Diff(userLines, newgenLines, true, true);

            foreach (Diff.Hunk hunk in diff)
            {
                if (hunk.Same)
                {
                    foreach (string line in hunk.Original())
                    {
                        vdo.AddLine(line, ChangeType.None);
                    }
                    continue;
                }

                // Conflict
                VisualDiffOutput.ConflictRange crange = new VisualDiffOutput.ConflictRange();
                crange.StartLineIndex = vdo.LeftLines.Count;
                for (int i = hunk.Left.Start; i <= hunk.Left.End; i++)
                {
                    vdo.LeftLines.Add(new DiffLine(userLines[i], ChangeType.User));
                    vdo.RightLines.Add(new DiffLine("", ChangeType.User, true));
                }
                for (int i = hunk.Right.Start; i <= hunk.Right.End; i++)
                {
                    vdo.LeftLines.Add(new DiffLine(newgenLines[i], ChangeType.Template));
                    vdo.RightLines.Add(new DiffLine("", ChangeType.Template, true));
                }
                crange.EndLineIndex = vdo.LeftLines.Count;
                vdo.ConflictRanges.Add(crange);
                vdo.DiffType = TypeOfDiff.Conflict;
            }
        }
示例#2
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);
        }