From 0ae6c641b2dd631ffecdafac41ea0e8f77f4923f Mon Sep 17 00:00:00 2001 From: Carlos Martin Nieto Date: Wed, 20 Apr 2016 22:53:45 -0700 Subject: [PATCH] Paths in Git structures are strings not FilePaths These paths use a slash for separation, and attempts to hide this behind FilePath end up making it more complex to figure out what we should accept. Move to accept strings and keep them as such instead of trying to convert them. --- LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs | 2 +- LibGit2Sharp.Tests/FileHistoryFixture.cs | 2 +- LibGit2Sharp/Core/NativeMethods.cs | 2 +- LibGit2Sharp/Core/Proxy.cs | 2 +- LibGit2Sharp/GitObject.cs | 2 +- LibGit2Sharp/Repository.cs | 2 +- LibGit2Sharp/Tree.cs | 36 +++++++++++++++------ LibGit2Sharp/TreeDefinition.cs | 9 ++---- LibGit2Sharp/TreeEntry.cs | 5 ++- LibGit2Sharp/TreeEntryChanges.cs | 4 +-- 10 files changed, 38 insertions(+), 28 deletions(-) diff --git a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs index f51def511..e1e6359e1 100644 --- a/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs +++ b/LibGit2Sharp.Tests/DiffTreeToTreeFixture.cs @@ -10,7 +10,7 @@ namespace LibGit2Sharp.Tests { public class DiffTreeToTreeFixture : BaseFixture { - private static readonly string subBranchFilePath = Path.Combine("1", "branch_file.txt"); + private static readonly string subBranchFilePath = String.Join("/", "1", "branch_file.txt"); [Fact] public void ComparingATreeAgainstItselfReturnsNoDifference() diff --git a/LibGit2Sharp.Tests/FileHistoryFixture.cs b/LibGit2Sharp.Tests/FileHistoryFixture.cs index ae2f48bb6..365ae89a1 100644 --- a/LibGit2Sharp.Tests/FileHistoryFixture.cs +++ b/LibGit2Sharp.Tests/FileHistoryFixture.cs @@ -151,7 +151,7 @@ public void CanTellComplexCommitHistory() var commit2 = MakeAndCommitChange(repo, repoPath, path1, "Hello World again"); // Move the first file to a new directory. - var newPath1 = Path.Combine(SubFolderPath1, path1); + var newPath1 = Path.Combine(SubFolderPath1, path1).Replace(@"\", "/"); Commands.Move(repo, path1, newPath1); var commit3 = repo.Commit("Moved " + path1 + " to " + newPath1, Constants.Signature, Constants.Signature); diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 846617f2c..fb18ded5e 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -1821,7 +1821,7 @@ IntPtr data internal static extern unsafe int git_tree_entry_bypath( out git_tree_entry* tree, git_object* root, - [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath treeentry_path); + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string treeentry_path); [DllImport(libgit2)] internal static extern unsafe void git_tree_entry_free(git_tree_entry* treeEntry); diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index fbf7d2b3e..da54e4064 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -3220,7 +3220,7 @@ public static unsafe TreeEntryHandle git_tree_entry_byindex(ObjectHandle tree, l return new TreeEntryHandle(handle, false); } - public static unsafe TreeEntryHandle git_tree_entry_bypath(RepositoryHandle repo, ObjectId id, FilePath treeentry_path) + public static unsafe TreeEntryHandle git_tree_entry_bypath(RepositoryHandle repo, ObjectId id, string treeentry_path) { using (var obj = new ObjectSafeWrapper(id, repo)) { diff --git a/LibGit2Sharp/GitObject.cs b/LibGit2Sharp/GitObject.cs index 2412003d8..812c881ba 100644 --- a/LibGit2Sharp/GitObject.cs +++ b/LibGit2Sharp/GitObject.cs @@ -60,7 +60,7 @@ public virtual string Sha get { return Id.Sha; } } - internal static GitObject BuildFrom(Repository repo, ObjectId id, GitObjectType type, FilePath path) + internal static GitObject BuildFrom(Repository repo, ObjectId id, GitObjectType type, string path) { switch (type) { diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index fc8783c76..2c7b8b015 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -527,7 +527,7 @@ public GitObject Lookup(string objectish, ObjectType type) return Lookup(objectish, type.ToGitObjectType(), LookUpOptions.None); } - internal GitObject LookupInternal(ObjectId id, GitObjectType type, FilePath knownPath) + internal GitObject LookupInternal(ObjectId id, GitObjectType type, string knownPath) { Ensure.ArgumentNotNull(id, "id"); diff --git a/LibGit2Sharp/Tree.cs b/LibGit2Sharp/Tree.cs index 0a19f4e04..d34c0b75e 100644 --- a/LibGit2Sharp/Tree.cs +++ b/LibGit2Sharp/Tree.cs @@ -5,6 +5,8 @@ using System.Linq; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; +using System.Text; +using System; namespace LibGit2Sharp { @@ -14,7 +16,7 @@ namespace LibGit2Sharp [DebuggerDisplay("{DebuggerDisplay,nq}")] public class Tree : GitObject, IEnumerable { - private readonly FilePath path; + private readonly string path; private readonly ILazy lazyCount; @@ -24,7 +26,7 @@ public class Tree : GitObject, IEnumerable protected Tree() { } - internal Tree(Repository repo, ObjectId id, FilePath path) + internal Tree(Repository repo, ObjectId id, string path) : base(repo, id) { this.path = path ?? ""; @@ -47,9 +49,9 @@ internal Tree(Repository repo, ObjectId id, FilePath path) get { return RetrieveFromPath(relativePath); } } - private unsafe TreeEntry RetrieveFromPath(FilePath relativePath) + private unsafe TreeEntry RetrieveFromPath(string relativePath) { - if (relativePath.IsNullOrEmpty()) + if (string.IsNullOrEmpty(relativePath)) { return null; } @@ -61,21 +63,20 @@ private unsafe TreeEntry RetrieveFromPath(FilePath relativePath) return null; } - string posixPath = relativePath.Posix; - string filename = posixPath.Split('/').Last(); - string parentPath = posixPath.Substring(0, posixPath.Length - filename.Length); - return new TreeEntry(treeEntry, Id, repo, path.Combine(parentPath)); + string filename = relativePath.Split('/').Last(); + string parentPath = relativePath.Substring(0, relativePath.Length - filename.Length); + return new TreeEntry(treeEntry, Id, repo, Tree.CombinePath(path, parentPath)); } } internal string Path { - get { return path.Native; } + get { return path; } } #region IEnumerable Members - unsafe TreeEntry byIndex(ObjectSafeWrapper obj, uint i, ObjectId parentTreeId, Repository repo, FilePath parentPath) + unsafe TreeEntry byIndex(ObjectSafeWrapper obj, uint i, ObjectId parentTreeId, Repository repo, string parentPath) { using (var entryHandle = Proxy.git_tree_entry_byindex(obj.ObjectPtr, i)) { @@ -83,6 +84,21 @@ unsafe TreeEntry byIndex(ObjectSafeWrapper obj, uint i, ObjectId parentTreeId, R } } + internal static string CombinePath(string a, string b) + { + var bld = new StringBuilder(); + bld.Append(a); + if (!String.IsNullOrEmpty(a) && + !a.EndsWith("/", StringComparison.InvariantCulture) && + !b.StartsWith("/", StringComparison.InvariantCulture)) + { + bld.Append('/'); + } + bld.Append(b); + + return bld.ToString(); + } + /// /// Returns an enumerator that iterates through the collection. /// diff --git a/LibGit2Sharp/TreeDefinition.cs b/LibGit2Sharp/TreeDefinition.cs index 68f287879..1830ed55a 100644 --- a/LibGit2Sharp/TreeDefinition.cs +++ b/LibGit2Sharp/TreeDefinition.cs @@ -126,11 +126,6 @@ public virtual TreeDefinition Add(string targetTreeEntryPath, TreeEntryDefinitio Ensure.ArgumentNotNullOrEmptyString(targetTreeEntryPath, "targetTreeEntryPath"); Ensure.ArgumentNotNull(treeEntryDefinition, "treeEntryDefinition"); - if (Path.IsPathRooted(targetTreeEntryPath)) - { - throw new ArgumentException("The provided path is an absolute path."); - } - if (treeEntryDefinition is TransientTreeTreeEntryDefinition) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, @@ -383,9 +378,9 @@ private void WrapTree(string entryName, TreeEntryDefinition treeEntryDefinition) } } - private static Tuple ExtractPosixLeadingSegment(FilePath targetPath) + private static Tuple ExtractPosixLeadingSegment(string targetPath) { - string[] segments = targetPath.Posix.Split(new[] { '/' }, 2); + string[] segments = targetPath.Split(new[] { '/' }, 2); if (segments[0] == string.Empty || (segments.Length == 2 && (segments[1] == string.Empty || segments[1].StartsWith("/", StringComparison.Ordinal)))) { diff --git a/LibGit2Sharp/TreeEntry.cs b/LibGit2Sharp/TreeEntry.cs index f3713a776..e500a8ee1 100644 --- a/LibGit2Sharp/TreeEntry.cs +++ b/LibGit2Sharp/TreeEntry.cs @@ -1,7 +1,6 @@ using System; using System.Diagnostics; using System.Globalization; -using System.Runtime.InteropServices; using LibGit2Sharp.Core; using LibGit2Sharp.Core.Handles; @@ -28,7 +27,7 @@ public class TreeEntry : IEquatable protected TreeEntry() { } - internal unsafe TreeEntry(TreeEntryHandle entry, ObjectId parentTreeId, Repository repo, FilePath parentPath) + internal unsafe TreeEntry(TreeEntryHandle entry, ObjectId parentTreeId, Repository repo, string parentPath) { this.parentTreeId = parentTreeId; this.repo = repo; @@ -41,7 +40,7 @@ internal unsafe TreeEntry(TreeEntryHandle entry, ObjectId parentTreeId, Reposito Mode = Proxy.git_tree_entry_attributes(entry); Name = Proxy.git_tree_entry_name(entry); - path = new Lazy(() => System.IO.Path.Combine(parentPath.Native, Name)); + path = new Lazy(() => Tree.CombinePath(parentPath, Name)); } /// diff --git a/LibGit2Sharp/TreeEntryChanges.cs b/LibGit2Sharp/TreeEntryChanges.cs index cfe0fd8e8..1ab1a6172 100644 --- a/LibGit2Sharp/TreeEntryChanges.cs +++ b/LibGit2Sharp/TreeEntryChanges.cs @@ -18,8 +18,8 @@ protected TreeEntryChanges() internal unsafe TreeEntryChanges(git_diff_delta* delta) { - Path = LaxFilePathMarshaler.FromNative(delta->new_file.Path).Native; - OldPath = LaxFilePathMarshaler.FromNative(delta->old_file.Path).Native; + Path = LaxUtf8Marshaler.FromNative(delta->new_file.Path); + OldPath = LaxUtf8Marshaler.FromNative(delta->old_file.Path); Mode = (Mode)delta->new_file.Mode; OldMode = (Mode)delta->old_file.Mode;