Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf6a3c5

Browse files
author
Edward Thomson
committed
Merge pull request libgit2#1237 from libgit2/cmn/lg2-update
Update to libgit2 6aa06b6
2 parents 92eaebc + 4c605af commit cf6a3c5

File tree

10 files changed

+161
-33
lines changed

10 files changed

+161
-33
lines changed

LibGit2Sharp.Tests/MergeFixture.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,24 @@ public void ConflictingMergeReposBinary()
295295
}
296296
}
297297

298+
[Fact]
299+
public void CanFailOnFirstMergeConflict()
300+
{
301+
string path = SandboxMergeTestRepo();
302+
using (var repo = new Repository(path))
303+
{
304+
var mergeResult = repo.Merge("conflicts", Constants.Signature, new MergeOptions() { FailOnConflict = true, });
305+
Assert.Equal(MergeStatus.Conflicts, mergeResult.Status);
306+
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);
312+
}
313+
314+
}
315+
298316
[Theory]
299317
[InlineData(true, FastForwardStrategy.Default, fastForwardBranchInitialId, MergeStatus.FastForward)]
300318
[InlineData(true, FastForwardStrategy.FastForwardOnly, fastForwardBranchInitialId, MergeStatus.FastForward)]

LibGit2Sharp/Core/GitDiff.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,12 @@ internal delegate int diff_notify_cb(
197197
IntPtr matched_pathspec,
198198
IntPtr payload);
199199

200+
internal delegate int diff_progress_cb(
201+
IntPtr diff_so_far,
202+
IntPtr old_path,
203+
IntPtr new_path,
204+
IntPtr payload);
205+
200206
[StructLayout(LayoutKind.Sequential)]
201207
internal class GitDiffOptions : IDisposable
202208
{
@@ -208,7 +214,8 @@ internal class GitDiffOptions : IDisposable
208214
public SubmoduleIgnore IgnoreSubmodules;
209215
public GitStrArrayManaged PathSpec;
210216
public diff_notify_cb NotifyCallback;
211-
public IntPtr NotifyPayload;
217+
public diff_progress_cb ProgressCallback;
218+
public IntPtr Payload;
212219

213220
/* options controlling how to diff text is generated */
214221

LibGit2Sharp/Core/GitMergeOpts.cs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ internal struct GitMergeOpts
88
{
99
public uint Version;
1010

11-
public GitMergeTreeFlags MergeTreeFlags;
11+
public GitMergeFlag MergeTreeFlags;
1212

1313
/// <summary>
1414
/// Similarity to consider a file renamed.
@@ -27,6 +27,14 @@ internal struct GitMergeOpts
2727
/// </summary>
2828
public IntPtr SimilarityMetric;
2929

30+
/// <summary>
31+
/// Maximum number of times to merge common ancestors to build a
32+
/// virtual merge base when faced with criss-cross merges. When this
33+
/// limit is reached, the next ancestor will simply be used instead of
34+
/// attempting to merge it. The default is unlimited.
35+
/// </summary>
36+
public uint RecursionLimit;
37+
3038
/// <summary>
3139
/// Flags for automerging content.
3240
/// </summary>
@@ -35,7 +43,7 @@ internal struct GitMergeOpts
3543
/// <summary>
3644
/// File merging flags.
3745
/// </summary>
38-
public GitMergeFileFlags FileFlags;
46+
public GitMergeFileFlag FileFlags;
3947
}
4048

4149
/// <summary>
@@ -98,30 +106,43 @@ internal enum GitMergePreference
98106
}
99107

100108
[Flags]
101-
internal enum GitMergeTreeFlags
109+
internal enum GitMergeFlag
102110
{
103111
/// <summary>
104112
/// No options.
105113
/// </summary>
106-
GIT_MERGE_TREE_NORMAL = 0,
114+
GIT_MERGE_NORMAL = 0,
107115

108116
/// <summary>
109117
/// Detect renames that occur between the common ancestor and the "ours"
110118
/// side or the common ancestor and the "theirs" side. This will enable
111119
/// the ability to merge between a modified and renamed file.
112120
/// </summary>
113-
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
121+
GIT_MERGE_FIND_RENAMES = (1 << 0),
114122

115123
/// <summary>
116124
/// If a conflict occurs, exit immediately instead of attempting to
117125
/// continue resolving conflicts. The merge operation will fail with
118126
/// GIT_EMERGECONFLICT and no index will be returned.
119127
///</summary>
120-
GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1),
128+
GIT_MERGE_FAIL_ON_CONFLICT = (1 << 1),
129+
130+
/// <summary>
131+
/// Do not write the REUC extension on the generated index
132+
/// </summary>
133+
GIT_MERGE_SKIP_REUC = (1 << 2),
134+
135+
/// <summary>
136+
/// If the commits being merged have multiple merge bases, do not build
137+
/// a recursive merge base (by merging the multiple merge bases),
138+
/// instead simply use the first base. This flag provides a similar
139+
/// merge base to `git-merge-resolve`.
140+
/// </summary>
141+
GIT_MERGE_NO_RECURSIVE = (1 << 3),
121142
}
122143

