From 4407bcba3af167449854af9b6acf9de2e3dd09f9 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sat, 4 Jul 2015 19:00:58 +0200 Subject: [PATCH 1/2] Make probing of test resources more reliable --- LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs index 240e8a4ca..84d48c477 100644 --- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs +++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs @@ -56,7 +56,7 @@ private static void SetUpTestEnvironment() { IsFileSystemCaseSensitive = IsFileSystemCaseSensitiveInternal(); - string initialAssemblyParentFolder = Directory.GetParent(new Uri(Assembly.GetExecutingAssembly().EscapedCodeBase).LocalPath).FullName; + string initialAssemblyParentFolder = Directory.GetParent(new Uri(typeof(BaseFixture).Assembly.EscapedCodeBase).LocalPath).FullName; const string sourceRelativePath = @"../../Resources"; ResourcesDirectory = new DirectoryInfo(Path.Combine(initialAssemblyParentFolder, sourceRelativePath)); From 1a12ea6c8eec34ec9882ba998c392df3d8197e95 Mon Sep 17 00:00:00 2001 From: nulltoken Date: Sat, 4 Jul 2015 18:50:29 +0200 Subject: [PATCH 2/2] Update libgit2 to 4d6362b https://github.com/libgit2/libgit2/compare/a56db99...4d6362b --- LibGit2Sharp.Tests/FilterFixture.cs | 163 +++++++++++------- LibGit2Sharp.Tests/StashFixture.cs | 8 +- .../TestHelpers/FileExportFilter.cs | 14 ++ LibGit2Sharp/Core/GitErrorCode.cs | 15 ++ LibGit2Sharp/Core/GitSubmoduleIgnore.cs | 11 ++ LibGit2Sharp/Core/NativeMethods.cs | 8 +- LibGit2Sharp/Core/Proxy.cs | 15 +- LibGit2Sharp/Filter.cs | 16 +- LibGit2Sharp/LibGit2Sharp.csproj | 5 +- LibGit2Sharp/StashApplyStatus.cs | 5 + LibGit2Sharp/Submodule.cs | 5 +- LibGit2Sharp/packages.config | 2 +- 12 files changed, 175 insertions(+), 92 deletions(-) create mode 100644 LibGit2Sharp/Core/GitSubmoduleIgnore.cs diff --git a/LibGit2Sharp.Tests/FilterFixture.cs b/LibGit2Sharp.Tests/FilterFixture.cs index 5b8918064..51576c72c 100644 --- a/LibGit2Sharp.Tests/FilterFixture.cs +++ b/LibGit2Sharp.Tests/FilterFixture.cs @@ -69,9 +69,14 @@ public void InitCallbackNotMadeWhenFilterNeverUsed() initializeCallback); var registration = GlobalSettings.RegisterFilter(filter); - Assert.False(called); - - GlobalSettings.DeregisterFilter(registration); + try + { + Assert.False(called); + } + finally + { + GlobalSettings.DeregisterFilter(registration); + } } [Fact] @@ -89,16 +94,22 @@ public void InitCallbackMadeWhenUsingTheFilter() successCallback, initializeCallback); var registration = GlobalSettings.RegisterFilter(filter); - Assert.False(called); - string repoPath = InitNewRepository(); - using (var repo = CreateTestRepository(repoPath)) + try { - StageNewFile(repo); - Assert.True(called); - } + Assert.False(called); - GlobalSettings.DeregisterFilter(registration); + string repoPath = InitNewRepository(); + using (var repo = CreateTestRepository(repoPath)) + { + StageNewFile(repo); + Assert.True(called); + } + } + finally + { + GlobalSettings.DeregisterFilter(registration); + } } [Fact] @@ -116,13 +127,18 @@ public void WhenStagingFileApplyIsCalledWithCleanForCorrectPath() var filter = new FakeFilter(FilterName, attributes, clean); var registration = GlobalSettings.RegisterFilter(filter); - using (var repo = CreateTestRepository(repoPath)) + try { - StageNewFile(repo); - Assert.True(called); + using (var repo = CreateTestRepository(repoPath)) + { + StageNewFile(repo); + Assert.True(called); + } + } + finally + { + GlobalSettings.DeregisterFilter(registration); } - - GlobalSettings.DeregisterFilter(registration); } [Fact] @@ -138,17 +154,22 @@ public void CleanFilterWritesOutputToObjectTree() var filter = new FakeFilter(FilterName, attributes, cleanCallback); var registration = GlobalSettings.RegisterFilter(filter); - using (var repo = CreateTestRepository(repoPath)) + try { - FileInfo expectedFile = StageNewFile(repo, decodedInput); - var commit = repo.Commit("Clean that file"); - var blob = (Blob)commit.Tree[expectedFile.Name].Target; + using (var repo = CreateTestRepository(repoPath)) + { + FileInfo expectedFile = StageNewFile(repo, decodedInput); + var commit = repo.Commit("Clean that file"); + var blob = (Blob)commit.Tree[expectedFile.Name].Target; - var textDetected = blob.GetContentText(); - Assert.Equal(encodedInput, textDetected); + var textDetected = blob.GetContentText(); + Assert.Equal(encodedInput, textDetected); + } + } + finally + { + GlobalSettings.DeregisterFilter(registration); } - - GlobalSettings.DeregisterFilter(registration); } [Fact] @@ -165,19 +186,24 @@ public void WhenCheckingOutAFileFileSmudgeWritesCorrectFileToWorkingDirectory() var filter = new FakeFilter(FilterName, attributes, null, smudgeCallback); var registration = GlobalSettings.RegisterFilter(filter); - FileInfo expectedFile = CheckoutFileForSmudge(repoPath, branchName, encodedInput); - - string combine = Path.Combine(repoPath, "..", expectedFile.Name); - string readAllText = File.ReadAllText(combine); - Assert.Equal(decodedInput, readAllText); + try + { + FileInfo expectedFile = CheckoutFileForSmudge(repoPath, branchName, encodedInput); - GlobalSettings.DeregisterFilter(registration); + string combine = Path.Combine(repoPath, "..", expectedFile.Name); + string readAllText = File.ReadAllText(combine); + Assert.Equal(decodedInput, readAllText); + } + finally + { + GlobalSettings.DeregisterFilter(registration); + } } [Fact] public void CanFilterLargeFiles() { - const int ContentLength = 128 * 1024 * 1024; + const int ContentLength = 128 * 1024 * 1024 - 13; const char ContentValue = 'x'; char[] content = (new string(ContentValue, 1024)).ToCharArray(); @@ -187,51 +213,60 @@ public void CanFilterLargeFiles() var filter = new FileExportFilter(FilterName, attributes); var registration = GlobalSettings.RegisterFilter(filter); - string filePath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, Guid.NewGuid().ToString() + ".blob"); - FileInfo contentFile = new FileInfo(filePath); - using (var writer = new StreamWriter(contentFile.OpenWrite()) { AutoFlush = true }) + try { - for (int i = 0; i < ContentLength / content.Length; i++) + string filePath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, Guid.NewGuid().ToString() + ".blob"); + FileInfo contentFile = new FileInfo(filePath); + using (var writer = new StreamWriter(contentFile.OpenWrite()) { AutoFlush = true }) { - writer.Write(content); - } - } + int remain = ContentLength; - string attributesPath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, ".gitattributes"); - FileInfo attributesFile = new FileInfo(attributesPath); + while (remain > 0) + { + int chunkSize = remain > content.Length ? content.Length : remain; + writer.Write(content, 0, chunkSize); + remain -= chunkSize; + } + } - string configPath = CreateConfigurationWithDummyUser(Constants.Signature); - var repositoryOptions = new RepositoryOptions { GlobalConfigurationLocation = configPath }; + string attributesPath = Path.Combine(Directory.GetParent(repoPath).Parent.FullName, ".gitattributes"); + FileInfo attributesFile = new FileInfo(attributesPath); - using (Repository repo = new Repository(repoPath, repositoryOptions)) - { - File.WriteAllText(attributesPath, "*.blob filter=test"); - repo.Stage(attributesFile.Name); - repo.Stage(contentFile.Name); - repo.Commit("test"); - contentFile.Delete(); - repo.Checkout("HEAD", new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force }); - } + string configPath = CreateConfigurationWithDummyUser(Constants.Signature); + var repositoryOptions = new RepositoryOptions { GlobalConfigurationLocation = configPath }; - contentFile = new FileInfo(filePath); - Assert.True(contentFile.Exists, "Contents not restored correctly by forced checkout."); - using (StreamReader reader = contentFile.OpenText()) - { - int totalRead = 0; - char[] block = new char[1024]; - int read; - while ((read = reader.Read(block, 0, block.Length)) > 0) + using (Repository repo = new Repository(repoPath, repositoryOptions)) { - Assert.True(CharArrayAreEqual(block, content, read)); - totalRead += read; + File.WriteAllText(attributesPath, "*.blob filter=test"); + repo.Stage(attributesFile.Name); + repo.Stage(contentFile.Name); + repo.Commit("test"); + contentFile.Delete(); + repo.Checkout("HEAD", new CheckoutOptions() { CheckoutModifiers = CheckoutModifiers.Force }); } - Assert.Equal(ContentLength, totalRead); - } + contentFile = new FileInfo(filePath); + Assert.True(contentFile.Exists, "Contents not restored correctly by forced checkout."); + using (StreamReader reader = contentFile.OpenText()) + { + int totalRead = 0; + char[] block = new char[1024]; + int read; + while ((read = reader.Read(block, 0, block.Length)) > 0) + { + Assert.True(CharArrayAreEqual(block, content, read)); + totalRead += read; + } - contentFile.Delete(); + Assert.Equal(ContentLength, totalRead); + } - GlobalSettings.DeregisterFilter(registration); + contentFile.Delete(); + } + finally + { + GlobalSettings.DeregisterFilter(registration); + } } [Fact] diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs index ee413c921..369ac0994 100644 --- a/LibGit2Sharp.Tests/StashFixture.cs +++ b/LibGit2Sharp.Tests/StashFixture.cs @@ -219,7 +219,7 @@ public void CanStashAndApplyWithOptions() repo.Stashes.Add(stasher, "This stash with default options"); Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Apply(0)); - Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(filename)); + Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(filename)); Assert.Equal(1, repo.Stashes.Count()); repo.Stage(filename); @@ -258,13 +258,13 @@ public void CanStashAndPop() Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Pop(0)); Assert.Equal(0, repo.Stashes.Count()); - Assert.Equal(FileStatus.NewInWorkdir, repo.RetrieveStatus(filename)); + Assert.Equal(FileStatus.NewInIndex, repo.RetrieveStatus(filename)); Assert.Equal(contents, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename))); } } [Fact] - public void StashReportsConflictsWhenReinstated() + public void StashFailsWithUncommittedChangesIntheIndex() { string path = SandboxStandardTestRepo(); using (var repo = new Repository(path)) @@ -286,7 +286,7 @@ public void StashReportsConflictsWhenReinstated() repo.Stage(filename); Touch(repo.Info.WorkingDirectory, filename2, newContents); - Assert.Equal(StashApplyStatus.Conflicts, repo.Stashes.Pop(0, new StashApplyOptions + Assert.Equal(StashApplyStatus.UncommittedChanges, repo.Stashes.Pop(0, new StashApplyOptions { ApplyModifiers = StashApplyModifiers.ReinstateIndex, })); diff --git a/LibGit2Sharp.Tests/TestHelpers/FileExportFilter.cs b/LibGit2Sharp.Tests/TestHelpers/FileExportFilter.cs index 3036be414..f68a03412 100644 --- a/LibGit2Sharp.Tests/TestHelpers/FileExportFilter.cs +++ b/LibGit2Sharp.Tests/TestHelpers/FileExportFilter.cs @@ -19,6 +19,20 @@ public FileExportFilter(string name, IEnumerable attribute FilesFiltered = new HashSet(); } + protected override void Create(string path, string root, FilterMode mode) + { + if (mode == FilterMode.Clean) + { + string filename = Path.GetFileName(path); + string cachePath = Path.Combine(root, ".git", filename); + + if (File.Exists(cachePath)) + { + File.Delete(cachePath); + } + } + } + protected override void Clean(string path, string root, Stream input, Stream output) { CleanCalledCount++; diff --git a/LibGit2Sharp/Core/GitErrorCode.cs b/LibGit2Sharp/Core/GitErrorCode.cs index a6c44e68b..1698ad2f5 100644 --- a/LibGit2Sharp/Core/GitErrorCode.cs +++ b/LibGit2Sharp/Core/GitErrorCode.cs @@ -91,6 +91,21 @@ internal enum GitErrorCode /// Peel = -19, + /// + /// Unexpected EOF. + /// + EndOfFile = -20, + + /// + /// Invalid operation or input. + /// + Invalid = -21, + + /// + /// Uncommitted changes in index prevented operation. + /// + Uncommitted = -22, + /// /// Skip and passthrough the given ODB backend. /// diff --git a/LibGit2Sharp/Core/GitSubmoduleIgnore.cs b/LibGit2Sharp/Core/GitSubmoduleIgnore.cs new file mode 100644 index 000000000..5550864a6 --- /dev/null +++ b/LibGit2Sharp/Core/GitSubmoduleIgnore.cs @@ -0,0 +1,11 @@ +namespace LibGit2Sharp.Core +{ + internal enum GitSubmoduleIgnore + { + Unspecified = -1, + None = 1, + Untracked = 2, + Dirty = 3, + All = 4, + } +} diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 74bc91b52..276826f08 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -1526,10 +1526,6 @@ internal static extern int git_submodule_add_to_index( SubmoduleSafeHandle submodule, [MarshalAs(UnmanagedType.Bool)] bool write_index); - [DllImport(libgit2)] - internal static extern int git_submodule_save( - SubmoduleSafeHandle submodule); - [DllImport(libgit2)] internal static extern void git_submodule_free( IntPtr submodule); @@ -1576,7 +1572,9 @@ internal static extern int git_submodule_reload( [DllImport(libgit2)] internal static extern int git_submodule_status( out SubmoduleStatus status, - SubmoduleSafeHandle submodule); + RepositorySafeHandle repo, + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictFilePathMarshaler))] FilePath name, + GitSubmoduleIgnore ignore); [DllImport(libgit2)] internal static extern int git_submodule_init( diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 09ad8a1fb..e86026cf2 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -2679,6 +2679,11 @@ private static StashApplyStatus get_stash_status(int res) return StashApplyStatus.Conflicts; } + if (res == (int)GitErrorCode.Uncommitted) + { + return StashApplyStatus.UncommittedChanges; + } + if (res == (int)GitErrorCode.NotFound) { return StashApplyStatus.NotFound; @@ -2805,12 +2810,6 @@ public static void git_submodule_add_to_index(SubmoduleSafeHandle submodule, boo Ensure.ZeroResult(res); } - public static void git_submodule_save(SubmoduleSafeHandle submodule) - { - var res = NativeMethods.git_submodule_save(submodule); - Ensure.ZeroResult(res); - } - public static void git_submodule_update(SubmoduleSafeHandle submodule, bool init, ref GitSubmoduleOptions options) { var res = NativeMethods.git_submodule_update(submodule, init, ref options); @@ -2868,10 +2867,10 @@ public static void git_submodule_reload(SubmoduleSafeHandle submodule) Ensure.ZeroResult(res); } - public static SubmoduleStatus git_submodule_status(SubmoduleSafeHandle submodule) + public static SubmoduleStatus git_submodule_status(RepositorySafeHandle repo, string name) { SubmoduleStatus status; - var res = NativeMethods.git_submodule_status(out status, submodule); + var res = NativeMethods.git_submodule_status(out status, repo, name, GitSubmoduleIgnore.Unspecified); Ensure.ZeroResult(res); return status; } diff --git a/LibGit2Sharp/Filter.cs b/LibGit2Sharp/Filter.cs index 23814e3ba..770471f6f 100644 --- a/LibGit2Sharp/Filter.cs +++ b/LibGit2Sharp/Filter.cs @@ -112,6 +112,16 @@ protected virtual void Complete(string path, string root, Stream output) protected virtual void Initialize() { } + /// + /// Indicates that a filter is going to be applied for the given file for + /// the given mode. + /// + /// The path of the file being filtered + /// The path of the working directory for the owning repository + /// The filter mode + protected virtual void Create(string path, string root, FilterMode mode) + { } + /// /// Clean the input stream and write to the output stream. /// @@ -234,6 +244,8 @@ int StreamCreateCallback(out IntPtr git_writestream_out, GitFilter self, IntPtr Marshal.PtrToStructure(nextPtr, nextStream); filterSource = FilterSource.FromNativePtr(filterSourcePtr); output = new WriteStream(nextStream, nextPtr); + + Create(filterSource.Path, filterSource.Root, filterSource.SourceMode); } catch (Exception exception) { @@ -308,7 +320,6 @@ unsafe int StreamWriteCallback(IntPtr stream, IntPtr buffer, UIntPtr len) Ensure.ArgumentNotZeroIntPtr(buffer, "buffer"); Ensure.ArgumentIsExpectedIntPtr(stream, thisPtr, "stream"); - string tempFileName = Path.GetTempFileName(); using (UnmanagedMemoryStream input = new UnmanagedMemoryStream((byte*)buffer.ToPointer(), (long)len)) using (BufferedStream outputBuffer = new BufferedStream(output, BufferSize)) { @@ -327,9 +338,6 @@ unsafe int StreamWriteCallback(IntPtr stream, IntPtr buffer, UIntPtr len) return (int)GitErrorCode.Ambiguous; } } - - // clean up after outselves - File.Delete(tempFileName); } catch (Exception exception) { diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index 6e952be2e..9a00d0dad 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,6 +1,6 @@  - + Debug AnyCPU @@ -72,6 +72,7 @@ + @@ -393,7 +394,7 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - +