From 784f38a361229c6917bf4deb7629066adf6ef717 Mon Sep 17 00:00:00 2001 From: "Joel W. Reed" Date: Wed, 26 Mar 2008 17:27:05 -0400 Subject: [PATCH] don't barf when diffing binary files --- ChangeLog | 1 + .../DiffItemLocalFile.cs | 7 ++++++- .../DiffItemVersionedFile.cs | 15 ++++++++++++--- .../Difference.cs | 15 +++------------ .../DifferenceUtil.cs | 18 +++++++++++++++++- .../Makefile | 4 ---- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfb7fc4..24c6e66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ # NEW: better cygwin support, eg. pipe-able ls-files output # NEW: show the difference between two versions for a specified path with tf diff + # NEW: don't barf when diffing binary files # BUGFIX: tf.sh shouldn't assume mono is always in /usr/bin/ # BUGFIX: make Microsoft.TeamFoundation.Client.Authenticator work with mono versions post 1.2.6 diff --git a/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemLocalFile.cs b/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemLocalFile.cs index 445e122..a0d5ffb 100644 --- a/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemLocalFile.cs +++ b/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemLocalFile.cs @@ -33,6 +33,7 @@ using System.Net; using System.Text; using System.Xml; using System.Web.Services; +using Microsoft.TeamFoundation.VersionControl.Common; namespace Microsoft.TeamFoundation.VersionControl.Client { @@ -57,7 +58,11 @@ namespace Microsoft.TeamFoundation.VersionControl.Client { file = sr.ReadToEnd(); } - + + // tfs doesn't seem to be very adept at identifying binary files + // so help out a little + if (DiffItemUtil.IsBinary(file)) encoding = RepositoryConstants.EncodingBinary; + return file; } diff --git a/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemVersionedFile.cs b/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemVersionedFile.cs index 1b06655..53829e8 100644 --- a/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemVersionedFile.cs +++ b/class/Microsoft.TeamFoundation.VersionControl.Client/DiffItemVersionedFile.cs @@ -33,6 +33,7 @@ using System.Net; using System.Text; using System.Xml; using System.Web.Services; +using Microsoft.TeamFoundation.VersionControl.Common; namespace Microsoft.TeamFoundation.VersionControl.Client { @@ -42,6 +43,7 @@ namespace Microsoft.TeamFoundation.VersionControl.Client private string label; private Item item; private VersionSpec versionSpec; + private int encoding; public DiffItemVersionedFile(Item item, VersionSpec versionSpec) { @@ -49,6 +51,7 @@ namespace Microsoft.TeamFoundation.VersionControl.Client this.item = item; this.versionSpec = versionSpec; this.label = item.ServerItem; + this.encoding = item.Encoding; } public DiffItemVersionedFile(VersionControlServer versionControl, @@ -56,6 +59,7 @@ namespace Microsoft.TeamFoundation.VersionControl.Client { this.versionControlServer = versionControl; this.item = versionControl.GetItem(itemId, changeset); + this.encoding = item.Encoding; this.label = displayPath; } @@ -64,14 +68,19 @@ namespace Microsoft.TeamFoundation.VersionControl.Client // this is a quite inefficient implementation, FIXME string tname = Path.GetTempFileName(); item.DownloadFile(tname); - + string file; using (StreamReader sr = new StreamReader(tname)) { file = sr.ReadToEnd(); } - + File.Delete(tname); + + // tfs doesn't seem to be very adept at identifying binary files + // so help out a little + if (DiffItemUtil.IsBinary(file)) encoding = RepositoryConstants.EncodingBinary; + return file; } @@ -88,7 +97,7 @@ namespace Microsoft.TeamFoundation.VersionControl.Client public int GetEncoding() { - return item.Encoding; + return encoding; } } } diff --git a/class/Microsoft.TeamFoundation.VersionControl.Client/Difference.cs b/class/Microsoft.TeamFoundation.VersionControl.Client/Difference.cs index ec75910..c61c4fc 100644 --- a/class/Microsoft.TeamFoundation.VersionControl.Client/Difference.cs +++ b/class/Microsoft.TeamFoundation.VersionControl.Client/Difference.cs @@ -139,26 +139,17 @@ namespace Microsoft.TeamFoundation.VersionControl.Client DiffOptions diffOpts, string fileNameForHeader, bool wait) { - DiffItemUtil aItem = new DiffItemUtil('a', fileNameForHeader, source.GetFile()); - DiffItemUtil bItem = new DiffItemUtil('b', fileNameForHeader, target.GetFile()); + DiffItemUtil aItem = new DiffItemUtil('a', fileNameForHeader, source); + DiffItemUtil bItem = new DiffItemUtil('b', fileNameForHeader, target); StreamWriter stream = diffOpts.StreamWriter; // short circuit for binary file comparisions - if (source.GetEncoding() == RepositoryConstants.EncodingBinary && target.GetEncoding() == RepositoryConstants.EncodingBinary) + if (source.GetEncoding() == RepositoryConstants.EncodingBinary || target.GetEncoding() == RepositoryConstants.EncodingBinary) { stream.WriteLine("Binary files {0} and {1} differ", aItem.Name, bItem.Name); return; } -#if HAVE_GNOME_VFS - Gnome.Vfs.MimeType mimeType = new Gnome.Vfs.MimeType(Gnome.Vfs.Mime.TypeFromName(fileNameForHeader)); - if (!mimeType.CanBeExecutable) - { - stream.WriteLine("Binary files {0} and {1} differ", aItem.Name, bItem.Name); - return; - } -#endif - WriteHeader(aItem, bItem, diffOpts); // short circuit new files diff --git a/class/Microsoft.TeamFoundation.VersionControl.Client/DifferenceUtil.cs b/class/Microsoft.TeamFoundation.VersionControl.Client/DifferenceUtil.cs index d3f847d..1f9d182 100644 --- a/class/Microsoft.TeamFoundation.VersionControl.Client/DifferenceUtil.cs +++ b/class/Microsoft.TeamFoundation.VersionControl.Client/DifferenceUtil.cs @@ -49,8 +49,9 @@ namespace Microsoft.TeamFoundation.VersionControl.Client } } - public DiffItemUtil(char prefix, string name, string fileContents) + public DiffItemUtil(char prefix, string name, IDiffItem file) { + string fileContents = file.GetFile(); Length = fileContents.Length; string path = PrefixedHeaderPath(prefix, name); @@ -63,6 +64,9 @@ namespace Microsoft.TeamFoundation.VersionControl.Client // gnu patch doesn't want to see backslashes in filenames this.name = path.Replace('\\', '/'); + // don't bother trying to parse lines for binary files + if (file.GetEncoding() == RepositoryConstants.EncodingBinary) return; + // if file ends with /n the split below generates one extra row we dont want int len = fileContents.Length; if (fileContents.EndsWith("\n")) len -= 1; @@ -81,6 +85,18 @@ namespace Microsoft.TeamFoundation.VersionControl.Client return sb.ToString(); } + + static public bool IsBinary(string s) + { + int size = Math.Min(8000, s.Length); + for (int i=0; i