public static void WriteUnifiedDiff(Diff diff, TextWriter writer, string fromfile, string tofile, int context) {
			writer.Write("--- ");
			writer.WriteLine(fromfile);
			writer.Write("+++ ");
			writer.WriteLine(tofile);
			
			ArrayList hunkset = new ArrayList();
			
			foreach (Diff.Hunk hunk in diff) {
				Diff.Hunk lasthunk = null;
				if (hunkset.Count > 0) lasthunk = (Diff.Hunk)hunkset[hunkset.Count-1];
				
				if (hunk.Same) {
					// At the start of a hunk set, keep only context lines of context.
					if (lasthunk == null) {
						if (hunk.Left.Count > context)
							hunkset.Add( hunk.Crop(hunk.Left.Count-context, 0) );
						else
							hunkset.Add( hunk );
					// Can't have two same hunks in a row, so the last one was a difference.
					} else {
						// Small enough context that this unified diff range will not stop.
						if (hunk.Left.Count <= context*2) {
							hunkset.Add( hunk );
							
						// Too much of the same.  Keep context lines and end this section.
						// And then keep the last context lines as context for the next section.
						} else {
							hunkset.Add( hunk.Crop(0, hunk.Left.Count-context) );
							WriteUnifiedDiffSection(writer, hunkset);
							hunkset.Clear();
							
							if (hunk.Left.Count > context)
								hunkset.Add( hunk.Crop(hunk.Left.Count-context, 0) );
							else
								hunkset.Add( hunk );
						}
					}
				
				} else {
					hunkset.Add(hunk);
				}
			}
			
			if (hunkset.Count > 0 && !(hunkset.Count == 1 && ((Diff.Hunk)hunkset[0]).Same))
				WriteUnifiedDiffSection(writer, hunkset);
		}
		private static IDiff[] makediffs(IList original, IList[] changed, IComparer comparer, IEqualityComparer hashcoder) {
			IDiff[] diffs = new IDiff[changed.Length];
			for (int i = 0; i < changed.Length; i++)
				diffs[i] = new Diff(original, changed[i], comparer, hashcoder);
			return diffs;
		}
			internal Hunk(Merge merge, Diff.Hunk[][] hunks, int start, int count, bool same) {
				this.merge = merge;
				this.hunks = hunks;
				this.start = start;
				this.count = count;
				this.same = same;
				
				int ct = 0;
				foreach (Diff.Hunk[] hh in hunks) {
					foreach (Diff.Hunk h in hh) {
						if (!h.Same) {
							ct++;
							break;
						}
					}
				}
				conflict = (ct > 1);
			}
예제 #4
0
			public Enumerator(Diff diff) {
				this.diff = diff;
				Reset();
			}
예제 #5
0
		private void Refresh() {
			box.Show();
			
			try {
				if (left is string)
					diff = new Diff((string)left, (string)right, true, true);
				else if (left is string[])
					diff = new Diff((string[])left, (string[])right, null, null);
			} catch (Exception e) {
				Console.Error.WriteLine(e.ToString());
				return;
			} 
			
			if (widget != null) {
				pos = widget.Position;
				box.Remove(widget);
				widget.Dispose();
			}
						
			DiffWidget.Options opts = new DiffWidget.Options();
			opts.Font = DesktopService.DefaultMonospaceFont;
			opts.LeftName = "Repository";
			opts.RightName = "Working Copy";
			widget = new DiffWidget(diff, opts);
			
			box.Add(widget);
			box.ShowAll();
			
			widget.ExposeEvent += new ExposeEventHandler(OnExposed);
		}
예제 #6
0
			public void GetButtonPosition (Diff.Hunk hunk, int z1, int z2, int y1, int y2, out int x, out int y, out int r)
			{
				r = 14;
				if (hunk.Left.Count == 0) {
					x = 0;
					y = Math.Min (z1, z2);
				} else {
					x = Allocation.Width - r;
					y = Math.Min (y1, y2);
				}
			}
예제 #7
0
		int[,] GetLCS (Diff.Hunk hunk)
		{
			int[,] result;
			if (llcsCache.TryGetValue (hunk, out result))
				return result;
			return null;
		}
예제 #8
0
		public static Cairo.Color GetColor (Diff.Hunk hunk, double alpha)
		{
			if (hunk.Left.Count == 0)
				return new Cairo.Color (0.4, 0.8, 0.4, alpha);
			if (hunk.Right.Count == 0) 
				return new Cairo.Color (0.8, 0.4, 0.4, alpha);
			return new Cairo.Color (0.4, 0.8, 0.8, alpha);
		}