123144
[Flags]
124-
internal enum GitMergeFileFlags
145+
internal enum GitMergeFileFlag
125146
{
126147
/// <summary>
127148
/// Defaults

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/CurrentOperation.cs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,39 +21,49 @@ public enum CurrentOperation
2121
/// </summary>
2222
Revert = 2,
2323

24+
/// <summary>
25+
/// A sequencer revert is in progress.
26+
/// </summary>
27+
RevertSequence = 3,
28+
2429
/// <summary>
2530
/// A cherry-pick is in progress.
2631
/// </summary>
27-
CherryPick = 3,
32+
CherryPick = 4,
33+
34+
/// <summary>
35+
/// A sequencer cherry-pick is in progress.
36+
/// </summary>
37+
CherryPickSequence = 5,
2838

2939
/// <summary>
3040
/// A bisect is in progress.
3141
/// </summary>
32-
Bisect = 4,
42+
Bisect = 6,
3343

3444
/// <summary>
3545
/// A rebase is in progress.
3646
/// </summary>
37-
Rebase = 5,
47+
Rebase = 7,
3848

3949
/// <summary>
4050
/// A rebase --interactive is in progress.
4151
/// </summary>
42-
RebaseInteractive = 6,
52+
RebaseInteractive = 8,
4353

4454
/// <summary>
4555
/// A rebase --merge is in progress.
4656
/// </summary>
47-
RebaseMerge = 7,
57+
RebaseMerge = 9,
4858

4959
/// <summary>
5060
/// A mailbox application (am) is in progress.
5161
/// </summary>
52-
ApplyMailbox = 8,
62+
ApplyMailbox = 10,
5363

5464
/// <summary>
5565
/// A mailbox application (am) or rebase is in progress.
5666
/// </summary>
57-
ApplyMailboxOrRebase = 9,
67+
ApplyMailboxOrRebase = 11,
5868
}
5969
}

LibGit2Sharp/LibGit2Sharp.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3-
<Import Project="..\packages\LibGit2Sharp.NativeBinaries.1.0.106\build\LibGit2Sharp.NativeBinaries.props" Condition="Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.106\build\LibGit2Sharp.NativeBinaries.props')" />
3+
<Import Project="..\packages\LibGit2Sharp.NativeBinaries.1.0.119\build\LibGit2Sharp.NativeBinaries.props" Condition="Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.119\build\LibGit2Sharp.NativeBinaries.props')" />
44
<PropertyGroup>
55
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
66
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -405,7 +405,7 @@
405405
<PropertyGroup>
406406
<ErrorText>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}.</ErrorText>
407407
</PropertyGroup>
408-
<Error Condition="!Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.106\build\LibGit2Sharp.NativeBinaries.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\LibGit2Sharp.NativeBinaries.1.0.106\build\LibGit2Sharp.NativeBinaries.props'))" />
408+
<Error Condition="!Exists('..\packages\LibGit2Sharp.NativeBinaries.1.0.119\build\LibGit2Sharp.NativeBinaries.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\LibGit2Sharp.NativeBinaries.1.0.119\build\LibGit2Sharp.NativeBinaries.props'))" />
409409
</Target>
410410
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
411411
Other similar extension points exist, see Microsoft.Common.targets.

LibGit2Sharp/MergeOptionsBase.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ protected MergeOptionsBase()
2222
/// </summary>
2323
public bool FindRenames { get; set; }
2424

25+
/// <summary>
26+
/// If set, do not create or return conflict entries, but stop and return
27+
/// an error result after finding the first conflict.
28+
/// </summary>
29+
public bool FailOnConflict { get; set; }
30+
31+
/// <summary>
32+
/// Do not write the Resolve Undo Cache extension on the generated index. This can
33+
/// be useful when no merge resolution will be presented to the user (e.g. a server-side
34+
/// merge attempt).
35+
/// </summary>
36+
public bool SkipReuc { get; set; }
37+
2538
/// <summary>
2639
/// Similarity to consider a file renamed.
2740
/// </summary>

LibGit2Sharp/ObjectDatabase.cs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,13 @@ public virtual bool CanMergeWithoutConflict(Commit one, Commit another)
522522
Ensure.ArgumentNotNull(one, "one");
523523
Ensure.ArgumentNotNull(another, "another");
524524

525-
var result = repo.ObjectDatabase.MergeCommits(one, another, null);
525+
var opts = new MergeTreeOptions()
526+
{
527+
SkipReuc = true,
528+
FailOnConflict = true,
529+
};
530+
531+
var result = repo.ObjectDatabase.MergeCommits(one, another, opts);
526532
return (result.Status == MergeTreeStatus.Succeeded);
527533
}
528534

