public void The_merged_file_needs_careful_testing() { // inputs string fileBodyLeft = Helper.GetResource(resourcePrefix + "MultiDiffs_Left.txt"); string fileBodyRight = Helper.GetResource(resourcePrefix + "MultiDiffs_Right.txt"); string fileExpected = Helper.GetResource(resourcePrefix + "MultiDiffs_Expected.txt"); TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsAndRegions, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.Conflict, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(fileExpected.Trim(), mergedText.Trim(), "Combined file should equal expected file."); int leftConflictLinesMax = leftConflictLines.GetUpperBound(0); Assert.AreEqual(7, leftConflictLinesMax, "Should be 8 left lines in conflict."); int rightConflictLinesMax = rightConflictLines.GetUpperBound(0); Assert.AreEqual(7, rightConflictLinesMax, "Should be 8 right lines in conflict."); Assert.AreEqual(0, leftConflictLines[0].StartLine, "Left conflict lines should start at line 1 (index 0)."); Assert.AreEqual(23, leftConflictLines[leftConflictLinesMax].StartLine, "Last left conflict line should start at line 24 (index 23)."); Assert.AreEqual(2, rightConflictLines[0].StartLine, "Right conflict lines should start at line 3 (index 2)."); Assert.AreEqual(25, rightConflictLines[rightConflictLinesMax].EndLine, "Last right conflict lines should start at line 26 (index 25)."); }
public void AssertDiffType(string prevgenFilename, string userFilename, string templateFilename, TypeOfDiff typeOfDiff) { CodeRoot prevgen = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, prevgenFilename)); CodeRoot template = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, templateFilename)); CodeRoot user = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, userFilename)); CodeRootMap map = new CodeRootMap(); if (prevgen != null) { map.AddCodeRoot(prevgen, Version.PrevGen); } if (template != null) { map.AddCodeRoot(template, Version.NewGen); } if (user != null) { map.AddCodeRoot(user, Version.User); } TypeOfDiff diff = map.Diff(); Assert.That(diff, Is.EqualTo(typeOfDiff)); }
private void RaiseDiffFinishedEvent(string filename, TypeOfDiff diffType) { if (DiffFinished != null) { DiffFinished(filename, diffType); } }
/// <summary> /// Null to visibility conversion method /// </summary> /// <param name="value"></param> /// <param name="targetType"></param> /// <param name="parameter"></param> /// <param name="culture"></param> /// <returns></returns> public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) { return(Binding.DoNothing); } if ((value is TypeOfDiff) == false) { return(Binding.DoNothing); } TypeOfDiff d = (TypeOfDiff)value; switch (d) { case TypeOfDiff.SourceOnly: return("This string exists only in the source language."); case TypeOfDiff.TargetOnly: return("This string exists only in the target language."); case TypeOfDiff.SourceAndTarget: return("This string exists in both the target and source language (but has not been checked by a nativ speaker)."); default: throw new NotImplementedException(d.ToString()); } }
/// <summary> /// Parameterized class constructor /// </summary> /// <param name="item"></param> /// <param name="difference"></param> public EntryDiffViewModel(string key, string value, string comment, int rowid, TypeOfDiff difference = TypeOfDiff.SourceOnly) : this() { Parent = null; mTranslationDiff = new EntryDiffModel(key, value, comment, difference); }
public static TypeOfDiff CombineChildDiffTypes(TypeOfDiff diff1, TypeOfDiff diff2) { if (diff1 == diff2) { return(diff1); } if (diff1 == TypeOfDiff.Conflict || diff2 == TypeOfDiff.Conflict) { return(TypeOfDiff.Conflict); } if (diff1 == TypeOfDiff.Warning || diff2 == TypeOfDiff.Warning) { return(TypeOfDiff.Warning); } if (diff1 == TypeOfDiff.Unknown || diff2 == TypeOfDiff.Unknown) { return(TypeOfDiff.Unknown); } if (diff1 == TypeOfDiff.ExactCopy) { return(diff2); } if (diff2 == TypeOfDiff.ExactCopy) { return(diff1); } switch (diff1) { case TypeOfDiff.TemplateChangeOnly: if (diff2 == TypeOfDiff.UserChangeOnly) { return(TypeOfDiff.UserAndTemplateChange); } if (diff2 == TypeOfDiff.UserAndTemplateChange) { return(TypeOfDiff.UserAndTemplateChange); } break; case TypeOfDiff.UserChangeOnly: if (diff2 == TypeOfDiff.TemplateChangeOnly) { return(TypeOfDiff.UserAndTemplateChange); } if (diff2 == TypeOfDiff.UserAndTemplateChange) { return(TypeOfDiff.UserAndTemplateChange); } break; case TypeOfDiff.UserAndTemplateChange: return(TypeOfDiff.UserAndTemplateChange); } return(TypeOfDiff.Unknown); }
/// <summary> /// This function does the actual conversion from enum to <seealso cref="BitmapImage"/>. /// </summary> /// <param name="image"></param> /// <returns></returns> public BitmapImage SetImageSource(TypeOfDiff image) { BitmapImage ret = null; switch (image) { case TypeOfDiff.SourceOnly: ret = GetApplicationResource("IconImage_SourceOnly"); break; case TypeOfDiff.TargetOnly: ret = GetApplicationResource("IconImage_TargetOnly"); break; case TypeOfDiff.SourceAndTarget: ret = GetApplicationResource("IconImage_SourceAndTarget"); break; default: throw new NotImplementedException(image.ToString()); } // just return dynamic resource if we found one // otherwise fall-through here and return back up image (which is hopefully where it should be) if (ret != null) { return(ret); } string resourceAssembly = Assembly.GetAssembly(typeof(TypeOfDiffToImageConverter)).GetName().Name; string folder = "Images/TypeOfDiffState/"; // Tango Icon set: http://commons.wikimedia.org/wiki/Tango_icons // Default image displayed in message box string source = string.Format("pack://application:,,,/{0};component/{1}48px-Dialog-information_on.svg.png", resourceAssembly, folder); try { source = string.Format("pack://application:,,,/{0};component/{1}{2}", resourceAssembly, folder, TypeOfDiffToImageConverter.msgBoxImageResourcesUris[(int)image]); } catch (Exception) { } Uri imageUri = new Uri(source, UriKind.RelativeOrAbsolute); return(new BitmapImage(imageUri)); }
/// <summary> /// Returns the combined diff type of this node and all of its children. /// </summary> /// <returns>The combined diff type of this node and all of its children.</returns> public override TypeOfDiff Diff() { if (coderoots.GetFirstNonNullObject() == null) { throw new InvalidOperationException("Cannot perform a diff if no CodeRoots have been added."); } TypeOfDiff diff = TypeOfDiff.ExactCopy; DiffTypeExcludingChildren = TypeOfDiff.ExactCopy; // Diff the coderoots, looking at more than a basic signature comparison but not looking at children (we have already done that above) if (coderoots.PrevGen == null) { if (coderoots.NewGen == null) { return(TypeOfDiff.ExactCopy); } if (coderoots.User == null) { return(TypeOfDiff.ExactCopy); } TwoWayDiffWhenPrevGenMissing = true; } else { if (coderoots.PrevGen.IsTheSame(coderoots.NewGen, ComparisonDepth.Outer) == false) { // If NewGen is null, this will return false. DiffTypeExcludingChildren = CombineChildDiffTypes(DiffTypeExcludingChildren, TypeOfDiff.TemplateChangeOnly); } if (coderoots.PrevGen.IsTheSame(coderoots.User, ComparisonDepth.Outer) == false) { // If User is null, this will return false. DiffTypeExcludingChildren = CombineChildDiffTypes(DiffTypeExcludingChildren, TypeOfDiff.UserChangeOnly); } if (DiffTypeExcludingChildren == TypeOfDiff.Conflict && coderoots.NewGen.IsTheSame(coderoots.User, ComparisonDepth.Outer)) { DiffTypeExcludingChildren = TypeOfDiff.UserAndTemplateChange; } } // Diff the children foreach (CodeRootMapNode node in children) { diff = CombineChildDiffTypes(diff, node.Diff()); } diff = CombineChildDiffTypes(DiffTypeExcludingChildren, diff); TwoWayDiffWhenPrevGenMissing = false; return(diff); }
/// <summary> /// Gets the type of diff for the current object. Also sets the lowest common denominator diff type for the diffFile. /// </summary> /// <param name="diffFile"></param> /// <param name="userFileExists"></param> /// <param name="parentFileExists"></param> /// <param name="userEntityFound"></param> /// <param name="parentEntityFound"></param> /// <returns>The type of diff of the current object.</returns> private TypeOfDiff SetDiffType(DiffFile diffFile, bool userFileExists, bool parentFileExists, bool userEntityFound, bool parentEntityFound) { TypeOfDiff newDiffType = TypeOfDiff.ExactCopy; if (userFileExists && parentFileExists) { if (userEntityFound && parentEntityFound) { newDiffType = TypeOfDiff.ExactCopy; } else if (userEntityFound && !parentEntityFound) { newDiffType = TypeOfDiff.TemplateChangeOnly; } else if (!userEntityFound && parentEntityFound) { newDiffType = TypeOfDiff.UserChangeOnly; } else if (!userEntityFound && !parentEntityFound) { newDiffType = TypeOfDiff.UserAndTemplateChange; } } else if (userFileExists && !parentFileExists) { if (userEntityFound) { newDiffType = TypeOfDiff.ExactCopy; } else { newDiffType = TypeOfDiff.UserChangeOnly; } } else if (!userFileExists && parentFileExists) { if (parentEntityFound) { newDiffType = TypeOfDiff.ExactCopy; } else { newDiffType = TypeOfDiff.UserChangeOnly; } } TypeOfDiff currentDiffType = diffFile.DiffType; diffFile.DiffType = ArchAngel.Providers.CodeProvider.CSharp.Utility.ModifyTypeOfDiff(currentDiffType, newDiffType); return(newDiffType); }
public void AssertDiffType(string prevgenFilename, string userFilename, string templateFilename, TypeOfDiff typeOfDiff) { CodeRoot prevgen = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, prevgenFilename)); CodeRoot template = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, templateFilename)); CodeRoot user = GetCodeRoot(Path.Combine(RESOURCES_FOLDER, userFilename)); CodeRootMap map = new CodeRootMap(); if(prevgen != null) map.AddCodeRoot(prevgen, Version.PrevGen); if (template != null) map.AddCodeRoot(template, Version.NewGen); if (user != null) map.AddCodeRoot(user, Version.User); TypeOfDiff diff = map.Diff(); Assert.That(diff, Is.EqualTo(typeOfDiff)); }
public void The_merged_file_is_empty() { // inputs string fileBodyLeft = string.Empty; string fileBodyRight = string.Empty; TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsOnly, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.ExactCopy, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(-1, leftConflictLines.GetUpperBound(0), "Left conflict lines should be zero."); Assert.AreEqual(-1, rightConflictLines.GetUpperBound(0), "Right conflict lines should be zero."); Assert.AreEqual(0, mergedText.Length, "Combined length should equal start length."); }
public void The_merged_file_equals_the_nonempty_file() { // inputs (test opposite order) string fileBodyLeft = string.Empty; string fileBodyRight = File.ReadAllText(@"..\..\Notes.txt"); TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsAndRegions, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.Warning, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(-1, leftConflictLines.GetUpperBound(0), "Left conflict lines should be > zero."); Assert.AreEqual(0, rightConflictLines.GetUpperBound(0), "Right conflict lines should be zero."); Assert.AreEqual(fileBodyRight.Trim(), mergedText.Trim(), "Merged text should equal start text."); }
public void The_merged_file_equals_the_left_file() { // inputs string fileBodyLeft = Helper.GetResource(resourcePrefix + "ThreeLines.txt"); string fileBodyRight = Helper.GetResource(resourcePrefix + "TwoLines.txt"); TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsAndRegions, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.Warning, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(0, leftConflictLines.GetUpperBound(0), "Left conflict lines should be zero."); Assert.AreEqual(-1, rightConflictLines.GetUpperBound(0), "Right conflict lines should be > zero."); Assert.AreEqual(fileBodyLeft.Trim(), mergedText.Trim(), "Left file should equal combined file."); }
/// <summary> /// Parameterized class constructor. /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="comment"></param> /// <param name="difference"></param> public EntryDiffModel(string key, string value, string comment, TypeOfDiff difference = TypeOfDiff.SourceOnly) : this() { switch (difference) { case TypeOfDiff.SourceOnly: SourceEntry = new Entry(key, value, comment); break; case TypeOfDiff.TargetOnly: TargetEntry = new Entry(key, value, comment); break; default: throw new System.NotImplementedException(difference.ToString()); } }
public void The_result_is_LeftFile_plus_RightFile() { // inputs string fileBodyLeft = Helper.GetResource(resourcePrefix + "ThreeLines.txt"); string fileBodyRight = Helper.GetResource(resourcePrefix + "ThreeDiffLines.txt"); string fileExpected = Helper.GetResource(resourcePrefix + "AllLinesDifferent_Expected.txt"); TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsAndRegions, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.Conflict, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(fileExpected.Trim(), mergedText.Trim(), "Combined file should equal expected file."); Assert.AreEqual(2, leftConflictLines.GetUpperBound(0), "Should be one left line in conflict."); Assert.AreEqual(2, rightConflictLines.GetUpperBound(0), "Should be one right line in conflict."); Assert.AreEqual(0, leftConflictLines[0].StartLine, "Left conflict lines should start at line 1 (index 0)."); Assert.AreEqual(3, rightConflictLines[0].StartLine, "Right conflict lines should start at line 4 (index 3)."); }
public void The_left_conflict_lines_start_from_0() { // inputs string fileBodyLeft = Helper.GetResource(resourcePrefix + "ThreeLines.txt"); string fileBodyRight = Helper.GetResource(resourcePrefix + "ThreeLines_FirstLineChanged.txt"); string fileExpected = Helper.GetResource(resourcePrefix + "FirstLineDifferent_Expected.txt"); TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsAndRegions, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); Assert.AreEqual(TypeOfDiff.Conflict, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(fileExpected.Trim(), mergedText.Trim(), "Combined file should equal expected file."); Assert.AreEqual(0, leftConflictLines.GetUpperBound(0), "Should be one left line in conflict."); Assert.AreEqual(0, rightConflictLines.GetUpperBound(0), "Should be one right line in conflict."); Assert.AreEqual(0, leftConflictLines[0].StartLine, "Left conflict lines should start at line 1 (index 0)."); Assert.AreEqual(1, rightConflictLines[0].StartLine, "Right conflict lines should start at line 2 (index 1)."); }
public void The_merged_file_equals_the_start_file() { // inputs string fileBodyLeft = File.ReadAllText(@"..\..\Notes.txt"); string fileBodyRight = fileBodyLeft; TypeOfDiff typeOfDiff = SlyceMerge.PerformTwoWayDiff(identifyConflictsOnly, fileBodyLeft, fileBodyRight, out leftConflictLines, out rightConflictLines, out mergedText); // ignore differences in trailing CrLf fileBodyLeft = fileBodyLeft.Trim(); mergedText = mergedText.Trim(); Assert.AreEqual(TypeOfDiff.ExactCopy, typeOfDiff, "TypeOfDiffs are different."); Assert.AreEqual(-1, leftConflictLines.GetUpperBound(0), "Left conflict lines should be zero."); Assert.AreEqual(-1, rightConflictLines.GetUpperBound(0), "Right conflict lines should be zero."); Assert.AreEqual(fileBodyLeft, mergedText, "Merged text should equal start text."); }
/// <summary> /// Returns a IBaseConstruct which is the result of merging the BaseConstructs in this subtree. /// </summary> /// <returns>A IBaseConstruct which is the result of merging the BaseConstructs in this subtree.</returns> /// <exception cref="InvalidOperationException">Thrown if there are no BaseConstructs in this node /// or any of its children.</exception> public virtual IBaseConstruct GetMergedBaseConstruct() { if (mergedObj != null) { return(mergedObj); } IBaseConstruct newBc = baseConstructs.GetFirstNonNullObject(); if (newBc == null) { throw new InvalidOperationException( "Cannot create a merged IBaseConstruct because this node contains no data"); } newBc = newBc.Clone(); if (baseConstructs.DetermineMissingConstructs() == MissingObject.None) { bool result = newBc.CustomMergeStep(baseConstructs.User, baseConstructs.NewGen, baseConstructs.PrevGen); if (result == false) { // Need to notify the user of this issue. throw new MergeException("Could not perform automatic merge, CustomMergeStep failed. ", GetFirstValidBaseConstruct().FullyQualifiedIdentifer, GetFirstValidBaseConstruct().GetType().ToString()); } } if (newBc is IBody) { IBody bodyNode = (IBody)newBc; string userText = GetBodyText(UserObj); string newgenText = GetBodyText(NewGenObj); string prevgenText = GetBodyText(PrevGenObj); if (UserObj == null && NewGenObj != null) { bodyNode.BodyText = newgenText; } else if (NewGenObj == null && UserObj != null) { bodyNode.BodyText = userText; } else { string mergedText; TypeOfDiff result = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText).DiffType; if (result == TypeOfDiff.Conflict) { throw new InvalidOperationException("Cannot merge BaseConstructs if there is a conflict in their body text."); } bodyNode.BodyText = mergedText; } } foreach (CodeRootMapNode child in children) { MissingObject missingObjects = child.DetermineMissingConstructs(); if ((missingObjects & MissingObject.NewGen) != 0 && (missingObjects & MissingObject.User) != 0) { continue; } IBaseConstruct childBC = child.GetMergedBaseConstruct(); newBc.AddChild(childBC); } return(newBc); }
/// <summary> /// Gets the severest common type of diff from those supplied in the parameter list, /// returning a higher severity level than either value if required. /// </summary> /// <returns>Resulting DiffType.</returns> /// <param name="diffType1">First DiffType.</param> /// <param name="diffType2">Second DiffType.</param> public static TypeOfDiff CombineDiffTypes(TypeOfDiff diffType1, TypeOfDiff diffType2) { TypeOfDiff resultingDiff = diffType1; switch (diffType2) { case TypeOfDiff.Conflict: resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.ExactCopy: resultingDiff = diffType1; break; case TypeOfDiff.TemplateChangeOnly: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.TemplateChangeOnly: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: resultingDiff = TypeOfDiff.TemplateChangeOnly; break; case TypeOfDiff.UserChangeOnly: //DiffType = TypeOfDiff.UserAndTemplateChange; //resultingDiff = TypeOfDiff.Conflict; resultingDiff = TypeOfDiff.UserAndTemplateChange; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.UserAndTemplateChange: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: case TypeOfDiff.UserChangeOnly: case TypeOfDiff.TemplateChangeOnly: resultingDiff = TypeOfDiff.UserAndTemplateChange; //resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.UserChangeOnly: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.UserChangeOnly: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: resultingDiff = TypeOfDiff.UserChangeOnly; break; case TypeOfDiff.TemplateChangeOnly: //DiffType = TypeOfDiff.UserAndTemplateChange; resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } return(resultingDiff); }
/// <summary> /// To be called when no analysis is being performed and files are to be overwritten, not merged. /// </summary> public void SetAsOverwite() { diffType = TypeOfDiff.NewFile; }
internal static void TestFiles_UserAndTemplate(string original, string changed, TypeOfDiff diffType) { CodeRootMap codeRootMap = new CodeRootMap(); ICodeRoot codeRoot = GetCodeRoot(original); codeRootMap.AddCodeRoot(codeRoot, Version.PrevGen); codeRoot = GetCodeRoot(changed); codeRootMap.AddCodeRoot(codeRoot, Version.User); codeRootMap.AddCodeRoot(codeRoot, Version.NewGen); Assert.That(codeRootMap.Diff(), Is.EqualTo(diffType)); }
/// <summary> /// Merge two text files, by performing a line-by-line, case-sensitive comparison /// </summary> /// <returns>Enum indicating Conflict, Warning or Exact Copy</returns> /// <param name="identifyConflictsOnly">Flag - if true, don't merge</param> /// <param name="fileBodyLeft">Contents of LEFT file</param> /// <param name="fileBodyRight">Contents of RIGHT file</param> /// <param name="leftConflictLines">Array of lines with conflict from LEFT file</param> /// <param name="rightConflictLines">Array of lines with conflict from RIGHT file</param> /// <param name="combinedText">Result of merging files.</param> public static TypeOfDiff PerformTwoWayDiff( bool identifyConflictsOnly, string fileBodyLeft, string fileBodyRight, out LineSpan[] leftConflictLines, out LineSpan[] rightConflictLines, out string combinedText) { TypeOfDiff returnValue = TypeOfDiff.ExactCopy; combinedText = ""; StringUtility.RemoveTrailingLineBreaks(ref fileBodyLeft); StringUtility.RemoveTrailingLineBreaks(ref fileBodyRight); // break files into arrays of lines string[] leftLines = Common.Utility.StandardizeLineBreaks(fileBodyLeft, Common.Utility.LineBreaks.Unix).Split('\n'); string[] rightLines = Common.Utility.StandardizeLineBreaks(fileBodyRight, Common.Utility.LineBreaks.Unix).Split('\n'); // handle case where at least one file is empty if (fileBodyLeft.Length == 0 || fileBodyRight.Length == 0) { // both files are empty (unlikely in practice) if (fileBodyLeft.Length == 0 && fileBodyRight.Length == 0) { leftConflictLines = new LineSpan[0]; rightConflictLines = new LineSpan[0]; return(TypeOfDiff.ExactCopy); } // one file is empty if (fileBodyLeft.Length > 0) { combinedText = fileBodyLeft; leftConflictLines = new[] { new LineSpan(0, leftLines.Length - 1) }; rightConflictLines = new LineSpan[0]; } else { combinedText = fileBodyRight; leftConflictLines = new LineSpan[0]; rightConflictLines = new[] { new LineSpan(0, rightLines.Length - 1) }; } return(TypeOfDiff.Warning); } // initialise variables for merging StringBuilder sbMerged = new StringBuilder(Math.Max(fileBodyLeft.Length, fileBodyRight.Length) + 1000); // DMW_Question Is a 'combinedLineCount' really a 'mergedLineCount'? int combinedLineCount = 0; ArrayList combinedLeftColouredLines = new ArrayList(); ArrayList combinedRightColouredLines = new ArrayList(); // perform the diff (case-sensitive, check white space) Diff diff = new Diff(leftLines, rightLines, true, true); // loop through parts of the diff foreach (Diff.Hunk hunk in diff) { if (hunk.Same) { for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); combinedLineCount++; } } else // hunks are different { if (hunk.Left.Count > 0 && hunk.Right.Count > 0) { returnValue = TypeOfDiff.Conflict; } else if (returnValue != TypeOfDiff.Conflict) { returnValue = TypeOfDiff.Warning; } // LEFT file for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedLeftColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } // RIGHT file for (int i = hunk.Right.Start; i <= hunk.Right.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(rightLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedRightColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } } } leftConflictLines = (LineSpan[])combinedLeftColouredLines.ToArray(typeof(LineSpan)); rightConflictLines = (LineSpan[])combinedRightColouredLines.ToArray(typeof(LineSpan)); combinedText = sbMerged.ToString(); return(returnValue); }
public TypeOfDiff DisplayNodeFiles(TreeListNode node, DiffFile currentDiffFile, AutoMergeTypes autoMergeType, string userText, string templateText, string parentText, string mergedText, TypeOfDiff currentDiffType, OriginTypes originType) { OriginType = originType; CurrentDiffFile = currentDiffFile; CurrentDiffType = currentDiffType; BusyPopulatingEditor = true; if (node.Tag.GetType() == typeof(DiffFile) && !((DiffFile)node.Tag).IsText) { ucBinaryFileViewer1.RootParent = SlyceMergeWorker.PreviousGenerationFolder; ucBinaryFileViewer1.RootTemplate = Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator); ucBinaryFileViewer1.RootUser = Controller.Instance.ProjectSettings.ProjectPath; ucBinaryFileViewer1.DiffFile = (DiffFile)node.Tag; // Binary file ucBinaryFileViewer1.Visible = true; ucBinaryFileViewer1.Left = this.Left; ucBinaryFileViewer1.Width = this.ClientSize.Width; ucBinaryFileViewer1.Top = this.Top; ucBinaryFileViewer1.Height = this.ClientSize.Height; SetNavigationButtons(); ShowBinaryFiles(node); return GetCurrentDiffStatus(); } else { ucBinaryFileViewer1.Visible = false; } OrigianlLineSpan = null; bool filesTheSame = true; syntaxEditor1.ResetText(); // Perform a 3-way diff on the file string parentFile = ""; string userFile = ""; string templateFile = ""; string mergedFile = ""; string fileBodyParent = null; string fileBodyUser = null; string fileBodyGenerated = null; if (OriginType == OriginTypes.DiffFile) { parentFile = Path.Combine(SlyceMergeWorker.PreviousGenerationFolder, ((DiffFile)node.Tag).RelativePath); userFile = Path.Combine(Controller.Instance.ProjectSettings.ProjectPath, ((DiffFile)node.Tag).RelativePath); templateFile = Path.Combine(Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator), ((DiffFile)node.Tag).RelativePath); mergedFile = Path.Combine(SlyceMergeWorker.StagingFolder, ((DiffFile)node.Tag).RelativePath + ".merged"); fileBodyParent = File.Exists(parentFile) ? IOUtility.GetTextFileBody(parentFile) : ""; fileBodyUser = File.Exists(userFile) ? IOUtility.GetTextFileBody(userFile) : ""; fileBodyGenerated = File.Exists(templateFile) ? IOUtility.GetTextFileBody(templateFile) : ""; } else { fileBodyParent = parentText; fileBodyUser = userText; fileBodyGenerated = templateText; } fileBodyParent = Slyce.Common.Utility.StandardizeLineBreaks(fileBodyParent, Slyce.Common.Utility.LineBreaks.Unix); fileBodyUser = Slyce.Common.Utility.StandardizeLineBreaks(fileBodyUser, Slyce.Common.Utility.LineBreaks.Unix); fileBodyGenerated = Slyce.Common.Utility.StandardizeLineBreaks(fileBodyGenerated, Slyce.Common.Utility.LineBreaks.Unix); DetermineFileType(node); if (CurrentDiffType == TypeOfDiff.UserChangeOnly) { MarginTextUser = "******"; Slyce.IntelliMerge.UI.Utility.Perform2WayDiffInSingleEditor(syntaxEditor1, ref fileBodyUser, ref fileBodyParent, true); syntaxEditor1.Document.ReadOnly = true; toolStripButtonAcceptTemplateChanges.Enabled = false; toolStripButtonAcceptUserChanges.Enabled = false; this.Text = "View only - No conflicts"; buttonClose.Text = "&Close"; buttonSave.Visible = false; SetNavigationButtons(); this.ShowDialog(Controller.Instance.MainForm); return CurrentDiffType; } else if (CurrentDiffType == TypeOfDiff.TemplateChangeOnly) { MarginTextUser = "******"; if (fileBodyGenerated == null) { // This is marked as a TemplateChange because the template DELETED the corresponding entity DisplayingTextMessage = true; toolStripComboBoxFileType.Text = Slyce.Common.SyntaxEditorHelper.LanguageNameFromEnum(Slyce.Common.SyntaxEditorHelper.Languages.PlainText); syntaxEditor1.WordWrap = ActiproSoftware.SyntaxEditor.WordWrapType.Word; syntaxEditor1.Text = "This is a TemplateChange because it looks like the Template has not created the corresponding entity. In effect, the template has DELETED the corresponding entity. Alternatively, the corresponding entity has been RENAMED, or it's namespace has been renamed. If this is the case, click 'Select Match' on the popup menu to locate a renamed version of this entity if the template has renamed it (or its namespace)."; } else { Slyce.IntelliMerge.UI.Utility.Perform2WayDiffInSingleEditor(syntaxEditor1, ref fileBodyGenerated, ref fileBodyParent, true); } syntaxEditor1.Document.ReadOnly = true; toolStripButtonAcceptTemplateChanges.Enabled = false; toolStripButtonAcceptUserChanges.Enabled = false; this.Text = "View only - No conflicts"; buttonClose.Text = "&Close"; buttonSave.Visible = false; SetNavigationButtons(); this.ShowDialog(Controller.Instance.MainForm); return CurrentDiffType; } else if (CurrentDiffType == TypeOfDiff.UserAndTemplateChange) { if (OriginType == OriginTypes.DiffFile) { string mergedFileName = mergedFile.Replace(".merged", ".copy"); if (!File.Exists(mergedFileName)) { throw new Exception("Merged file with user and template changes not found."); } mergedText = IOUtility.GetTextFileBody(mergedFileName); mergedText = Slyce.Common.Utility.StandardizeLineBreaks(mergedText, Slyce.Common.Utility.LineBreaks.Unix); } SlyceMerge.LineSpan[] userLines; SlyceMerge.LineSpan[] templateLines; SlyceMerge.LineSpan[] rightLinesUser; SlyceMerge.LineSpan[] rightLinesTemplate; string combinedText; SlyceMerge.PerformTwoWayDiff(false, mergedText, fileBodyUser, out userLines, out rightLinesUser, out combinedText); SlyceMerge.PerformTwoWayDiff(false, mergedText, fileBodyGenerated, out templateLines, out rightLinesTemplate, out combinedText); syntaxEditor1.Text = mergedText; for (int i = 0; i < userLines.Length; i++) { #region Get offset int offsetUser = 0; for (int counterRightLineUser = 0; counterRightLineUser < rightLinesUser.Length; counterRightLineUser++) { if (rightLinesUser[counterRightLineUser].StartLine < userLines[i].StartLine) { offsetUser += (rightLinesUser[counterRightLineUser].EndLine - rightLinesUser[counterRightLineUser].StartLine + 1); } else { break; } } #endregion for (int lineCounter = userLines[i].StartLine; lineCounter <= userLines[i].EndLine; lineCounter++) { syntaxEditor1.Document.Lines[lineCounter - offsetUser].BackColor = Slyce.IntelliMerge.UI.Utility.ColourNewGen; } } for (int i = 0; i < templateLines.Length; i++) { #region Get offset int offsetTemplate = 0; for (int counterRightLineTemplate = 0; counterRightLineTemplate < rightLinesTemplate.Length; counterRightLineTemplate++) { if (rightLinesTemplate[counterRightLineTemplate].StartLine < templateLines[i].StartLine) { offsetTemplate += (rightLinesTemplate[counterRightLineTemplate].EndLine - rightLinesTemplate[counterRightLineTemplate].StartLine + 1); } else { break; } } #endregion for (int lineCounter = templateLines[i].StartLine; lineCounter <= templateLines[i].EndLine; lineCounter++) { syntaxEditor1.Document.Lines[lineCounter - offsetTemplate].BackColor = Slyce.IntelliMerge.UI.Utility.ColourUser; } } syntaxEditor1.Document.ReadOnly = true; toolStripButtonAcceptTemplateChanges.Enabled = false; toolStripButtonAcceptUserChanges.Enabled = false; this.Text = "View only - No conflicts"; buttonClose.Text = "&Close"; buttonSave.Visible = false; SetNavigationButtons(); this.ShowDialog(Controller.Instance.MainForm); return currentDiffFile.DiffType; } syntaxEditor1.SuspendPainting(); if (File.Exists(mergedFile)) { using (TextReader tr = new StreamReader(mergedFile)) { string line = ""; int lineCounter = 0; int pipeIndex = 0; int backColor = 0; while ((line = tr.ReadLine()) != null) { pipeIndex = line.IndexOf("|"); backColor = int.Parse(line.Substring(0, pipeIndex)); syntaxEditor1.Document.AppendText(line.Substring(pipeIndex + 1) + Environment.NewLine); syntaxEditor1.Document.Lines[lineCounter].BackColor = Color.FromArgb(backColor); lineCounter++; } } } else // A merged file hasn't been created yet, so conflicts still exist { if (fileBodyParent != null && fileBodyUser != null && fileBodyGenerated != null) { // Perform 3-way diff string output; SlyceMerge slyceMerge = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out output); int lineCounter = 0; StringBuilder sb = new StringBuilder(Math.Max(fileBodyUser.Length, Math.Max(fileBodyParent.Length, fileBodyGenerated.Length)) + 1000); System.Collections.ArrayList colouredLines = new System.Collections.ArrayList(); foreach (SlyceMerge.LineText line in slyceMerge.Lines) { int charPos = 0; int numLineBreaks = 0; charPos = line.Text.IndexOf("\r", 0); if (charPos < 0) { numLineBreaks++; } while (charPos >= 0) { numLineBreaks++; charPos = line.Text.IndexOf("\r", charPos + 1); } sb.AppendLine(line.Text.Replace("\r", "")); colouredLines.Add(new SlyceMerge.LineSpan(lineCounter, lineCounter + numLineBreaks, line.Colour)); lineCounter += numLineBreaks; } int linesToRemove = 0; string text = sb.ToString(); string lastChar = text.Substring(text.Length - linesToRemove - 1); while (lastChar.Length == 0 || lastChar == "\n" || lastChar == "\r" && text.Length >= linesToRemove + 1) { linesToRemove++; lastChar = text.Substring(text.Length - linesToRemove - 1, 1); } syntaxEditor1.Document.Text = text.Substring(0, text.Length - linesToRemove); for (int i = 0; i < colouredLines.Count; i++) { SlyceMerge.LineSpan ls = (SlyceMerge.LineSpan)colouredLines[i]; if (ls.OriginalColor != Color.White) { filesTheSame = false; } for (int x = ls.StartLine; x <= ls.EndLine; x++) { if (x >= syntaxEditor1.Document.Lines.Count) { break; } syntaxEditor1.Document.Lines[x].BackColor = ls.OriginalColor; } } if (filesTheSame) { this.Text = "No Changes"; } } else if (fileBodyParent != null && fileBodyUser != null && fileBodyGenerated == null) { // No template file, just use the user file syntaxEditor1.Text = fileBodyUser; this.Text = "No Conflicts"; } else if (fileBodyParent != null && fileBodyUser == null && fileBodyGenerated != null) { // No user file, just use the template file Slyce.IntelliMerge.UI.Utility.Perform2WayDiffInSingleEditor(syntaxEditor1, ref fileBodyGenerated, ref fileBodyParent, true); } else if (fileBodyParent == null && fileBodyUser != null && fileBodyGenerated != null) { // No parent file, make sure the user merges the template and user files string combinedText; Slyce.IntelliMerge.SlyceMerge.LineSpan[] userLines; Slyce.IntelliMerge.SlyceMerge.LineSpan[] templateLines; SlyceMerge.PerformTwoWayDiff(false, fileBodyUser, fileBodyGenerated, out userLines, out templateLines, out combinedText); Slyce.IntelliMerge.UI.Utility.PopulateSyntaxEditor(syntaxEditor1, combinedText, userLines, templateLines); this.Text = "User changes vs generated"; } else { if (fileBodyParent != null) { if (File.Exists(userFile) || File.Exists(templateFile)) { throw new Exception("More than one file exists. Shouldn't be here."); } syntaxEditor1.Text = fileBodyParent; this.Text = "Unchanged file"; } else if (fileBodyUser != null) { if (File.Exists(parentFile) || File.Exists(templateFile)) { throw new Exception("More than one file exists. Shouldn't be here."); } syntaxEditor1.Text = fileBodyUser; this.Text = "User-only file"; } else if (fileBodyGenerated != null) { if (File.Exists(parentFile) || File.Exists(userFile)) { throw new Exception("More than one file exists. Shouldn't be here."); } syntaxEditor1.Text = fileBodyGenerated; this.Text = "Newly Generated file"; } } } syntaxEditor1.Refresh(); if (syntaxEditor1.Document.Text.Length > 0) { syntaxEditor1.SelectedView.Selection.StartOffset = 0; syntaxEditor1.SelectedView.Selection.EndOffset = 0; } syntaxEditor1.Document.Modified = false; syntaxEditor1.ResumePainting(); BusyPopulatingEditor = false; switch (autoMergeType) { case AutoMergeTypes.None: GotoNextConflictLine(0); this.ShowDialog(Controller.Instance.MainForm); break; case AutoMergeTypes.KeepUserChanges: AcceptAllUserChanges(); if (!SaveCurrentFile(false)) { MessageBox.Show("There was a problem processing this file automatically. Please resolve these changes manually.", "Auto Processing Problem", MessageBoxButtons.OK, MessageBoxIcon.Warning); GotoNextConflictLine(0); this.ShowDialog(Controller.Instance.MainForm); } break; case AutoMergeTypes.KeepTemplateChanges: AcceptAllTemplateChanges(); if (!SaveCurrentFile(false)) { MessageBox.Show("There was a problem processing this file automatically. Please resolve these changes manually.", "Auto Processing Problem", MessageBoxButtons.OK, MessageBoxIcon.Warning); GotoNextConflictLine(0); this.ShowDialog(Controller.Instance.MainForm); } break; } SetNavigationButtons(); if (CancelClicked) { return TypeOfDiff.Conflict; } else { return GetCurrentDiffStatus(); } }
internal void SetDiffType(TypeOfDiff diffType) { DiffType = SlyceMerge.CombineDiffTypes(DiffType, diffType); }
/// <summary> /// Gets the severest common type of diff from those supplied in the parameter list, /// returning a higher severity level than either value if required. /// </summary> /// <returns>Resulting DiffType.</returns> /// <param name="diffType1">First DiffType.</param> /// <param name="diffType2">Second DiffType.</param> public static TypeOfDiff CombineDiffTypes(TypeOfDiff diffType1, TypeOfDiff diffType2) { TypeOfDiff resultingDiff = diffType1; switch (diffType2) { case TypeOfDiff.Conflict: resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.ExactCopy: resultingDiff = diffType1; break; case TypeOfDiff.TemplateChangeOnly: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.TemplateChangeOnly: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: resultingDiff = TypeOfDiff.TemplateChangeOnly; break; case TypeOfDiff.UserChangeOnly: //DiffType = TypeOfDiff.UserAndTemplateChange; //resultingDiff = TypeOfDiff.Conflict; resultingDiff = TypeOfDiff.UserAndTemplateChange; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.UserAndTemplateChange: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: case TypeOfDiff.UserChangeOnly: case TypeOfDiff.TemplateChangeOnly: resultingDiff = TypeOfDiff.UserAndTemplateChange; //resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.UserChangeOnly: switch (diffType1) { case TypeOfDiff.Conflict: case TypeOfDiff.UserChangeOnly: case TypeOfDiff.UserAndTemplateChange: resultingDiff = diffType1; break; case TypeOfDiff.ExactCopy: resultingDiff = TypeOfDiff.UserChangeOnly; break; case TypeOfDiff.TemplateChangeOnly: //DiffType = TypeOfDiff.UserAndTemplateChange; resultingDiff = TypeOfDiff.Conflict; break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } break; case TypeOfDiff.Warning: resultingDiff = TypeOfDiff.Warning; break; } return resultingDiff; }
public virtual TypeOfDiff Diff() { TypeOfDiff diff = TypeOfDiff.ExactCopy; DiffTypeExcludingChildren = TypeOfDiff.ExactCopy; if (MergedObj != null) { DiffTypeExcludingChildren = TypeOfDiff.ExactCopy; } else if (baseConstructs.PrevGen == null) { if (baseConstructs.NewGen == null && baseConstructs.User == null) { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.Warning); } else if (baseConstructs.NewGen == null) { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly); } else if (baseConstructs.User == null) { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly); } else if (baseConstructs.User.IsTheSame(baseConstructs.NewGen, ComparisonDepth.Outer)) { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.ExactCopy); } else { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.Conflict); } if (baseConstructs.NewGen != null && baseConstructs.User != null && baseConstructs.GetFirstNonNullObject().IsLeaf) { // Do a diff on the body text of our BaseConstructs string userText = GetFullText(UserObj).TrimStart(Environment.NewLine.ToCharArray()); string newgenText = GetFullText(NewGenObj).TrimStart(Environment.NewLine.ToCharArray()); TypeOfDiff result = SlyceMerge.PerformTwoWayDiff(userText, newgenText); DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, result); } } else { if (BaseConstructsAreSame == false) { // Do a diff on the outer text of our BaseConstructs string userText = GetOuterText(UserObj); string newgenText = GetOuterText(NewGenObj); string prevgenText = GetOuterText(PrevGenObj); string mergedText; DiffTypeExcludingChildren = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText, false).DiffType; } // Also diff ourselves, looking at more than a basic signature comparison but not looking at children (we have already done that above) if (baseConstructs.PrevGen == null) { if (baseConstructs.NewGen == null) { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly); } else if (baseConstructs.User == null && ParentTree.UserCodeRoot != null) // if the user file is null it may not have been generated yet - this is the first run of this project. { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly); } else { DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserAndTemplateChange); } } else { if (baseConstructs.PrevGen.IsTheSame(baseConstructs.NewGen, ComparisonDepth.Outer) == false) { // If NewGen is null, this will return false. DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly); } if (baseConstructs.PrevGen.IsTheSame(baseConstructs.User, ComparisonDepth.Outer) == false) { // If User is null, this will return false. DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly); } if (baseConstructs.NewGen != null && baseConstructs.User != null && diffTypeExcChildren == TypeOfDiff.Conflict && baseConstructs.NewGen.IsTheSame(baseConstructs.User, ComparisonDepth.Outer)) { DiffTypeExcludingChildren = TypeOfDiff.UserAndTemplateChange; } if (baseConstructs.NewGen == null && baseConstructs.User == null) { DiffTypeExcludingChildren = TypeOfDiff.UserAndTemplateChange; } } if (baseConstructs.GetFirstNonNullObject().IsLeaf) { // Do a diff on the body text of our BaseConstructs string userText = GetBodyText(UserObj).TrimStart(Environment.NewLine.ToCharArray()); string newgenText = GetBodyText(NewGenObj).TrimStart(Environment.NewLine.ToCharArray()); string prevgenText = GetBodyText(PrevGenObj).TrimStart(Environment.NewLine.ToCharArray()); string mergedText; TypeOfDiff result = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText).DiffType; DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, result); } if (baseConstructs.NewGen != null && ParentTree.PrevGenCodeRoot == null && ParentTree.UserCodeRoot == null) { // Template base construct exists, but Prevgen and User CodeRoots haven't been added.. Make it an exact copy. DiffTypeExcludingChildren = TypeOfDiff.ExactCopy; } } // Diff out child nodes. foreach (CodeRootMapNode node in children) { diff = CombineChildDiffTypes(diff, node.Diff()); } diff = CombineChildDiffTypes(diff, diffTypeExcChildren); return(diff); }