diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs index dc0b85600..8c480d8af 100644 --- a/LibGit2Sharp.Tests/MergeFixture.cs +++ b/LibGit2Sharp.Tests/MergeFixture.cs @@ -572,6 +572,32 @@ public void CanMergeCommittish(string committish, FastForwardStrategy strategy, } } + [Theory] + [InlineData(true, FastForwardStrategy.FastForwardOnly)] + [InlineData(false, FastForwardStrategy.FastForwardOnly)] + [InlineData(true, FastForwardStrategy.NoFastFoward)] + [InlineData(false, FastForwardStrategy.NoFastFoward)] + public void MergeWithWorkDirConflictsThrows(bool shouldStage, FastForwardStrategy strategy) + { + // Merging the fast_forward branch results in a change to file + // b.txt. In this test we modify the file in the working directory + // and then attempt to perform a merge. We expect the merge to fail + // due to merge conflicts. + string committishToMerge = "fast_forward"; + + using (var repo = new Repository(CloneMergeTestRepo())) + { + Touch(repo.Info.WorkingDirectory, "b.txt", "this is an alternate change"); + + if (shouldStage) + { + repo.Index.Stage("b.txt"); + } + + Assert.Throws(() => repo.Merge(committishToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy })); + } + } + [Theory] [InlineData(CheckoutFileConflictStrategy.Ours)] [InlineData(CheckoutFileConflictStrategy.Theirs)] diff --git a/LibGit2Sharp/CherryPickOptions.cs b/LibGit2Sharp/CherryPickOptions.cs index ccb8b0b4f..0f27de211 100644 --- a/LibGit2Sharp/CherryPickOptions.cs +++ b/LibGit2Sharp/CherryPickOptions.cs @@ -104,7 +104,6 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy get { return CheckoutStrategy.GIT_CHECKOUT_SAFE | - CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS | GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy); } } diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs index 29d6aa370..dfedca458 100644 --- a/LibGit2Sharp/Core/GitCheckoutOpts.cs +++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs @@ -160,4 +160,50 @@ internal interface IConvertableToGitCheckoutOpts CheckoutNotifyFlags CheckoutNotifyFlags { get; } } + + /// + /// This wraps an IConvertableToGitCheckoutOpts object and can tweak the + /// properties so that they are appropriate for a checkout performed as + /// part of a FastForward merge. Most properties are passthrough to the + /// wrapped object. + /// + internal class FastForwardCheckoutOptionsAdapter : IConvertableToGitCheckoutOpts + { + private IConvertableToGitCheckoutOpts internalOptions; + + internal FastForwardCheckoutOptionsAdapter(IConvertableToGitCheckoutOpts internalOptions) + { + this.internalOptions = internalOptions; + } + + /// + /// Passthrough to the wrapped object. + /// + /// + public CheckoutCallbacks GenerateCallbacks() + { + return internalOptions.GenerateCallbacks(); + } + + /// + /// There should be no resolvable conflicts in a FastForward merge. + /// Just perform checkout with the safe checkout strategy. + /// + public CheckoutStrategy CheckoutStrategy + { + get + { + return CheckoutStrategy.GIT_CHECKOUT_SAFE; + } + } + + /// + /// Passthrough to the wrapped object. + /// + /// + public CheckoutNotifyFlags CheckoutNotifyFlags + { + get { return internalOptions.CheckoutNotifyFlags; } + } + } } diff --git a/LibGit2Sharp/MergeOptions.cs b/LibGit2Sharp/MergeOptions.cs index 881ffb8f5..b88cd0ca3 100644 --- a/LibGit2Sharp/MergeOptions.cs +++ b/LibGit2Sharp/MergeOptions.cs @@ -95,8 +95,7 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy { get { - return CheckoutStrategy.GIT_CHECKOUT_SAFE| - CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS | + return CheckoutStrategy.GIT_CHECKOUT_SAFE | GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy); } } diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index 54791a8ed..1c583c528 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1351,7 +1351,7 @@ private MergeResult FastForwardMerge(GitMergeHeadHandle mergeHead, Signature mer Commit fastForwardCommit = (Commit) Lookup(id, ObjectType.Commit); Ensure.GitObjectIsNotNull(fastForwardCommit, id.Sha); - CheckoutTree(fastForwardCommit.Tree, null, options); + CheckoutTree(fastForwardCommit.Tree, null, new FastForwardCheckoutOptionsAdapter(options)); var reference = Refs.Head.ResolveToDirectReference(); diff --git a/LibGit2Sharp/RevertOptions.cs b/LibGit2Sharp/RevertOptions.cs index 49a350e58..9b1113610 100644 --- a/LibGit2Sharp/RevertOptions.cs +++ b/LibGit2Sharp/RevertOptions.cs @@ -104,7 +104,6 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy get { return CheckoutStrategy.GIT_CHECKOUT_SAFE | - CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS | GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy); } }