8000 FastForward merge should block if there are checkout conflicts. · apfunk/libgit2sharp@91456eb · GitHub
[go: up one dir, main page]

Skip to content

Commit 91456eb

Browse files
committed
FastForward merge should block if there are checkout conflicts.
Currently, if there are changes in your working directory and a fastforward merge would update those files, the checkout that is performed as part of the fast forward will skip over these files. This change fixes and adds regression tests around this behavior.
1 parent 67be02b commit 91456eb

File tree

6 files changed

+74
-5
lines changed

6 files changed

+74
-5
lines changed

LibGit2Sharp.Tests/MergeFixture.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,32 @@ public void CanMergeCommittish(string committish, FastForwardStrategy strategy,
572572
}
573573
}
574574

575+
[Theory]
576+
[InlineData(true, FastForwardStrategy.FastForwardOnl 8000 y)]
577+
[InlineData(false, FastForwardStrategy.FastForwardOnly)]
578+
[InlineData(true, FastForwardStrategy.NoFastFoward)]
579+
[InlineData(false, FastForwardStrategy.NoFastFoward)]
580+
public void MergeWithWorkDirConflictsThrows(bool shouldStage, FastForwardStrategy strategy)
581+
{
582+
// Merging the fast_forward branch results in a change to file
583+
// b.txt. In this test we modify the file in the working directory
584+
// and then attempt to perform a merge. We expect the merge to fail
585+
// due to merge conflicts.
586+
string committishToMerge = "fast_forward";
587+
588+
using (var repo = new Repository(CloneMergeTestRepo()))
589+
{
590+
Touch(repo.Info.WorkingDirectory, "b.txt", "this is an alternate change");
591+
592+
if (shouldStage)
593+
{
594+
repo.Index.Stage("b.txt");
595+
}
596+
597+
Assert.Throws<MergeConflictException>(() => repo.Merge(committishToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy }));
598+
}
599+
}
600+
575601
[Theory]
576602
[InlineData(CheckoutFileConflictStrategy.Ours)]
577603
[InlineData(CheckoutFileConflictStrategy.Theirs)]

LibGit2Sharp/CherryPickOptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
104104
get
105105
{
106106
return CheckoutStrategy.GIT_CHECKOUT_SAFE |
107-
CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS |
108107
GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy);
109108
}
110109
}

LibGit2Sharp/Core/GitCheckoutOpts.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,50 @@ internal interface IConvertableToGitCheckoutOpts
160160

161161
CheckoutNotifyFlags CheckoutNotifyFlags { get; }
162162
}
163+
164+
/// <summary>
165+
/// This wraps an IConvertableToGitCheckoutOpts object and can tweak the
166+
/// properties so that they are appropriate for a checkout performed as
167+
/// part of a FastForward merge. Most properties are passthrough to the
168+
/// wrapped object.
169+
/// </summary>
170+
internal class FastForwardCheckoutOptionsAdapter : IConvertableToGitCheckoutOpts
171+
{
172+
private IConvertableToGitCheckoutOpts internalOptions;
173+
174+
internal FastForwardCheckoutOptionsAdapter(IConvertableToGitCheckoutOpts internalOptions)
175+
{
176+
this.internalOptions = internalOptions;
177+
}
178+
179+
/// <summary>
180+
/// Passthrough to the wrapped object.
181+
/// </summary>
182+
/// <returns></returns>
183+
public CheckoutCallbacks GenerateCallbacks()
184+
{
185+
return internalOptions.GenerateCallbacks();
186+
}
187+
188+
/// <summary>
189+
/// There should be no resolvable conflicts in a FastForward merge.
190+
/// Just perform checkout with the safe checkout strategy.
191+
/// </summary>
192+
public CheckoutStrategy CheckoutStrategy
193+
{
194+
get
195+
{
196+
return CheckoutStrategy.GIT_CHECKOUT_SAFE;
197+
}
198+
}
199+
200+
/// <summary>
201+
/// Passthrough to the wrapped object.
202+
/// </summary>
203+
/// <returns></returns>
204+
public CheckoutNotifyFlags CheckoutNotifyFlags
205+
{
206+
get { return internalOptions.CheckoutNotifyFlags; }
207+
}
208+
}
163209
}

LibGit2Sharp/MergeOptions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
9595
{
9696
get
9797
{
98-
return CheckoutStrategy.GIT_CHECKOUT_SAFE|
99-
CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS |
98+
return CheckoutStrategy.GIT_CHECKOUT_SAFE |
10099
GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy);
101100
}
102101
}

LibGit2Sharp/Repository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ private MergeResult FastForwardMerge(GitMergeHeadHandle mergeHead, Signature mer
13511351
Commit fastForwardCommit = (Commit) Lookup(id, ObjectType.Commit);
13521352
Ensure.GitObjectIsNotNull(fastForwardCommit, id.Sha);
13531353

1354-
CheckoutTree(fastForwardCommit.Tree, null, options);
1354+
CheckoutTree(fastForwardCommit.Tree, null, new FastForwardCheckoutOptionsAdapter(options));
13551355

13561356
var reference = Refs.Head.ResolveToDirectReference();
13571357

LibGit2Sharp/RevertOptions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ CheckoutStrategy IConvertableToGitCheckoutOpts.CheckoutStrategy
104104
get
105105
{
106106
return CheckoutStrategy.GIT_CHECKOUT_SAFE |
107-
CheckoutStrategy.GIT_CHECKOUT_ALLOW_CONFLICTS |
108107
GitCheckoutOptsWrapper.CheckoutStrategyFromFileConflictStrategy(FileConflictStrategy);
109108
}
110109
}

0 commit comments

Comments
 (0)
0