8000 Don't throw on merge conflict · leoniDEV/libgit2sharp@6d14e31 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6d14e31

Browse files
committed
Don't throw on merge conflict
Instead of throwing an exception, return the merge error in the normal way, as this early failure was requested by the user and thus not an exceptional circunstance.
1 parent 575df91 commit 6d14e31

File tree

8 files changed

+58
-78
lines changed

8 files changed

+58
-78
lines changed

LibGit2Sharp.Tests/MergeFixture.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,14 @@ public void CanFailOnFirstMergeConflict()
301301
string path = SandboxMergeTestRepo();
302302
using (var repo = new Repository(path))
303303
{
304-
var master = repo.Lookup<Commit>("master");
305-
var branch = repo.Lookup<Commit>("conflicts");
304+
var mergeResult = repo.Merge("conflicts", Constants.Signature, new MergeOptions() { FailOnConflict = true, });
305+
Assert.Equal(MergeStatus.Conflicts, mergeResult.Status);
306306

307-
Assert.Throws<ConflictInMergeException>(() =>
308-
{
309-
repo.Merge("conflicts", Constants.Signature, new MergeOptions() { FailOnConflict = true, });
310-
});
307+
var master = repo.Branches["master"];
308+
var branch = repo.Branches["conflicts"];
309+
var mergeTreeResult = repo.ObjectDatabase.MergeCommits(master.Tip, branch.Tip, new MergeTreeOptions() { FailOnConflict = true });
310+
Assert.Equal(MergeTreeStatus.Conflicts, mergeTreeResult.Status);
311+
Assert.Empty(mergeTreeResult.Conflicts);
311312
}
312313

313314
}

LibGit2Sharp/ConflictInMergeException.cs

Lines changed: 0 additions & 59 deletions
This file was deleted.

LibGit2Sharp/Core/Ensure.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ private static readonly Dictionary<GitErrorCode, Func<string, GitErrorCode, GitE
125125
{ GitErrorCode.UnmergedEntries, (m, r, c) => new UnmergedIndexEntriesException(m, r, c) },
126126
{ GitErrorCode.NonFastForward, (m, r, c) => new NonFastForwardException(m, r, c) },
127127
{ GitErrorCode.Conflict, (m, r, c) => new CheckoutConflictException(m, r, c) },
128-
{ GitErrorCode.MergeConflict, (m ,r, c) => new ConflictInMergeException(m, r, c) },
129128
{ GitErrorCode.LockedFile, (m, r, c) => new LockedFileException(m, r, c) },
130129
{ GitErrorCode.NotFound, (m, r, c) => new NotFoundException(m, r, c) },
131130
{ GitErrorCode.Peel, (m, r, c) => new PeelException(m, r, c) },

LibGit2Sharp/Core/Proxy.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,11 +1101,19 @@ public static void git_index_clear(Index index)
11011101

11021102
#region git_merge_
11031103

1104-
public static IndexSafeHandle git_merge_commits(RepositorySafeHandle repo, GitObjectSafeHandle ourCommit, GitObjectSafeHandle theirCommit, GitMergeOpts opts)
1104+
public static IndexSafeHandle git_merge_commits(RepositorySafeHandle repo, GitObjectSafeHandle ourCommit, GitObjectSafeHandle theirCommit, GitMergeOpts opts, out bool earlyStop)
11051105
{
11061106
IndexSafeHandle index;
11071107
int res = NativeMethods.git_merge_commits(out index, repo, ourCommit, theirCommit, ref opts);
1108-
Ensure.ZeroResult(res);
1108+
if (res == (int)GitErrorCode.MergeConflict)
1109+
{
1110+
earlyStop = true;
1111+
}
1112+
else
1113+
{
1114+
earlyStop = false;
1115+
Ensure.ZeroResult(res);
1116+
}
11091117

11101118
return index;
11111119
}
@@ -1189,7 +1197,7 @@ public static ObjectId git_annotated_commit_id(GitAnnotatedCommitHandle mergeHea
11891197
return NativeMethods.git_annotated_commit_id(mergeHead).MarshalAsObjectId();
11901198
}
11911199

1192-
public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle[] heads, GitMergeOpts mergeOptions, GitCheckoutOpts checkoutOptions)
1200+
public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle[] heads, GitMergeOpts mergeOptions, GitCheckoutOpts checkoutOptions, out bool earlyStop)
11931201
{
11941202
IntPtr[] their_heads = heads.Select(head => head.DangerousGetHandle()).ToArray();
11951203

@@ -1199,7 +1207,15 @@ public static void git_merge(RepositorySafeHandle repo, GitAnnotatedCommitHandle
11991207
ref mergeOptions,
12001208
ref checkoutOptions);
12011209

1202-
Ensure.ZeroResult(res);
1210+
if (res == (int)GitErrorCode.MergeConflict)
1211+
{
1212+
earlyStop = true;
1213+
}
1214+
else
1215+
{
1216+
earlyStop = false;
1217+
Ensure.ZeroResult(res);
1218+
}
12031219
}
12041220

