diff --git a/Lib/NativeBinaries/amd64/git2.dll b/Lib/NativeBinaries/amd64/git2.dll index 6d668c9ca..9eb2096ae 100644 Binary files a/Lib/NativeBinaries/amd64/git2.dll and b/Lib/NativeBinaries/amd64/git2.dll differ diff --git a/Lib/NativeBinaries/amd64/git2.pdb b/Lib/NativeBinaries/amd64/git2.pdb index 23fac854b..8cdaaf6f1 100644 Binary files a/Lib/NativeBinaries/amd64/git2.pdb and b/Lib/NativeBinaries/amd64/git2.pdb differ diff --git a/Lib/NativeBinaries/x86/git2.dll b/Lib/NativeBinaries/x86/git2.dll index 2a8420816..5c8e4b7c4 100644 Binary files a/Lib/NativeBinaries/x86/git2.dll and b/Lib/NativeBinaries/x86/git2.dll differ diff --git a/Lib/NativeBinaries/x86/git2.pdb b/Lib/NativeBinaries/x86/git2.pdb index 3f9756224..4a72f127e 100644 Binary files a/Lib/NativeBinaries/x86/git2.pdb and b/Lib/NativeBinaries/x86/git2.pdb differ diff --git a/LibGit2Sharp.Tests/CheckoutFixture.cs b/LibGit2Sharp.Tests/CheckoutFixture.cs index a09802d1f..17d4a0528 100644 --- a/LibGit2Sharp.Tests/CheckoutFixture.cs +++ b/LibGit2Sharp.Tests/CheckoutFixture.cs @@ -23,8 +23,9 @@ public void CanCheckoutAnExistingBranch(string branchName) Branch master = repo.Branches["master"]; Assert.True(master.IsCurrentRepositoryHead); - // Hard reset to ensure that working directory, index, and HEAD match - repo.Reset(ResetOptions.Hard); + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); Branch branch = repo.Branches[branchName]; @@ -55,8 +56,9 @@ public void CanCheckoutAnExistingBranchByName(string branchName) Branch master = repo.Branches["master"]; Assert.True(master.IsCurrentRepositoryHead); - // Hard reset to ensure that working directory, index, and HEAD match - repo.Reset(ResetOptions.Hard); + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); Branch test = repo.Checkout(branchName); @@ -84,8 +86,9 @@ public void CanCheckoutAnArbitraryCommit(string commitPointer) Branch master = repo.Branches["master"]; Assert.True(master.IsCurrentRepositoryHead); - // Hard reset to ensure that working directory, index, and HEAD match - repo.Reset(ResetOptions.Hard); + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); Branch detachedHead = repo.Checkout(commitPointer); @@ -197,8 +200,9 @@ public void CanForcefullyCheckoutWithStagedChanges() Branch master = repo.Branches["master"]; Assert.True(master.IsCurrentRepositoryHead); - // Hard reset to ensure that working directory, index, and HEAD match - repo.Reset(ResetOptions.Hard); + // Set the working directory to the current head + ResetAndCleanWorkingDirectory(repo); + Assert.False(repo.Index.RetrieveStatus().IsDirty); // Add local change @@ -335,5 +339,19 @@ private void PopulateBasicRepository(Repository repo) repo.CreateBranch(otherBranchName); } + + /// + /// Reset and clean current working directory. This will ensure that the current + /// working directory matches the current Head commit. + /// + /// Repository whose current working directory should be operated on. + private void ResetAndCleanWorkingDirectory(Repository repo) + { + // Reset the index and the working tree. + repo.Reset(ResetOptions.Hard); + + // Remove untracked files. + repo.Index.CleanWorkingDirectory(); + } } } diff --git a/LibGit2Sharp.Tests/CommitFixture.cs b/LibGit2Sharp.Tests/CommitFixture.cs index eafe598d5..b40a5cdac 100644 --- a/LibGit2Sharp.Tests/CommitFixture.cs +++ b/LibGit2Sharp.Tests/CommitFixture.cs @@ -28,7 +28,9 @@ public void CanCorrectlyCountCommitsWhenSwitchingToAnotherBranch() TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); using (var repo = new Repository(path.RepositoryPath)) { + // Hard reset and then remove untracked files repo.Reset(ResetOptions.Hard); + repo.Index.CleanWorkingDirectory(); repo.Checkout("test"); Assert.Equal(2, repo.Commits.Count()); @@ -227,7 +229,9 @@ public void CanEnumerateFromDetachedHead() TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); using (var repoClone = new Repository(path.RepositoryPath)) { + // Hard reset and then remove untracked files repoClone.Reset(ResetOptions.Hard); + repoClone.Index.CleanWorkingDirectory(); string headSha = repoClone.Head.Tip.Sha; repoClone.Checkout(headSha); diff --git a/LibGit2Sharp.Tests/ConfigurationFixture.cs b/LibGit2Sharp.Tests/ConfigurationFixture.cs index 604c49416..2e22010d7 100644 --- a/LibGit2Sharp.Tests/ConfigurationFixture.cs +++ b/LibGit2Sharp.Tests/ConfigurationFixture.cs @@ -77,6 +77,7 @@ public void CanUnsetAnEntryFromTheGlobalConfiguration() .AppendFormat("Man-I-am-totally-global = 42{0}", Environment.NewLine); File.WriteAllText(globalLocation, sb.ToString()); + File.WriteAllText(systemLocation, string.Empty); var options = new RepositoryOptions { diff --git a/LibGit2Sharp.Tests/IndexFixture.cs b/LibGit2Sharp.Tests/IndexFixture.cs index c286da293..50d0d01ba 100644 --- a/LibGit2Sharp.Tests/IndexFixture.cs +++ b/LibGit2Sharp.Tests/IndexFixture.cs @@ -82,6 +82,24 @@ public void ReadIndexWithBadParamsFails() } } + [Fact] + public void CanCleanWorkingDirectory() + { + TemporaryCloneOfTestRepo path = BuildTemporaryCloneOfTestRepo(StandardTestRepoWorkingDirPath); + using (var repo = new Repository(path.RepositoryPath)) + { + // Verify that there are the expected number of entries and untracked files + Assert.Equal(6, repo.Index.RetrieveStatus().Count()); + Assert.Equal(1, repo.Index.RetrieveStatus().Untracked.Count()); + + repo.Index.CleanWorkingDirectory(); + + // Verify that there are the expected number of entries and 0 untracked files + Assert.Equal(5, repo.Index.RetrieveStatus().Count()); + Assert.Equal(0, repo.Index.RetrieveStatus().Untracked.Count()); + } + } + [Theory] [InlineData("1/branch_file.txt", FileStatus.Unaltered, true, FileStatus.Unaltered, true, 0)] [InlineData("README", FileStatus.Unaltered, true, FileStatus.Unaltered, true, 0)] diff --git a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs index 1093f09bc..a5c3d2a80 100644 --- a/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs +++ b/LibGit2Sharp.Tests/RepositoryOptionsFixture.cs @@ -157,6 +157,7 @@ public void CanProvideDifferentConfigurationFilesToARepository() .AppendFormat("email = {0}{1}", email, Environment.NewLine); File.WriteAllText(globalLocation, sb.ToString()); + File.WriteAllText(systemLocation, string.Empty); var options = new RepositoryOptions { GlobalConfigurationLocation = globalLocation, diff --git a/LibGit2Sharp.Tests/ResetHeadFixture.cs b/LibGit2Sharp.Tests/ResetHeadFixture.cs index 5dbf383bc..f738a7f17 100644 --- a/LibGit2Sharp.Tests/ResetHeadFixture.cs +++ b/LibGit2Sharp.Tests/ResetHeadFixture.cs @@ -174,7 +174,7 @@ public void HardResetUpdatesTheContentOfTheWorkingDirectory() names.Sort(StringComparer.Ordinal); File.Delete(Path.Combine(repo.Info.WorkingDirectory, "README")); - File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "WillBeRemoved.txt"), "content\n"); + File.WriteAllText(Path.Combine(repo.Info.WorkingDirectory, "WillNotBeRemoved.txt"), "content\n"); Assert.True(names.Count > 4); @@ -183,7 +183,7 @@ public void HardResetUpdatesTheContentOfTheWorkingDirectory() names = new DirectoryInfo(repo.Info.WorkingDirectory).GetFileSystemInfos().Select(fsi => fsi.Name).ToList(); names.Sort(StringComparer.Ordinal); - Assert.Equal(new[] { ".git", "README", "branch_file.txt", "new.txt" }, names); + Assert.Equal(new[] { ".git", "README", "WillNotBeRemoved.txt", "branch_file.txt", "new.txt", "new_untracked_file.txt" }, names); } } } diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs index 39a6f6ce8..a1b984e53 100644 --- a/LibGit2Sharp/Core/GitCheckoutOpts.cs +++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs @@ -3,11 +3,12 @@ namespace LibGit2Sharp.Core { - internal delegate int skipped_notify_cb( - IntPtr skipped_file, + internal delegate int conflict_cb( + IntPtr conflicting_path, ref GitOid blob_oid, - int file_mode, - IntPtr payload); + uint index_mode, + uint wd_mode, + IntPtr payload); internal delegate void progress_cb( IntPtr strPtr, @@ -23,8 +24,8 @@ internal class GitCheckoutOpts public int DirMode; public int FileMode; public int FileOpenFlags; - public skipped_notify_cb skippedNotifyCb; - public IntPtr NotifyPayload; + public conflict_cb conflictCb; + public IntPtr ConflictPayload; public progress_cb ProgressCb; public IntPtr ProgressPayload; public UnSafeNativeMethods.git_strarray paths; @@ -33,9 +34,85 @@ internal class GitCheckoutOpts [Flags] internal enum CheckoutStrategy { - GIT_CHECKOUT_DEFAULT = (1 << 0), - GIT_CHECKOUT_OVERWRITE_MODIFIED = (1 << 1), - GIT_CHECKOUT_CREATE_MISSING = (1 << 2), - GIT_CHECKOUT_REMOVE_UNTRACKED = (1 << 3), + /// + /// Default is a dry run, no actual updates. + /// + GIT_CHECKOUT_DEFAULT = 0, + + /// + /// Allow update of entries where working dir matches HEAD. + /// + GIT_CHECKOUT_UPDATE_UNMODIFIED = (1 << 0), + + /// + /// Allow update of entries where working dir does not have file. + /// + GIT_CHECKOUT_UPDATE_MISSING = (1 << 1), + + /// + /// Allow safe updates that cannot overwrite uncommited data. + /// + GIT_CHECKOUT_SAFE = + (GIT_CHECKOUT_UPDATE_UNMODIFIED | GIT_CHECKOUT_UPDATE_MISSING), + + /// + /// Allow update of entries in working dir that are modified from HEAD. + /// + GIT_CHECKOUT_UPDATE_MODIFIED = (1 << 2), + + /// + /// Update existing untracked files that are now present in the index. + /// + GIT_CHECKOUT_UPDATE_UNTRACKED = (1 << 3), + + /// + /// Allow all updates to force working directory to look like index. + /// + GIT_CHECKOUT_FORCE = + (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_UPDATE_MODIFIED | GIT_CHECKOUT_UPDATE_UNTRACKED), + + /// + /// Allow checkout to make updates even if conflicts are found. + /// + GIT_CHECKOUT_ALLOW_CONFLICTS = (1 << 4), + + /// + /// Remove untracked files not in index (that are not ignored). + /// + GIT_CHECKOUT_REMOVE_UNTRACKED = (1 << 5), + + /// + /// Only update existing files, don't create new ones. + /// + GIT_CHECKOUT_UPDATE_ONLY = (1 << 6), + + /* + * THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED. + */ + + /// + /// Allow checkout to skip unmerged files (NOT IMPLEMENTED). + /// + GIT_CHECKOUT_SKIP_UNMERGED = (1 << 10), + + /// + /// For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED). + /// + GIT_CHECKOUT_USE_OURS = (1 << 11), + + /// + /// For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED). + /// + GIT_CHECKOUT_USE_THEIRS = (1 << 12), + + /// + /// Recursively checkout submodules with same options (NOT IMPLEMENTED). + /// + GIT_CHECKOUT_UPDATE_SUBMODULES = (1 << 16), + + /// + /// Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED) */ + /// + GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED = (1 << 17), } } diff --git a/LibGit2Sharp/Core/GitDiff.cs b/LibGit2Sharp/Core/GitDiff.cs index a760b8032..cbca24ac1 100644 --- a/LibGit2Sharp/Core/GitDiff.cs +++ b/LibGit2Sharp/Core/GitDiff.cs @@ -6,16 +6,111 @@ namespace LibGit2Sharp.Core [Flags] internal enum GitDiffOptionFlags { + /// + /// Normal diff, the default. + /// GIT_DIFF_NORMAL = 0, + + /// + /// Reverse the sides of the diff. + /// GIT_DIFF_REVERSE = (1 << 0), + + /// + /// Treat all files as text, disabling binary attributes and detection. + /// GIT_DIFF_FORCE_TEXT = (1 << 1), + + /// + /// Ignore all whitespace. + /// GIT_DIFF_IGNORE_WHITESPACE = (1 << 2), + + /// + /// Ignore changes in amount of whitespace. + /// GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3), + + /// + /// Ignore whitespace at end of line. + /// GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4), + + /// + /// Exclude submodules from the diff completely. + /// GIT_DIFF_IGNORE_SUBMODULES = (1 << 5), + + /// + /// Use the "patience diff" algorithm (currently unimplemented). + /// GIT_DIFF_PATIENCE = (1 << 6), + + /// + /// Include ignored files in the diff list. + /// GIT_DIFF_INCLUDE_IGNORED = (1 << 7), + + /// + /// Include untracked files in the diff list. + /// GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), + + /// + /// Include unmodified files in the diff list. + /// + GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), + + /// + /// Even with the GIT_DIFF_INCLUDE_UNTRACKED flag, when an untracked + /// directory is found, only a single entry for the directory is added + /// to the diff list; with this flag, all files under the directory will + /// be included, too. + /// + GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), + + /// + /// If the pathspec is set in the diff options, this flags means to + /// apply it as an exact match instead of as an fnmatch pattern. + /// + GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), + + /// + /// Use case insensitive filename comparisons. + /// + GIT_DIFF_DELTAS_ARE_ICASE = (1 << 12), + + /// + /// When generating patch text, include the content of untracked files. + /// + GIT_DIFF_INCLUDE_UNTRACKED_CONTENT = (1 << 13), + + /// + /// Disable updating of the `binary` flag in delta records. This is + /// useful when iterating over a diff if you don't need hunk and data + /// callbacks and want to avoid having to load file completely. + /// + GIT_DIFF_SKIP_BINARY_CHECK = (1 << 14), + + /// + /// Normally, a type change between files will be converted into a + /// DELETED record for the old and an ADDED record for the new; this + /// options enabled the generation of TYPECHANGE delta records. + /// + GIT_DIFF_INCLUDE_TYPECHANGE = (1 << 15), + + /// + /// Even with GIT_DIFF_INCLUDE_TYPECHANGE, blob->tree changes still + /// generally show as a DELETED blob. This flag tries to correctly + /// label blob->tree transitions as TYPECHANGE records with new_file's + /// mode set to tree. Note: the tree SHA will not be available. + /// + GIT_DIFF_INCLUDE_TYPECHANGE_TREES = (1 << 16), + + /// + /// Ignore file mode changes. + /// + GIT_DIFF_IGNORE_FILEMODE = (1 << 17), } [StructLayout(LayoutKind.Sequential)] diff --git a/LibGit2Sharp/Core/GitErrorCategory.cs b/LibGit2Sharp/Core/GitErrorCategory.cs index 81431d538..d8d06676f 100644 --- a/LibGit2Sharp/Core/GitErrorCategory.cs +++ b/LibGit2Sharp/Core/GitErrorCategory.cs @@ -18,5 +18,10 @@ internal enum GitErrorCategory Tag, Tree, Indexer, + Ssl, + Submodule, + Thread, + Stash, + Checkout, } } diff --git a/LibGit2Sharp/Core/GitErrorCode.cs b/LibGit2Sharp/Core/GitErrorCode.cs index 230ce17d6..9a6db9829 100644 --- a/LibGit2Sharp/Core/GitErrorCode.cs +++ b/LibGit2Sharp/Core/GitErrorCode.cs @@ -35,6 +35,16 @@ internal enum GitErrorCode /// BareRepo = -8, + /// + /// Operation cannot be performed against an orphaned HEAD. + /// + OrphanedHead = -9, + + /// + /// Operation cannot be performed against a not fully merged index. + /// + UnmergedEntries = -8, + /// /// Skip and passthrough the given ODB backend. /// diff --git a/LibGit2Sharp/Core/GitOdbBackend.cs b/LibGit2Sharp/Core/GitOdbBackend.cs index 65792ed52..19128bc4d 100644 --- a/LibGit2Sharp/Core/GitOdbBackend.cs +++ b/LibGit2Sharp/Core/GitOdbBackend.cs @@ -29,6 +29,7 @@ static GitOdbBackend() public readstream_callback ReadStream; public exists_callback Exists; public foreach_callback Foreach; + public IntPtr Writepack; public free_callback Free; /* The libgit2 structure definition ends here. Subsequent fields are for libgit2sharp bookkeeping. */ diff --git a/LibGit2Sharp/Core/NativeMethods.cs b/LibGit2Sharp/Core/NativeMethods.cs index 0d3b2f207..f50501bc3 100644 --- a/LibGit2Sharp/Core/NativeMethods.cs +++ b/LibGit2Sharp/Core/NativeMethods.cs @@ -157,6 +157,12 @@ internal static extern int git_checkout_head( RepositorySafeHandle repo, GitCheckoutOpts opts); + [DllImport(libgit2)] + internal static extern int git_checkout_index( + RepositorySafeHandle repo, + IndexSafeHandle index, + GitCheckoutOpts opts); + [DllImport(libgit2)] internal static extern int git_clone( out RepositorySafeHandle repo, @@ -303,18 +309,19 @@ internal static extern int git_config_foreach( [DllImport(libgit2)] internal static extern int git_diff_tree_to_tree( + out DiffListSafeHandle diff, RepositorySafeHandle repo, - GitDiffOptions options, GitObjectSafeHandle oldTree, GitObjectSafeHandle newTree, - out DiffListSafeHandle diff); + GitDiffOptions options); [DllImport(libgit2)] internal static extern int git_diff_index_to_tree( + out DiffListSafeHandle diff, RepositorySafeHandle repo, - GitDiffOptions options, GitObjectSafeHandle oldTree, - out DiffListSafeHandle diff); + IndexSafeHandle index, + GitDiffOptions options); [DllImport(libgit2)] internal static extern int git_diff_merge( @@ -323,16 +330,17 @@ internal static extern int git_diff_merge( [DllImport(libgit2)] internal static extern int git_diff_workdir_to_index( + out DiffListSafeHandle diff, RepositorySafeHandle repo, - GitDiffOptions options, - out DiffListSafeHandle diff); + IndexSafeHandle index, + GitDiffOptions options); [DllImport(libgit2)] internal static extern int git_diff_workdir_to_tree( + out DiffListSafeHandle diff, RepositorySafeHandle repo, - GitDiffOptions options, GitObjectSafeHandle oldTree, - out DiffListSafeHandle diff); + GitDiffOptions options); internal delegate int git_diff_file_fn( IntPtr data, @@ -814,10 +822,10 @@ internal static extern int git_tag_delete( internal static extern OidSafeHandle git_tag_target_oid(GitObjectSafeHandle tag); [DllImport(libgit2)] - internal static extern GitObjectType git_tag_type(GitObjectSafeHandle tag); + internal static extern GitObjectType git_tag_target_type(GitObjectSafeHandle tag); [DllImport(libgit2)] - internal static extern void git_threads_init(); + internal static extern int git_threads_init(); [DllImport(libgit2)] internal static extern void git_threads_shutdown(); diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index 179f0bc22..6c54c5b76 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -188,6 +188,15 @@ public static void git_checkout_head(RepositorySafeHandle repo, GitCheckoutOpts } } + public static void git_checkout_index(RepositorySafeHandle repo, IndexSafeHandle index, GitCheckoutOpts opts) + { + using (ThreadAffinity()) + { + int res = NativeMethods.git_checkout_index(repo, index, opts); + Ensure.Success(res); + } + } + #endregion #region git_clone_ @@ -506,14 +515,15 @@ public static void git_diff_blobs( public static DiffListSafeHandle git_diff_index_to_tree( RepositorySafeHandle repo, - GitDiffOptions options, - ObjectId oldTree) + IndexSafeHandle index, + ObjectId oldTree, + GitDiffOptions options) { using (ThreadAffinity()) using (var osw = new ObjectSafeWrapper(oldTree, repo)) { DiffListSafeHandle diff; - int res = NativeMethods.git_diff_index_to_tree(repo, options, osw.ObjectPtr, out diff); + int res = NativeMethods.git_diff_index_to_tree(out diff, repo, osw.ObjectPtr, index, options); Ensure.Success(res); return diff; @@ -545,16 +555,16 @@ public static void git_diff_print_patch(DiffListSafeHandle diff, NativeMethods.g public static DiffListSafeHandle git_diff_tree_to_tree( RepositorySafeHandle repo, - GitDiffOptions options, ObjectId oldTree, - ObjectId newTree) + ObjectId newTree, + GitDiffOptions options) { using (ThreadAffinity()) using (var osw1 = new ObjectSafeWrapper(oldTree, repo)) using (var osw2 = new ObjectSafeWrapper(newTree, repo)) { DiffListSafeHandle diff; - int res = NativeMethods.git_diff_tree_to_tree(repo, options, osw1.ObjectPtr, osw2.ObjectPtr, out diff); + int res = NativeMethods.git_diff_tree_to_tree(out diff, repo, osw1.ObjectPtr, osw2.ObjectPtr, options); Ensure.Success(res); return diff; @@ -563,12 +573,13 @@ public static DiffListSafeHandle git_diff_tree_to_tree( public static DiffListSafeHandle git_diff_workdir_to_index( RepositorySafeHandle repo, + IndexSafeHandle index, GitDiffOptions options) { using (ThreadAffinity()) { DiffListSafeHandle diff; - int res = NativeMethods.git_diff_workdir_to_index(repo, options, out diff); + int res = NativeMethods.git_diff_workdir_to_index(out diff, repo, index, options); Ensure.Success(res); return diff; @@ -577,14 +588,14 @@ public static DiffListSafeHandle git_diff_workdir_to_index( public static DiffListSafeHandle git_diff_workdir_to_tree( RepositorySafeHandle repo, - GitDiffOptions options, - ObjectId oldTree) + ObjectId oldTree, + GitDiffOptions options) { using (ThreadAffinity()) using (var osw = new ObjectSafeWrapper(oldTree, repo)) { DiffListSafeHandle diff; - int res = NativeMethods.git_diff_workdir_to_tree(repo, options, osw.ObjectPtr, out diff); + int res = NativeMethods.git_diff_workdir_to_tree(out diff, repo, osw.ObjectPtr, options); Ensure.Success(res); return diff; @@ -1572,9 +1583,9 @@ public static ObjectId git_tag_target_oid(GitObjectSafeHandle tag) return NativeMethods.git_tag_target_oid(tag).MarshalAsObjectId(); } - public static GitObjectType git_tag_type(GitObjectSafeHandle tag) + public static GitObjectType git_tag_target_type(GitObjectSafeHandle tag) { - return NativeMethods.git_tag_type(tag); + return NativeMethods.git_tag_target_type(tag); } #endregion diff --git a/LibGit2Sharp/Diff.cs b/LibGit2Sharp/Diff.cs index 0e8b4742f..748fc13f2 100644 --- a/LibGit2Sharp/Diff.cs +++ b/LibGit2Sharp/Diff.cs @@ -82,7 +82,7 @@ public virtual TreeChanges Compare(Tree oldTree, Tree newTree, IEnumerable @@ -151,12 +151,12 @@ public virtual TreeChanges Compare(IEnumerable paths = null) private static TreeComparisonHandleRetriever WorkdirToIndex(Repository repo) { - return (h, o) => Proxy.git_diff_workdir_to_index(repo.Handle, o); + return (h, o) => Proxy.git_diff_workdir_to_index(repo.Handle, repo.Index.Handle, o); } private static TreeComparisonHandleRetriever WorkdirToTree(Repository repo) { - return (h, o) => Proxy.git_diff_workdir_to_tree(repo.Handle, o, h); + return (h, o) => Proxy.git_diff_workdir_to_tree(repo.Handle, h, o); } private static TreeComparisonHandleRetriever WorkdirAndIndexToTree(Repository repo) @@ -167,8 +167,8 @@ private static TreeComparisonHandleRetriever WorkdirAndIndexToTree(Repository re try { - diff = Proxy.git_diff_index_to_tree(repo.Handle, o, h); - diff2 = Proxy.git_diff_workdir_to_index(repo.Handle, o); + diff = Proxy.git_diff_index_to_tree(repo.Handle, repo.Index.Handle, h, o); + diff2 = Proxy.git_diff_workdir_to_index(repo.Handle, repo.Index.Handle, o); Proxy.git_diff_merge(diff, diff2); } catch @@ -189,7 +189,7 @@ private static TreeComparisonHandleRetriever WorkdirAndIndexToTree(Repository re private static TreeComparisonHandleRetriever IndexToTree(Repository repo) { - return (h, o) => Proxy.git_diff_index_to_tree(repo.Handle, o, h); + return (h, o) => Proxy.git_diff_index_to_tree(repo.Handle, repo.Index.Handle, h, o); } private static DiffListSafeHandle BuildDiffListFromTreeAndComparer(ObjectId treeId, TreeComparisonHandleRetriever comparisonHandleRetriever, GitDiffOptions options) diff --git a/LibGit2Sharp/Index.cs b/LibGit2Sharp/Index.cs index 8a9f8d4dd..bdfd06642 100644 --- a/LibGit2Sharp/Index.cs +++ b/LibGit2Sharp/Index.cs @@ -338,6 +338,19 @@ public virtual void Remove(IEnumerable paths) UpdatePhysicalIndex(); } + /// + /// Clean the working tree by removing files that are not under version control. + /// + public virtual void CleanWorkingDirectory() + { + GitCheckoutOpts options = new GitCheckoutOpts + { + checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_REMOVE_UNTRACKED | CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS + }; + + Proxy.git_checkout_index(this.repo.Handle, this.repo.Index.Handle, options); + } + private IEnumerable> PrepareBatch(IEnumerable paths) { Ensure.ArgumentNotNull(paths, "paths"); diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 7fabcd11f..19b1c39a5 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -422,7 +422,7 @@ public static Repository Clone(string sourceUrl, string workdirPath, { nativeOpts = new GitCheckoutOpts { - checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_CREATE_MISSING, + checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_SAFE, ProgressCb = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress), }; } @@ -534,8 +534,7 @@ private void CheckoutHeadForce(CheckoutProgressHandler onCheckoutProgress) { GitCheckoutOpts options = new GitCheckoutOpts { - checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_CREATE_MISSING | - CheckoutStrategy.GIT_CHECKOUT_OVERWRITE_MODIFIED | + checkout_strategy = CheckoutStrategy.GIT_CHECKOUT_FORCE | CheckoutStrategy.GIT_CHECKOUT_REMOVE_UNTRACKED, ProgressCb = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress) }; diff --git a/LibGit2Sharp/TagAnnotation.cs b/LibGit2Sharp/TagAnnotation.cs index 196b79147..9f1a9f781 100644 --- a/LibGit2Sharp/TagAnnotation.cs +++ b/LibGit2Sharp/TagAnnotation.cs @@ -24,7 +24,7 @@ internal TagAnnotation(Repository repo, ObjectId id) { lazyName = GitObjectLazyGroup.Singleton(repo, id, Proxy.git_tag_name); lazyTarget = GitObjectLazyGroup.Singleton(repo, id, - obj => GitObject.BuildFrom(repo, Proxy.git_tag_target_oid(obj), Proxy.git_tag_type(obj), null)); + obj => GitObject.BuildFrom(repo, Proxy.git_tag_target_oid(obj), Proxy.git_tag_target_type(obj), null)); group = new GitObjectLazyGroup(repo, id); lazyTagger = group.AddLazy(Proxy.git_tag_tagger); diff --git a/LibGit2Sharp/libgit2_hash.txt b/LibGit2Sharp/libgit2_hash.txt index 7153295e3..26d87c25d 100644 --- a/LibGit2Sharp/libgit2_hash.txt +++ b/LibGit2Sharp/libgit2_hash.txt @@ -1 +1 @@ -1e99ce9ac7d7a73f629327d020034e4b2ed1374c +54be4d57ed3cfbfb8c970f04422f840bcb731ddd diff --git a/libgit2 b/libgit2 index 1e99ce9ac..54be4d57e 160000 --- a/libgit2 +++ b/libgit2 @@ -1 +1 @@ -Subproject commit 1e99ce9ac7d7a73f629327d020034e4b2ed1374c +Subproject commit 54be4d57ed3cfbfb8c970f04422f840bcb731ddd