@@ -603,22 +609,41 @@ public virtual MergeTreeResult MergeCommits(Commit ours, Commit theirs, MergeTre
603609

604610
options = options ?? new MergeTreeOptions();
605611

612+
// We throw away the index after looking at the conflicts, so we'll never need the REUC
613+
// entries to be there
614+
GitMergeFlag mergeFlags = GitMergeFlag.GIT_MERGE_NORMAL | GitMergeFlag.GIT_MERGE_SKIP_REUC;
615+
if (options.FindRenames)
616+
{
617+
mergeFlags |= GitMergeFlag.GIT_MERGE_FIND_RENAMES;
618+
}
619+
if (options.FailOnConflict)
620+
{
621+
mergeFlags |= GitMergeFlag.GIT_MERGE_FAIL_ON_CONFLICT;
622+
}
623+
624+
606625
var mergeOptions = new GitMergeOpts
607626
{
608627
Version = 1,
609628
MergeFileFavorFlags = options.MergeFileFavor,
610-
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES
611-
: GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
629+
MergeTreeFlags = mergeFlags,
612630
RenameThreshold = (uint)options.RenameThreshold,
613631
TargetLimit = (uint)options.TargetLimit,
614632
};
615633

634+
bool earlyStop;
616635
using (var oneHandle = Proxy.git_object_lookup(repo.Handle, ours.Id, GitObjectType.Commit))
617636
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))
637+
using (var indexHandle = Proxy.git_merge_commits(repo.Handle, oneHandle, twoHandle, mergeOptions, out earlyStop))
619638
{
620639
MergeTreeResult mergeResult;
621640

641+
// Stopped due to FailOnConflict so there's no index or conflict list
642+
if (earlyStop)
643+
{
644+
return new MergeTreeResult(new Conflict[] { });
645+
}
646+
622647
if (Proxy.git_index_has_conflicts(indexHandle))
623648
{
624649
List<Conflict> conflicts = new List<Conflict>();

LibGit2Sharp/Repository.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,8 +1329,8 @@ public RevertResult Revert(Commit commit, Signature reverter, RevertOptions opti
13291329
{
13301330
Version = 1,
13311331
MergeFileFavorFlags = options.MergeFileFavor,
1332-
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES :
1333-
GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
1332+
MergeTreeFlags = options.FindRenames ? GitMergeFlag.GIT_MERGE_FIND_RENAMES :
1333+
GitMergeFlag.GIT_MERGE_NORMAL,
13341334
RenameThreshold = (uint)options.RenameThreshold,
13351335
TargetLimit = (uint)options.TargetLimit,
13361336
};
@@ -1413,8 +1413,8 @@ public CherryPickResult CherryPick(Commit commit, Signature committer, CherryPic
14131413
{
14141414
Version = 1,
14151415
MergeFileFavorFlags = options.MergeFileFavor,
1416-
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES :
1417-
GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
1416+
MergeTreeFlags = options.FindRenames ? GitMergeFlag.GIT_MERGE_FIND_RENAMES :
1417+
GitMergeFlag.GIT_MERGE_NORMAL,
14181418
RenameThreshold = (uint)options.RenameThreshold,
14191419
TargetLimit = (uint)options.TargetLimit,
14201420
};
@@ -1553,21 +1553,39 @@ private MergeResult Merge(GitAnnotatedCommitHandle[] annotatedCommits, Signature
15531553
private MergeResult NormalMerge(GitAnnotatedCommitHandle[] annotatedCommits, Signature merger, MergeOptions options)
15541554
{
15551555
MergeResult mergeResult;
1556+
GitMergeFlag treeFlags = options.FindRenames ? GitMergeFlag.GIT_MERGE_FIND_RENAMES
1557+
: GitMergeFlag.GIT_MERGE_NORMAL;
1558+
1559+
if (options.FailOnConflict)
1560+
{
1561+
treeFlags |= GitMergeFlag.GIT_MERGE_FAIL_ON_CONFLICT;
1562+
}
1563+
1564+
if (options.SkipReuc)
1565+
{
1566+
treeFlags |= GitMergeFlag.GIT_MERGE_SKIP_REUC;
1567+
}
1568+
15561569
var mergeOptions = new GitMergeOpts
15571570
{
15581571
Version = 1,
15591572
MergeFileFavorFlags = options.MergeFileFavor,
1560-
MergeTreeFlags = options.FindRenames ? GitMergeTreeFlags.GIT_MERGE_TREE_FIND_RENAMES
1561-
: GitMergeTreeFlags.GIT_MERGE_TREE_NORMAL,
1573+
MergeTreeFlags = treeFlags,
15621574
RenameThreshold = (uint)options.RenameThreshold,
15631575
TargetLimit = (uint)options.TargetLimit,
15641576
};
15651577

1578+
bool earlyStop;
15661579
using (GitCheckoutOptsWrapper checkoutOptionsWrapper = new GitCheckoutOptsWrapper(options))
15671580
{
15681581
var checkoutOpts = checkoutOptionsWrapper.Options;
15691582

1570-
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);
15711589
}
15721590

15731591
if (Index.IsFullyMerged)

0 commit comments

Comments
 (0)