예제 #9
0
		public void CreateDiff ()
		{
			var leftLines = from l in OriginalEditor.Document.Lines select OriginalEditor.Document.GetTextAt (l.Offset, l.EditableLength);
			var rightLines = from l in DiffEditor.Document.Lines select DiffEditor.Document.GetTextAt (l.Offset, l.EditableLength);
			
			Diff = new Diff (rightLines.ToArray (), leftLines.ToArray (), true, true);
			QueueDraw ();
		}
		private float CompareLists(IList left, IList right, float threshold, bool output) {
			// Given two lists, find the elements in the list that correspond.
			// Two elements correspond if their 'difference metric' is less than
			// or equal to threshold.  For the hunks of correspondent items,
			// recursively descend into items not truly equal.  For hunks of
			// irreconsiliable material, raise the threshold to the next useful
			// level and rescan the items.
			
			if (left.Count == 0 && right.Count == 0)
				return 0;
			
			NodeComparerWrapper comparer = new NodeComparerWrapper(threshold, this);
			
			Diff diff = new Diff(left, right, comparer, comparer);
			
			int nitems = 0, ndiffs = 0;
			
			foreach (Diff.Hunk hunk in diff) {
				if (hunk.Same || (hunk.Left.Count == 1 && hunk.Right.Count == 1)) {
					// This comprises a block of correspondent items who
					// differ by no more than the threshold value.
					
					nitems += hunk.Left.Count;

					bool inSameRegion = false;
					
					for (int i = 0; i < hunk.Left.Count; i++) {
						object oleft = hunk.Left[i];
						object oright = hunk.Right[i];
						
						NodeInterface ileft = GetInterface(oleft);
						NodeInterface iright = GetInterface(oright);
						
						IList cleft = null, cright = null;
						cleft = ileft.GetChildren(oleft);
						cright = iright.GetChildren(oright);
						
						float comp = 0;
						if (ileft == iright)
							comp = ileft.Compare(oleft, oright, this);
						
						// If the nodes are equal, emit one node.
						if (ileft == iright && comp == 0) {
							if (output) {
								if (!inSameRegion) { WritePushSame(); inSameRegion = true; }
								WriteNodeSame(ileft, oleft, oright);
							}
							
						// Recurse into the lists of each node.
						} else if (ileft == iright && cleft != null && cright != null && cleft.Count > 0 && cright.Count > 0 && comp <= 1.0) {
							if (output && inSameRegion) { WritePopSame(); inSameRegion = false; }
							if (output) WritePushNode(ileft, oleft, oright);
							float d = CompareLists(cleft, cright, 0, output);
							d *= hunk.Left.Count;
							if (d < 1) d = 1;
							ndiffs += (int)d;
							if (output) WritePopNode();
							
						// The nodes are not equal, so emit removed and added nodes.
						} else {
							if (output && inSameRegion) { WritePopSame(); inSameRegion = false; }
							if (output) WriteNodeChange(ileft, oleft, iright, oright);
							ndiffs += hunk.Left.Count;
						}
					}
					
					if (output && inSameRegion) WritePopSame();
				} else {
					int ct = hunk.Left.Count + hunk.Right.Count;
					nitems += ct;
					ndiffs += ct;
					
					if (output) {
						bool noRecurse = comparer.minimumDifference >= 1;
						if (hunk.Right.Count == 0 || (hunk.Left.Count > 0 && noRecurse))
							WriteNodesRemoved(hunk.Left);
						if (hunk.Left.Count == 0 || (hunk.Right.Count > 0 && noRecurse))
							WriteNodesAdded(hunk.Right);
						if (hunk.Right.Count != 0 && hunk.Left.Count != 0 && !noRecurse)
							CompareLists(hunk.Left, hunk.Right, comparer.minimumDifference, output);
					}
				}
			}
			
			return (float)ndiffs / (float)nitems;
		}
		void SetDiffCellData (Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter)
		{
			try {
				CellRendererDiff cellRendererDiff = (CellRendererDiff)cell;
				Change change = store.GetValue (iter, objColumn) as Change;
				cellRendererDiff.Visible = !(bool)store.GetValue (iter, statusVisibleColumn);
				if (change == null || !cellRendererDiff.Visible) {
					cellRendererDiff.InitCell (treeviewPreview, false, "", "");
					return;
				}
				TextReplaceChange replaceChange = change as TextReplaceChange;
				if (replaceChange == null) 
					return;
			
				Mono.TextEditor.Document doc = new Mono.TextEditor.Document ();
				doc.Text = System.IO.File.ReadAllText (replaceChange.FileName);
				List<string> before = new List<string> ();
				foreach (var line in doc.Lines) {
					before.Add (doc.GetTextAt (line.Offset, line.EditableLength));
				}
				
				((Mono.TextEditor.IBuffer)doc).Replace (replaceChange.Offset, replaceChange.RemovedChars, replaceChange.InsertedText);
				
				List<string> after = new List<string> ();
				foreach (var line in doc.Lines) {
					after.Add (doc.GetTextAt (line.Offset, line.EditableLength));
				}
				
				Diff diff = new Diff (before.ToArray (), after.ToArray (), true, true);
				
				System.IO.StringWriter w = new System.IO.StringWriter();
				UnifiedDiff.WriteUnifiedDiff (diff, w, replaceChange.FileName, replaceChange.FileName, 2);
				cellRendererDiff.InitCell (treeviewPreview, true, w.ToString ().Trim (), replaceChange.FileName);
			} catch (Exception e) {
				Console.WriteLine (e);
			}
		}
		public DiffWidget(Diff diff, Options options) : this(Hunkify(diff), options) 
		{
		}
		public static void WriteUnifiedDiff(Diff diff, TextWriter writer) {
			WriteUnifiedDiff(diff, writer, "Left", "Right", 2);
		}
		public static void WriteUnifiedDiff(string[] leftLines, string leftName, string[] rightLines, string rightName, System.IO.TextWriter writer, int context, bool caseSensitive, bool compareWhitespace) {
			Diff diff = new Diff(leftLines, rightLines, caseSensitive, compareWhitespace);
			WriteUnifiedDiff(diff, writer, leftName, rightName, context);
		}