From 7081cd6ebefc3b3ef25e6e3cf531d52b4764cb05 Mon Sep 17 00:00:00 2001 From: Metalrom Date: Fri, 22 Feb 2013 13:56:57 +0100 Subject: [PATCH] Add Stashes.Remove --- LibGit2Sharp.Tests/StashFixture.cs | 28 ++++++++++++++++++++- LibGit2Sharp/Core/NativeMethods.cs | 3 +++ LibGit2Sharp/Core/Proxy.cs | 9 +++++++ LibGit2Sharp/StashCollection.cs | 39 +++++++++++++++++++++++++++++- 4 files changed, 77 insertions(+), 2 deletions(-) diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs index dbff37122..8e3ece11c 100644 --- a/LibGit2Sharp.Tests/StashFixture.cs +++ b/LibGit2Sharp.Tests/StashFixture.cs @@ -3,6 +3,7 @@ using System.Linq; using LibGit2Sharp.Tests.TestHelpers; using Xunit; +using Xunit.Extensions; namespace LibGit2Sharp.Tests { @@ -21,7 +22,7 @@ public void CannotAddStashAgainstBareRepository() } [Fact] - public void CanAddStash() + public void CanAddAndRemoveStash() { TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); using (var repo = new Repository(path.RepositoryPath)) @@ -61,6 +62,17 @@ public void CanAddStash() // Stash history has been shifted Assert.Equal(repo.Lookup("stash@{0}").Sha, secondStash.Target.Sha); Assert.Equal(repo.Lookup("stash@{1}").Sha, stash.Target.Sha); + + //Remove one stash + repo.Stashes.Remove("stash@{0}"); + Assert.Equal(1, repo.Stashes.Count()); + Stash newTopStash = repo.Stashes.First(); + Assert.Equal("stash@{0}", newTopStash.CanonicalName); + Assert.Equal(stash.Target.Sha, newTopStash.Target.Sha); + + // Stash history has been shifted + Assert.Equal(stash.Target.Sha, repo.Lookup("stash").Sha); + Assert.Equal(stash.Target.Sha, repo.Lookup("stash@{0}").Sha); } } @@ -183,5 +195,19 @@ public void CanStashIgnoredFiles() Assert.NotNull(blob); } } + + [Theory] + [InlineData("stah@{0}")] + [InlineData("stash@{0")] + [InlineData("stash@{fake}")] + [InlineData("dummy")] + public void RemovingStashWithBadParamShouldThrow(string stashRefLog) + { + TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); + using (var repo = new Repository(path.RepositoryPath)) + { + Assert.Throws(() => repo.Stashes.Remove(stashRefLog)); + } + } } } diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 67de340dd..7f26384df 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -953,6 +953,9 @@ internal static extern int git_stash_foreach( git_stash_cb callback, IntPtr payload); + [DllImport(libgit2)] + internal static extern int git_stash_drop(RepositorySafeHandle repo, UIntPtr index); + [DllImport(libgit2)] internal static extern int git_status_file( out FileStatus statusflags, diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 9090f8dd1..2a62f8026 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -1801,6 +1801,15 @@ public static ICollection git_stash_foreach( GitErrorCode.NotFound); } + public static void git_stash_drop(RepositorySafeHandle repo, int index) + { + using (ThreadAffinity()) + { + int res = NativeMethods.git_stash_drop(repo, (UIntPtr) index); + Ensure.BooleanResult(res); + } + } + #endregion #region git_status_ diff --git a/LibGit2Sharp/StashCollection.cs b/LibGit2Sharp/StashCollection.cs index 54078db40..d48ea9d0f 100644 --- a/LibGit2Sharp/StashCollection.cs +++ b/LibGit2Sharp/StashCollection.cs @@ -1,4 +1,5 @@ -using System.Collections; +using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -77,6 +78,42 @@ public virtual Stash Add(Signature stasher, string message = null, StashOptions return new Stash(repo, oid, 0); } + /// + /// Remove a single stashed state from the stash list. + /// + /// The log reference of the stash to delete. Pattern is "stash@{i}" where i is the index of the stash to remove + public virtual void Remove(string stashRefLog) + { + Ensure.ArgumentNotNullOrEmptyString(stashRefLog, "stashRefLog"); + + int index; + if(!TryExtractStashIndexFromRefLog(stashRefLog, out index) || index < 0) + { + throw new ArgumentException("must be a valid stash log reference. Pattern is 'stash@{i}' where 'i' is an integer", "stashRefLog"); + } + + Proxy.git_stash_drop(repo.Handle, index); + } + + private static bool TryExtractStashIndexFromRefLog(string stashRefLog, out int index) + { + index = -1; + + if (!stashRefLog.StartsWith("stash@{")) + { + return false; + } + + if (!stashRefLog.EndsWith("}")) + { + return false; + } + + var indexAsString = stashRefLog.Substring(7, stashRefLog.Length - 8); + + return int.TryParse(indexAsString, out index); + } + private string DebuggerDisplay { get