diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index 55282e10d..eadbffec5 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -295,6 +295,24 @@ public void ConflictingMergeReposBinary() } } + [Fact] + public void CanFailOnFirstMergeConflict() + { + string path = SandboxMergeTestRepo(); + using (var repo = new Repository(path)) + { + var mergeResult = repo.Merge("conflicts", Constants.Signature, new MergeOptions() { FailOnConflict = true, }); + Assert.Equal(MergeStatus.Conflicts, mergeResult.Status); + + var master = repo.Branches["master"]; + var branch = repo.Branches["conflicts"]; + var mergeTreeResult = repo.ObjectDatabase.MergeCommits(master.Tip, branch.Tip, new MergeTreeOptions() { FailOnConflict = true }); + Assert.Equal(MergeTreeStatus.Conflicts, mergeTreeResult.Status); + Assert.Empty(mergeTreeResult.Conflicts); + } + + } + [Theory] [InlineData(true, FastForwardStrategy.Default, fastForwardBranchInitialId, MergeStatus.FastForward)] [InlineData(true, FastForwardStrategy.FastForwardOnly, fastForwardBranchInitialId, MergeStatus.FastForward)] diff --git a/LibGit2Sharp/Core/GitDiff.cs b/LibGit2Sharp/Core/GitDiff.cs index 4d1e9768f..8236a5b85 100644 --- a/LibGit2Sharp/Core/GitDiff.cs +++ b/LibGit2Sharp/Core/GitDiff.cs @@ -197,6 +197,12 @@ internal delegate int diff_notify_cb( IntPtr matched_pathspec, IntPtr payload); + internal delegate int diff_progress_cb( + IntPtr diff_so_far, + IntPtr old_path, + IntPtr new_path, + IntPtr payload); + [StructLayout(LayoutKind.Sequential)] internal class GitDiffOptions : IDisposable { @@ -208,7 +214,8 @@ internal class GitDiffOptions : IDisposable public SubmoduleIgnore IgnoreSubmodules; public GitStrArrayManaged PathSpec; public diff_notify_cb NotifyCallback; - public IntPtr NotifyPayload; + public diff_progress_cb ProgressCallback; + public IntPtr Payload; /* options controlling how to diff text is generated */ diff --git a/LibGit2Sharp/Core/GitMergeOpts.cs b/LibGit2Sharp/Core/GitMergeOpts.cs index 90e5a3ee7..59a9040df 100644 --- a/LibGit2Sharp/Core/GitMergeOpts.cs +++ b/LibGit2Sharp/Core/GitMergeOpts.cs @@ -8,7 +8,7 @@ internal struct GitMergeOpts { public uint Version; - public GitMergeTreeFlags MergeTreeFlags; + public GitMergeFlag MergeTreeFlags; /// /// Similarity to consider a file renamed. @@ -27,6 +27,14 @@ internal struct GitMergeOpts /// public IntPtr SimilarityMetric; + /// + /// Maximum number of times to merge common ancestors to build a + /// virtual merge base when faced with criss-cross merges. When this + /// limit is reached, the next ancestor will simply be used instead of + /// attempting to merge it. The default is unlimited. + /// + public uint RecursionLimit; + /// /// Flags for automerging content. /// @@ -35,7 +43,7 @@ internal struct GitMergeOpts /// /// File merging flags. /// - public GitMergeFileFlags FileFlags; + public GitMergeFileFlag FileFlags; } /// @@ -98,30 +106,43 @@ internal enum GitMergePreference } [Flags] - internal enum GitMergeTreeFlags + internal enum GitMergeFlag { /// /// No options. /// - GIT_MERGE_TREE_NORMAL = 0, + GIT_MERGE_NORMAL = 0, /// /// Detect renames that occur between the common ancestor and the "ours" /// side or the common ancestor and the "theirs" side. This will enable /// the ability to merge between a modified and renamed file. /// - GIT_MERGE_TREE_FIND_RENAMES = (1 << 0), + GIT_MERGE_FIND_RENAMES = (1 << 0), /// /// If a conflict occurs, exit immediately instead of attempting to /// continue resolving conflicts. The merge operation will fail with /// GIT_EMERGECONFLICT and no index will be returned. /// - GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1), + GIT_MERGE_FAIL_ON_CONFLICT = (1 << 1), + + /// + /// Do not write the REUC extension on the generated index + /// + GIT_MERGE_SKIP_REUC = (1 << 2), + + /// + /// If the commits being merged have multiple merge bases, do not build + /// a recursive merge base (by merging the multiple merge bases), + /// instead simply use the first base. This flag provides a similar + /// merge base to `git-merge-resolve`. + /// + GIT_MERGE_NO_RECURSIVE = (1 << 3), } [Flags] - internal enum GitMergeFileFlags + internal enum GitMergeFileFlag { /// /// Defaults diff --git a/LibGit2Sharp/Core/Proxy.cs b/LibGit2Sharp/Core/Proxy.cs index dec711d24..ad74ad6db 100644 --- a/LibGit2Sharp/Core/Proxy.cs +++ b/LibGit2Sharp/Core/Proxy.cs @@ -1101,11 +1101,19 @@ public static void git_index_clear(Index index) #region git_merge_ - public static IndexSafeHandle git_merge_commits(RepositorySafeHandle repo, GitObjectSafeHandle ourCommit, GitObjectSafeHandle theirCommit, GitMergeOpts opts) + public static IndexSafeHandle git_merge_commits(RepositorySafeHandle repo, GitObjectSafeHandle ourCommit, GitObjectSafeHandle theirCommit, GitMergeOpts opts, out bool earlyStop) { IndexSafeHandle index; int res = NativeMethods.git_merge_commits(out index, repo, ourCommit, theirCommit, ref opts); - Ensure.ZeroResult(res); + if (res == (int)GitErrorCode.MergeConflict) + { + earlyStop = true; + } + else + { + earlyStop = false; + Ensure.ZeroResult(res); + } return index; } @@ -1189,7 +1197,7 @@ public static ObjectId git_annotated_commit_id(GitAnnotatedCommitHandle mergeHea return NativeMethods.git_annotated_commit_id(mergeHead).MarshalAsObjectId(); } - public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle[] heads, GitMergeOpts mergeOptions, GitCheckoutOpts checkoutOptions) + public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle[] heads, GitMergeOpts mergeOptions, GitCheckoutOpts checkoutOptions, out bool earlyStop) { IntPtr[] their_heads = heads.Select(head => head.DangerousGetHandle()).ToArray(); @@ -1199,7 +1207,15 @@ public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle ref mergeOptions, ref checkoutOptions); - Ensure.ZeroResult(res); + if (res == (int)GitErrorCode.MergeConflict) + { + earlyStop = true; + } + else + { + earlyStop = false; + Ensure.ZeroResult(res); + } } public static void git_merge_analysis( diff --git a/LibGit2Sharp/CurrentOperation.cs b/LibGit2Sharp/CurrentOperation.cs index 58f7064ae..9050e8235 100644 --- a/LibGit2Sharp/CurrentOperation.cs +++ b/LibGit2Sharp/CurrentOperation.cs @@ -21,39 +21,49 @@ public enum CurrentOperation /// Revert = 2, + /// + /// A sequencer revert is in progress. + /// + RevertSequence = 3, + /// /// A cherry-pick is in progress. /// - CherryPick = 3, + CherryPick = 4, + + /// + /// A sequencer cherry-pick is in progress. + /// + CherryPickSequence = 5, /// /// A bisect is in progress. /// - Bisect = 4, + Bisect = 6, /// /// A rebase is in progress. /// - Rebase = 5, + Rebase = 7, /// /// A rebase --interactive is in progress. /// - RebaseInteractive = 6, + RebaseInteractive = 8, /// /// A rebase --merge is in progress. /// - RebaseMerge = 7, + RebaseMerge = 9, /// /// A mailbox application (am) is in progress. /// - ApplyMailbox = 8, + ApplyMailbox = 10, /// /// A mailbox application (am) or rebase is in progress. /// - ApplyMailboxOrRebase = 9, + ApplyMailboxOrRebase = 11, } } diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index c2fc74e2e..34c4d3c75 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -1,6 +1,6 @@  - + Debug AnyCPU @@ -405,7 +405,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}. - +