Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions LibGit2Sharp.Tests/StashFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,22 @@ public void CanStashAndApplyWithOptions()
}
}

[Fact]
public void CanStashWithFilePaths()
{
string path = SandboxStandardTestRepo();
using (var repo = new Repository(path))
{
var stasher = Constants.Signature;

const string filename = "modified_unstaged_file.txt";

var stash = repo.Stashes.Add(stasher, "This stash one file", StashModifiers.Default, new[] { filename });

Assert.NotNull(stash);
}
}

[Fact]
public void CanStashAndPop()
{
Expand Down
28 changes: 28 additions & 0 deletions LibGit2Sharp/Core/GitStashSaveOpts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Runtime.InteropServices;

namespace LibGit2Sharp.Core
{
[StructLayout(LayoutKind.Sequential)]
internal unsafe struct GitStashSaveOpts
{
public GitStashSaveOpts(
StashModifiers flags,
git_signature* stasher,
string message,
GitStrArray paths
)
{
Version = 1;
Flags = flags;
Stasher = stasher;
Message = message;
Paths = paths;
}

public uint Version;
public StashModifiers Flags;
public git_signature* Stasher;
public string Message;
public GitStrArray Paths;
}
}
6 changes: 6 additions & 0 deletions LibGit2Sharp/Core/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1744,6 +1744,12 @@ internal static extern unsafe int git_stash_save(
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(StrictUtf8Marshaler))] string message,
StashModifiers flags);

[DllImport(libgit2, CallingConvention = CallingConvention.Cdecl)]
internal static extern unsafe int git_stash_save_with_opts(
out GitOid stashOid,
git_repository* repo,
ref GitStashSaveOpts saveOpts);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate int git_stash_cb(
UIntPtr index,
Expand Down
29 changes: 29 additions & 0 deletions LibGit2Sharp/Core/Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2857,6 +2857,35 @@ public static unsafe ObjectId git_stash_save(
}
}

public static unsafe ObjectId git_stash_save_with_opts(
RepositoryHandle repo,
Signature stasher,
string message,
StashModifiers options,
string[] paths)
{
using var sigHandle = stasher.BuildHandle();
using var pathStrArray = GitStrArrayManaged.BuildFrom(paths ?? []);

var stashOpts = new GitStashSaveOpts(
options,
sigHandle,
message,
pathStrArray.Array
);

int res = NativeMethods.git_stash_save_with_opts(out var stashOid, repo, ref stashOpts);

if (res == (int)GitErrorCode.NotFound)
{
return null;
}

Ensure.Int32Result(res);

return new ObjectId(stashOid);
}

public static unsafe ICollection<TResult> git_stash_foreach<TResult>(
RepositoryHandle repo,
Func<int, IntPtr, GitOid, TResult> resultSelector)
Expand Down
12 changes: 12 additions & 0 deletions LibGit2Sharp/StashCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ public virtual Stash Add(Signature stasher, string message)
return Add(stasher, message, StashModifiers.Default);
}

public virtual Stash Add(Signature stasher, string message, StashModifiers options, string[] paths)
{
ObjectId oid = Proxy.git_stash_save_with_opts(repo.Handle, stasher, message, options, paths);

if (oid == null)
{
return null;
}

return new Stash(repo, oid, 0);
}

/// <summary>
/// Creates a stash with the specified message.
/// </summary>
Expand Down
5 changes: 5 additions & 0 deletions LibGit2Sharp/StashModifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,10 @@ public enum StashModifiers
/// cleaned up from the working directory
/// </summary>
IncludeIgnored = (1 << 2),

/// <summary>
/// All changes in the index and working directory are left intact
/// </summary>
KeepAll = (1 << 3),
}
}