diff --git a/LibGit2Sharp.Tests/MergeFixture.cs b/LibGit2Sharp.Tests/MergeFixture.cs
index 7b1fda718..484128a25 100644
--- a/LibGit2Sharp.Tests/MergeFixture.cs
+++ b/LibGit2Sharp.Tests/MergeFixture.cs
@@ -669,6 +669,54 @@ public void CanSpecifyConflictFileStrategy(CheckoutFileConflictStrategy conflict
}
}
+ [Theory]
+ [InlineData(CheckoutFileConflictStrategy.Merge)]
+ [InlineData(CheckoutFileConflictStrategy.Diff3)]
+ [InlineData(CheckoutFileConflictStrategy.ZDiff3)]
+ public void CanSpecifyMergeConflictFileStrategy(CheckoutFileConflictStrategy conflictStrategy)
+ {
+ const string conflictFile = "a.txt";
+ const string expectedFileFormat = "a.{0}.txt";
+ const string conflictBranchName = "conflicts";
+ const string resultsBranchName = "results";
+
+ string expectedFileName = string.Format(expectedFileFormat, conflictStrategy.ToString().ToLower());
+ string path = SandboxMergeConflictTestRepo();
+
+ using (var repo = new Repository(path))
+ {
+ Branch branch = repo.Branches[conflictBranchName];
+ Assert.NotNull(branch);
+
+ // Ensure the working directory is clean before merging
+ repo.Reset(ResetMode.Hard);
+ repo.RemoveUntrackedFiles();
+
+ MergeOptions mergeOptions = new MergeOptions()
+ {
+ FileConflictStrategy = conflictStrategy
+ };
+
+ MergeResult result = repo.Merge(branch, Constants.Signature, mergeOptions);
+ Assert.Equal(MergeStatus.Conflicts, result.Status);
+
+ // Get the information on the conflict.
+ Conflict conflict = repo.Index.Conflicts[conflictFile];
+
+ Assert.NotNull(conflict);
+ Assert.NotNull(conflict.Theirs);
+ Assert.NotNull(conflict.Ours);
+
+ Commit expectedCommit = repo.Branches[resultsBranchName].Tip;
+ Blob expectedBlob = (Blob)expectedCommit[expectedFileName].Target;
+ string expectedContent = expectedBlob.GetContentText(new FilteringOptions(expectedFileName));
+
+ // Verify the content of the file on disk contains conflict markers.
+ string fileContent = File.ReadAllText(Path.Combine(repo.Info.WorkingDirectory, conflictFile));
+ Assert.Equal(expectedContent, fileContent);
+ }
+ }
+
[Theory]
[InlineData(MergeFileFavor.Ours)]
[InlineData(MergeFileFavor.Theirs)]
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/a.txt b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/a.txt
new file mode 100644
index 000000000..ac92cd6c0
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/a.txt
@@ -0,0 +1,7 @@
+A
+B
+C
+D
+E
+F
+G
\ No newline at end of file
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/HEAD b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/HEAD
new file mode 100644
index 000000000..b870d8262
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/main
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/config b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/config
new file mode 100644
index 000000000..8ad0b1bad
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/config
@@ -0,0 +1,6 @@
+[core]
+ repositoryformatversion = 0
+ filemode = false
+ bare = false
+ logallrefupdates = true
+ ignorecase = true
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/index b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/index
new file mode 100644
index 000000000..36023028e
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/index differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/info/refs b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/info/refs
new file mode 100644
index 000000000..c02e5d754
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/info/refs
@@ -0,0 +1,3 @@
+cd4b13da8859445f4357c1e24d92b483ffe2dc85 refs/heads/conflicts
+0076e9fe99d1c2df56cd939a897db42d714b088b refs/heads/main
+139641856b0ef7941f583972614c1df9bb26939b refs/heads/results
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/commit-graph b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/commit-graph
new file mode 100644
index 000000000..f561a0815
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/commit-graph differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/packs b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/packs
new file mode 100644
index 000000000..dd0211e7e
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/info/packs
@@ -0,0 +1,3 @@
+P pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.pack
+P pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.pack
+
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.idx b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.idx
new file mode 100644
index 000000000..775aec8e7
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.idx differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.pack b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.pack
new file mode 100644
index 000000000..1cf4cb9ea
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.pack differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.rev b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.rev
new file mode 100644
index 000000000..e640dbcea
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-5fd168964fc34fdc1e4a50ae098e21799dd906a4.rev differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.idx b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.idx
new file mode 100644
index 000000000..718705056
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.idx differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.mtimes b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.mtimes
new file mode 100644
index 000000000..8717541c1
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.mtimes differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.pack b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.pack
new file mode 100644
index 000000000..a1a8cc755
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.pack differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.rev b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.rev
new file mode 100644
index 000000000..fa4458d12
Binary files /dev/null and b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/objects/pack/pack-9ea8f8acf571abc3f715ea91223671d542aacb6c.rev differ
diff --git a/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/packed-refs b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/packed-refs
new file mode 100644
index 000000000..2848696a9
--- /dev/null
+++ b/LibGit2Sharp.Tests/Resources/mergeconflict_testrepo_wd/dot_git/packed-refs
@@ -0,0 +1,4 @@
+# pack-refs with: peeled fully-peeled sorted
+cd4b13da8859445f4357c1e24d92b483ffe2dc85 refs/heads/conflicts
+0076e9fe99d1c2df56cd939a897db42d714b088b refs/heads/main
+139641856b0ef7941f583972614c1df9bb26939b refs/heads/results
diff --git a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
index e9429d562..1f24f4f98 100644
--- a/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
+++ b/LibGit2Sharp.Tests/TestHelpers/BaseFixture.cs
@@ -36,6 +36,7 @@ static BaseFixture()
public static string ShallowTestRepoPath { get; private set; }
public static string MergedTestRepoWorkingDirPath { get; private set; }
public static string MergeTestRepoWorkingDirPath { get; private set; }
+ public static string MergeConflictTestRepoWorkingDirPath { get; private set; }
public static string MergeRenamesTestRepoWorkingDirPath { get; private set; }
public static string RevertTestRepoWorkingDirPath { get; private set; }
public static string SubmoduleTestRepoWorkingDirPath { get; private set; }
@@ -81,6 +82,7 @@ private static void SetUpTestEnvironment()
MergedTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "mergedrepo_wd");
MergeRenamesTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "mergerenames_wd");
MergeTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "merge_testrepo_wd");
+ MergeConflictTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "mergeconflict_testrepo_wd");
RevertTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "revert_testrepo_wd");
SubmoduleTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "submodule_wd");
SubmoduleTargetTestRepoWorkingDirPath = Path.Combine(ResourcesDirectory.FullName, "submodule_target_wd");
@@ -201,6 +203,11 @@ protected string SandboxMergeTestRepo()
return Sandbox(MergeTestRepoWorkingDirPath);
}
+ protected string SandboxMergeConflictTestRepo()
+ {
+ return Sandbox(MergeConflictTestRepoWorkingDirPath);
+ }
+
protected string SandboxRevertTestRepo()
{
return Sandbox(RevertTestRepoWorkingDirPath);
diff --git a/LibGit2Sharp/CheckoutFileConflictStrategy.cs b/LibGit2Sharp/CheckoutFileConflictStrategy.cs
index 9d53745e7..29726517a 100644
--- a/LibGit2Sharp/CheckoutFileConflictStrategy.cs
+++ b/LibGit2Sharp/CheckoutFileConflictStrategy.cs
@@ -33,6 +33,11 @@ public enum CheckoutFileConflictStrategy
///
/// Write diff3 formated files for conflicts.
///
- Diff3
+ Diff3,
+
+ ///
+ /// Write zdiff3 formated files for conflicts.
+ ///
+ ZDiff3
}
}
diff --git a/LibGit2Sharp/Core/GitCheckoutOpts.cs b/LibGit2Sharp/Core/GitCheckoutOpts.cs
index 053258565..56592e612 100644
--- a/LibGit2Sharp/Core/GitCheckoutOpts.cs
+++ b/LibGit2Sharp/Core/GitCheckoutOpts.cs
@@ -105,6 +105,11 @@ internal enum CheckoutStrategy
///
GIT_CHECKOUT_DONT_WRITE_INDEX = (1 << 23),
+ ///
+ /// Include common ancestor data in zdiff3 format for conflicts
+ ///
+ GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3 = (1 << 25),
+
// THE FOLLOWING OPTIONS ARE NOT YET IMPLEMENTED
///
diff --git a/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
index 0fba82754..56adcb243 100644
--- a/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
+++ b/LibGit2Sharp/Core/GitCheckoutOptsWrapper.cs
@@ -78,6 +78,10 @@ internal static CheckoutStrategy CheckoutStrategyFromFileConflictStrategy(Checko
case CheckoutFileConflictStrategy.Diff3:
flags = CheckoutStrategy.GIT_CHECKOUT_CONFLICT_STYLE_DIFF3;
break;
+
+ case CheckoutFileConflictStrategy.ZDiff3:
+ flags = CheckoutStrategy.GIT_CHECKOUT_CONFLICT_STYLE_ZDIFF3;
+ break;
}
return flags;
diff --git a/LibGit2Sharp/Core/GitMergeOpts.cs b/LibGit2Sharp/Core/GitMergeOpts.cs
index 48675a2d0..5f823e133 100644
--- a/LibGit2Sharp/Core/GitMergeOpts.cs
+++ b/LibGit2Sharp/Core/GitMergeOpts.cs
@@ -194,5 +194,10 @@ internal enum GitMergeFileFlag
/// Take extra time to find minimal diff
///
GIT_MERGE_FILE_DIFF_MINIMAL = (1 << 7),
+
+ ///
+ /// Create zdiff3 ("zealous diff3")-style files
+ ///
+ GIT_MERGE_FILE_STYLE_ZDIFF3 = (1 << 8),
}
}