diff --git a/Lib/NativeBinaries/amd64/git2-9bbc8f3.dll b/Lib/NativeBinaries/amd64/git2-9bbc8f3.dll
deleted file mode 100644
index f162e6c60..000000000
Binary files a/Lib/NativeBinaries/amd64/git2-9bbc8f3.dll and /dev/null differ
diff --git a/Lib/NativeBinaries/amd64/git2-b2d0243.dll b/Lib/NativeBinaries/amd64/git2-b2d0243.dll
new file mode 100644
index 000000000..0d7c8f8dd
Binary files /dev/null and b/Lib/NativeBinaries/amd64/git2-b2d0243.dll differ
diff --git a/Lib/NativeBinaries/amd64/git2-9bbc8f3.pdb b/Lib/NativeBinaries/amd64/git2-b2d0243.pdb
similarity index 51%
rename from Lib/NativeBinaries/amd64/git2-9bbc8f3.pdb
rename to Lib/NativeBinaries/amd64/git2-b2d0243.pdb
index 43f4171fc..1835fa726 100644
Binary files a/Lib/NativeBinaries/amd64/git2-9bbc8f3.pdb and b/Lib/NativeBinaries/amd64/git2-b2d0243.pdb differ
diff --git a/Lib/NativeBinaries/x86/git2-9bbc8f3.dll b/Lib/NativeBinaries/x86/git2-9bbc8f3.dll
deleted file mode 100644
index db04bb5b2..000000000
Binary files a/Lib/NativeBinaries/x86/git2-9bbc8f3.dll and /dev/null differ
diff --git a/Lib/NativeBinaries/x86/git2-b2d0243.dll b/Lib/NativeBinaries/x86/git2-b2d0243.dll
new file mode 100644
index 000000000..cbabc3d6d
Binary files /dev/null and b/Lib/NativeBinaries/x86/git2-b2d0243.dll differ
diff --git a/Lib/NativeBinaries/x86/git2-9bbc8f3.pdb b/Lib/NativeBinaries/x86/git2-b2d0243.pdb
similarity index 52%
rename from Lib/NativeBinaries/x86/git2-9bbc8f3.pdb
rename to Lib/NativeBinaries/x86/git2-b2d0243.pdb
index 89c4624fc..c8b831dd9 100644
Binary files a/Lib/NativeBinaries/x86/git2-9bbc8f3.pdb and b/Lib/NativeBinaries/x86/git2-b2d0243.pdb differ
diff --git a/LibGit2Sharp.Tests/StashFixture.cs b/LibGit2Sharp.Tests/StashFixture.cs
index c9f94064f..228cc3e44 100644
--- a/LibGit2Sharp.Tests/StashFixture.cs
+++ b/LibGit2Sharp.Tests/StashFixture.cs
@@ -176,6 +176,106 @@ public void CanStashAndKeepIndex()
}
}
+ [Fact]
+ public void CanStashAndApplyWithOptions()
+ {
+ string path = SandboxStandardTestRepo();
+ using (var repo = new Repository(path))
+ {
+ var stasher = Constants.Signature;
+
+ const string filename = "staged_file_path.txt";
+ Touch(repo.Info.WorkingDirectory, filename, "I'm staged\n");
+ repo.Stage(filename);
+
+ repo.Stashes.Add(stasher, "This stash with default options");
+ Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Apply(0));
+
+ Assert.Equal(FileStatus.Untracked, repo.RetrieveStatus(filename));
+ Assert.Equal(1, repo.Stashes.Count());
+
+ repo.Stage(filename);
+
+ repo.Stashes.Add(stasher, "This stash with default options");
+ Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Apply(0, StashApplyModifiers.ReinstateIndex));
+
+ Assert.Equal(FileStatus.Added, repo.RetrieveStatus(filename));
+ Assert.Equal(2, repo.Stashes.Count());
+ }
+ }
+
+ [Fact]
+ public void CanStashAndPop()
+ {
+ string path = SandboxStandardTestRepo();
+ using (var repo = new Repository(path))
+ {
+ var stasher = Constants.Signature;
+
+ const string filename = "staged_file_path.txt";
+ const string contents = "I'm staged\n";
+ string contentsNew = "I'm staged" + Environment.NewLine;
+ Touch(repo.Info.WorkingDirectory, filename, contents);
+ repo.Stage(filename);
+
+ repo.Stashes.Add(stasher, "This stash with default options");
+ Assert.Equal(StashApplyStatus.Applied, repo.Stashes.Pop(0));
+
+ Assert.Equal(FileStatus.Untracked, repo.RetrieveStatus(filename));
+ Assert.Equal(0, repo.Stashes.Count());
+ Assert.Equal(contentsNew, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename)));
+ }
+ }
+
+ [Fact]
+ public void StashReportsConflictsWhenReinstated()
+ {
+ string path = SandboxStandardTestRepo();
+ using (var repo = new Repository(path))
+ {
+ var stasher = Constants.Signature;
+
+ const string filename = "staged_file_path.txt";
+ const string originalContents = "I'm pre-stash.";
+ const string filename2 = "unstaged_file_path.txt";
+ const string newContents = "I'm post-stash.";
+
+ Touch(repo.Info.WorkingDirectory, filename, originalContents);
+ repo.Stage(filename);
+ Touch(repo.Info.WorkingDirectory, filename2, originalContents);
+
+ repo.Stashes.Add(stasher, "This stash with default options");
+
+ Touch(repo.Info.WorkingDirectory, filename, newContents);
+ repo.Stage(filename);
+ Touch(repo.Info.WorkingDirectory, filename2, newContents);
+
+ Assert.Equal(StashApplyStatus.Conflicts, repo.Stashes.Pop(0, StashApplyModifiers.ReinstateIndex));
+ Assert.Equal(1, repo.Stashes.Count());
+ Assert.Equal(originalContents, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename)));
+ Assert.Equal(originalContents, File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, filename2)));
+
+ }
+ }
+
+ [Fact]
+ public void StashReportsExistingInWorkDir()
+ {
+ string path = SandboxStandardTestRepo();
+ using (var repo = new Repository(path))
+ {
+ var stasher = Constants.Signature;
+
+ const string filename = "unstaged_file_path.txt";
+ Touch(repo.Info.WorkingDirectory, filename, "I'm unstaged\n");
+
+ repo.Stashes.Add(stasher, "This stash with default options", StashModifiers.IncludeUntracked);
+ Touch(repo.Info.WorkingDirectory, filename, "I'm another unstaged\n");
+
+ Assert.Equal(StashApplyStatus.UntrackedExist, repo.Stashes.Pop(0));
+ }
+ }
+
[Fact]
public void CanStashIgnoredFiles()
{
diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs
index 4416aa601..3424094be 100644
--- a/LibGit2Sharp/Core/GitCheckoutOpts.cs
+++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs
@@ -158,6 +158,7 @@ internal struct GitCheckoutOpts
public GitStrArray paths;
public IntPtr baseline;
+ public IntPtr baseline_index;
public IntPtr target_directory;
public IntPtr ancestor_label;
diff --git a/LibGit2Sharp/Core/GitMergeOpts.cs b/LibGit2Sharp/Core/GitMergeOpts.cs
index a2ebe979d..7ed690fea 100644
--- a/LibGit2Sharp/Core/GitMergeOpts.cs
+++ b/LibGit2Sharp/Core/GitMergeOpts.cs
@@ -31,6 +31,11 @@ internal struct GitMergeOpts
/// Flags for automerging content.
///
public MergeFileFavor MergeFileFavorFlags;
+
+ ///
+ /// Flags to use for file merging.
+ ///
+ public GitMergeFileFlags FileFlags;
}
///
@@ -105,4 +110,53 @@ internal enum GitMergeTreeFlags
///
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
}
+
+ [Flags]
+ internal enum GitMergeFileFlags
+ {
+ ///
+ /// No options.
+ ///
+ GIT_MERGE_FILE_DEFAULT = 0,
+
+ ///
+ /// Creates standard conflicted merge files.
+ ///
+ GIT_MERGE_FILE_STYLE_MERGE = (1 << 0),
+
+ ///
+ /// Creates diff3 style files.
+ ///
+ GIT_MERGE_FILE_STYLE_DIFF3 = (1 << 1),
+
+ ///
+ /// Condenses non-alphanumeric regions for simplified diff files.
+ ///
+ GIT_MERGE_FILE_SIMPLIFY_ALNUM = (1 << 2),
+
+ ///
+ /// Ignores all whitespace.
+ ///
+ GIT_MERGE_FILE_IGNORE_WHITESPACE = (1 << 3),
+
+ ///
+ /// Ignores changes in amount of whitespace.
+ ///
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE = (1 << 4),
+
+ ///
+ /// Ignores whitespace at the end of the line.
+ ///
+ GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL = (1 << 5),
+
+ ///
+ /// Uses the 'patience' diff algorithm.
+ ///
+ GIT_MERGE_FILE_DIFF_PATIENCE = (1 << 6),
+
+ ///
+ /// Take extra time to find the minimal diff.
+ ///
+ GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
+ }
}
diff --git a/LibGit2Sharp/Core/GitSmartSubtransportRegistration.cs b/LibGit2Sharp/Core/GitSmartSubtransportRegistration.cs
index 724c6c414..b816cae9c 100644
--- a/LibGit2Sharp/Core/GitSmartSubtransportRegistration.cs
+++ b/LibGit2Sharp/Core/GitSmartSubtransportRegistration.cs
@@ -8,9 +8,11 @@ internal class GitSmartSubtransportRegistration
{
public IntPtr SubtransportCallback;
public uint Rpc;
+ public IntPtr Param;
public delegate int create_callback(
out IntPtr subtransport,
- IntPtr transport);
+ IntPtr transport,
+ IntPtr param);
}
}
diff --git a/LibGit2Sharp/Core/NativeDllName.cs b/LibGit2Sharp/Core/NativeDllName.cs
index 01f148a91..9d4d1a4bd 100644
--- a/LibGit2Sharp/Core/NativeDllName.cs
+++ b/LibGit2Sharp/Core/NativeDllName.cs
@@ -2,6 +2,6 @@ namespace LibGit2Sharp.Core
{
internal static class NativeDllName
{
- public const string Name = "git2-9bbc8f3";
+ public const string Name = "git2-b2d0243";
}
}
diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs
index a8fb1eacf..699eed39e 100644
--- a/LibGit2Sharp/Core/NativeMethods.cs
+++ b/LibGit2Sharp/Core/NativeMethods.cs
@@ -726,7 +726,7 @@ internal static extern int git_note_remove(
[DllImport(libgit2)]
internal static extern int git_note_default_ref(
- [MarshalAs(UnmanagedType.CustomMarshaler, MarshalCookie = UniqueId.UniqueIdentifier, MarshalTypeRef = typeof(LaxUtf8NoCleanupMarshaler))] out string notes_ref,
+ GitBuf buf,
RepositorySafeHandle repo);
internal delegate int git_note_foreach_cb(
@@ -1325,6 +1325,20 @@ internal static extern int git_stash_foreach(
[DllImport(libgit2)]
internal static extern int git_stash_drop(RepositorySafeHandle repo, UIntPtr index);
+ [DllImport(libgit2)]
+ internal static extern int git_stash_apply(
+ RepositorySafeHandle repo,
+ UIntPtr index,
+ ref GitCheckoutOpts opts,
+ StashApplyModifiers flags);
+
+ [DllImport(libgit2)]
+ internal static extern int git_stash_pop(
+ RepositorySafeHandle repo,
+ UIntPtr index,
+ ref GitCheckoutOpts opts,
+ StashApplyModifiers flags);
+
[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 ab2f7eadc..443903921 100644
--- a/LibGit2Sharp/Core/Proxy.cs
+++ b/LibGit2Sharp/Core/Proxy.cs
@@ -1298,12 +1298,12 @@ public static ObjectId git_note_create(
public static string git_note_default_ref(RepositorySafeHandle repo)
{
using (ThreadAffinity())
+ using (var buf = new GitBuf())
{
- string notes_ref;
- int res = NativeMethods.git_note_default_ref(out notes_ref, repo);
+ int res = NativeMethods.git_note_default_ref(buf, repo);
Ensure.ZeroResult(res);
- return notes_ref;
+ return LaxUtf8Marshaler.FromNative(buf.ptr);
}
}
@@ -2719,7 +2719,47 @@ public static void git_stash_drop(RepositorySafeHandle repo, int index)
using (ThreadAffinity())
{
int res = NativeMethods.git_stash_drop(repo, (UIntPtr) index);
- Ensure.BooleanResult(res);
+ Ensure.ZeroResult(res);
+ }
+ }
+
+ private static StashApplyStatus get_stash_status(int res)
+ {
+ if (res == (int)GitErrorCode.MergeConflict)
+ {
+ return StashApplyStatus.Conflicts;
+ }
+
+ if (res == (int)GitErrorCode.Exists)
+ {
+ return StashApplyStatus.UntrackedExist;
+ }
+
+ Ensure.ZeroResult(res);
+ return StashApplyStatus.Applied;
+ }
+
+ public static StashApplyStatus git_stash_apply(
+ RepositorySafeHandle repo,
+ int index,
+ ref GitCheckoutOpts opts,
+ StashApplyModifiers flags)
+ {
+ using (ThreadAffinity())
+ {
+ return get_stash_status(NativeMethods.git_stash_apply(repo, (UIntPtr)index, ref opts, flags));
+ }
+ }
+
+ public static StashApplyStatus git_stash_pop(
+ RepositorySafeHandle repo,
+ int index,
+ ref GitCheckoutOpts opts,
+ StashApplyModifiers flags)
+ {
+ using (ThreadAffinity())
+ {
+ return get_stash_status(NativeMethods.git_stash_pop(repo, (UIntPtr)index, ref opts, flags));
}
}
diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj
index 3ca4a3892..194a1fedb 100644
--- a/LibGit2Sharp/LibGit2Sharp.csproj
+++ b/LibGit2Sharp/LibGit2Sharp.csproj
@@ -134,6 +134,7 @@
+
diff --git a/LibGit2Sharp/SmartSubtransportRegistration.cs b/LibGit2Sharp/SmartSubtransportRegistration.cs
index df7c1cb4b..8247b023c 100644
--- a/LibGit2Sharp/SmartSubtransportRegistration.cs
+++ b/LibGit2Sharp/SmartSubtransportRegistration.cs
@@ -80,7 +80,8 @@ private static class EntryPoints
private static int Subtransport(
out IntPtr subtransport,
- IntPtr transport)
+ IntPtr transport,
+ IntPtr payload)
{
subtransport = IntPtr.Zero;
diff --git a/LibGit2Sharp/StashApplyStatus.cs b/LibGit2Sharp/StashApplyStatus.cs
new file mode 100644
index 000000000..86fa6bff6
--- /dev/null
+++ b/LibGit2Sharp/StashApplyStatus.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace LibGit2Sharp
+{
+ ///
+ /// The status of what happened as a result of a stash application.
+ ///
+ public enum StashApplyStatus
+ {
+ ///
+ /// The changes were successfully stashed.
+ ///
+ Applied,
+
+ ///
+ /// The stash application resulted in conflicts.
+ ///
+ Conflicts,
+
+ ///
+ /// The stash application was not applied due to existing
+ /// untracked files that would be overwritten by the stash
+ /// contents.
+ ///
+ UntrackedExist,
+ }
+}
diff --git a/LibGit2Sharp/StashCollection.cs b/LibGit2Sharp/StashCollection.cs
index ffe137a5b..77c674cdd 100644
--- a/LibGit2Sharp/StashCollection.cs
+++ b/LibGit2Sharp/StashCollection.cs
@@ -114,6 +114,36 @@ public virtual void Remove(int index)
Proxy.git_stash_drop(repo.Handle, index);
}
+ ///
+ /// Applies a single stashed state from the stash list
+ ///
+ /// the index of the stash to remove (0 being the most recent one).
+ /// the options to use for checking out the stash.
+ /// the flags to use for applying the changes.
+ public virtual StashApplyStatus Apply(int index, StashApplyModifiers flags = StashApplyModifiers.Default, CheckoutOptions options = null)
+ {
+ using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options ?? new CheckoutOptions()))
+ {
+ var opts = checkoutOptionsWrapper.Options;
+ return Proxy.git_stash_apply(repo.Handle, index, ref opts, flags);
+ }
+ }
+
+ ///
+ /// Pops a single stashed state from the stash list
+ ///
+ /// the index of the stash to remove (0 being the most recent one).
+ /// the options to use for checking out the stash.
+ /// the flags to use for applying the changes.
+ public virtual StashApplyStatus Pop(int index, StashApplyModifiers flags = StashApplyModifiers.Default, CheckoutOptions options = null)
+ {
+ using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options ?? new CheckoutOptions()))
+ {
+ var opts = checkoutOptionsWrapper.Options;
+ return Proxy.git_stash_pop(repo.Handle, index, ref opts, flags);
+ }
+ }
+
private string DebuggerDisplay
{
get
diff --git a/LibGit2Sharp/StashModifiers.cs b/LibGit2Sharp/StashModifiers.cs
index b0e6d41ff..1f2f66be7 100644
--- a/LibGit2Sharp/StashModifiers.cs
+++ b/LibGit2Sharp/StashModifiers.cs
@@ -31,4 +31,23 @@ public enum StashModifiers
///
IncludeIgnored = (1 << 2),
}
+
+ ///
+ /// Options controlling Stash applying behavior.
+ ///
+ [Flags]
+ public enum StashApplyModifiers
+ {
+ ///
+ /// Default. Reinstante working directory stashed
+ /// changes.
+ ///
+ Default = 0,
+
+ ///
+ /// Reinstate both index and working directory stashed
+ /// changes.
+ ///
+ ReinstateIndex = (1 << 0),
+ }
}
diff --git a/LibGit2Sharp/libgit2_hash.txt b/LibGit2Sharp/libgit2_hash.txt
index 1f04184d9..985448b76 100644
--- a/LibGit2Sharp/libgit2_hash.txt
+++ b/LibGit2Sharp/libgit2_hash.txt
@@ -1 +1 @@
-9bbc8f350b80a5a6e94651ec667cf9e5d545b317
+b2d02433141ddc4c914a6b0e0027f6c58fc11cb6
diff --git a/libgit2 b/libgit2
index 9bbc8f350..47f374002 160000
--- a/libgit2
+++ b/libgit2
@@ -1 +1 @@
-Subproject commit 9bbc8f350b80a5a6e94651ec667cf9e5d545b317
+Subproject commit 47f37400253210f483d84fb9c2ecf44fb5986849
diff --git a/nuget.package/build/LibGit2Sharp.props b/nuget.package/build/LibGit2Sharp.props
index b12792b74..3c028bc9e 100644
--- a/nuget.package/build/LibGit2Sharp.props
+++ b/nuget.package/build/LibGit2Sharp.props
@@ -1,20 +1,20 @@
-
- NativeBinaries\amd64\git2-9bbc8f3.dll
+
+ NativeBinaries\amd64\git2-b2d0243.dll
PreserveNewest
-
- NativeBinaries\amd64\git2-9bbc8f3.pdb
+
+ NativeBinaries\amd64\git2-b2d0243.pdb
PreserveNewest
-
- NativeBinaries\x86\git2-9bbc8f3.dll
+
+ NativeBinaries\x86\git2-b2d0243.dll
PreserveNewest
-
- NativeBinaries\x86\git2-9bbc8f3.pdb
+
+ NativeBinaries\x86\git2-b2d0243.pdb
PreserveNewest