12051221
public static void git_merge_analysis(

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
<Compile Include="CommitOptions.cs" />
7070
<Compile Include="CommitSortStrategies.cs" />
7171
<Compile Include="CompareOptions.cs" />
72-
<Compile Include="ConflictInMergeException.cs" />
7372
<Compile Include="Core\FileHistory.cs" />
7473
<Compile Include="Core\GitFetchOptions.cs" />
7574
<Compile Include="Core\GitPushUpdate.cs" />

LibGit2Sharp/MergeOptionsBase.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ protected MergeOptionsBase()
2323
public bool FindRenames { get; set; }
2424

2525
/// <summary>
26-
/// If set, do not create conflict entries but fail the operation. No
27-
/// merged index will be created and a <see cref="LibGit2Sharp.ConflictInMergeException"/>
28-
/// exception will be thrown.
26+
/// If set, do not create or return conflict entries, but stop and return
27+
/// an error result after finding the first conflict.
2928
/// </summary>
3029
public bool FailOnConflict { get; set; }
3130

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,22 +603,41 @@ public virtual MergeTreeResult MergeCommits(Commit ours, Commit theirs, MergeTre
603603

604604
options = options ?? new MergeTreeOptions();
605605

606+
// We throw away the index after looking at the conflicts, so we'll never need the REUC
607+
// entries to be there
608+
GitMergeFlag mergeFlags = GitMergeFlag.GIT_MERGE_NORMAL | GitMergeFlag.GIT_MERGE_SKIP_REUC;
609+
if (options.FindRenames)
610+
{
611+
mergeFlags |= GitMergeFlag.GIT_MERGE_FIND_RENAMES;
612+
}
613+
if (options.FailOnConflict)
614+
{
615+
mergeFlags |= GitMergeFlag.GIT_MERGE_FAIL_ON_CONFLICT;
616+
}
617+
618+
606619
var mergeOptions = new GitMergeOpts
607620
{
608621
Version = 1,
609622
MergeFileFavorFlags = options.MergeFileFavor,
610-
MergeTreeFlags = options.FindRenames ? GitMergeFlag.GIT_MERGE_FIND_RENAMES
611-
: GitMergeFlag.GIT_MERGE_NORMAL,
623+
MergeTreeFlags = mergeFlags,
612624
RenameThreshold = (uint)options.RenameThreshold,
613625
TargetLimit = (uint)options.TargetLimit,
614626
};
615627

628+
bool earlyStop;
616629
using (var oneHandle = Proxy.git_object_lookup(repo.Handle, ours.Id, GitObjectType.Commit))
617630
using (var twoHandle = Proxy.git_object_lookup(repo.Handle, theirs.Id, GitObjectType.Commit))
618-
using (var indexHandle = Proxy.git_merge_commits(repo.Handle, oneHandle, twoHandle, mergeOptions))
631+
using (var indexHandle = Proxy.git_merge_commits(repo.Handle, oneHandle, twoHandle, mergeOptions, out earlyStop))
619632
{
620633
MergeTreeResult mergeResult;
621634

635+
// Stopped due to FailOnConflict so there's no index or conflict list
636+
if (earlyStop)
637+
{
638+
return new MergeTreeResult(new Conflict[] { });
639+
}
640+
622641
if (Proxy.git_index_has_conflicts(indexHandle))
623642
{
624643
List<Conflict> conflicts = new List<Conflict>();

LibGit2Sharp/Repository.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1575,11 +1575,17 @@ private MergeResult NormalMerge(GitAnnotatedCommitHandle[] annotatedCommits, Sig
15751575
TargetLimit = (uint)options.TargetLimit,
15761576
};
15771577

1578+
bool earlyStop;
15781579
using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
15791580
{
15801581
var checkoutOpts = checkoutOptionsWrapper.Options;
15811582

1582-
Proxy.git_merge(Handle, annotatedCommits, mergeOptions, checkoutOpts);
1583+
Proxy.git_merge(Handle, annotatedCommits, mergeOptions, checkoutOpts, out earlyStop);
1584+
}
1585+
1586+
if (earlyStop)
1587+
{
1588+
return new MergeResult(MergeStatus.Conflicts);
15831589
}
15841590

15851591
if (Index.IsFullyMerged)

0 commit comments

Comments
 (0)
0