@@ -755,47 +755,36 @@ public virtual Commit FindMergeBase(IEnumerable<Commit> commits, MergeBaseFindin
755
755
756
756
/// <summary>
757
757
/// Perform a three-way merge of two commits, looking up their
758
- /// commit ancestor. The returned index will contain the results
759
- /// of the merge and can be examined for conflicts. The returned
760
- /// index must be disposed.
758
+ /// commit ancestor. The returned <see cref="MergeTreeResult"/> will contain the results
759
+ /// of the merge and can be examined for conflicts.
761
760
/// </summary>
762
- /// <param name="ours">The first tree </param>
763
- /// <param name="theirs">The second tree </param>
761
+ /// <param name="ours">The first commit </param>
762
+ /// <param name="theirs">The second commit </param>
764
763
/// <param name="options">The <see cref="MergeTreeOptions"/> controlling the merge</param>
765
- /// <returns>The <see cref="Index "/> containing the merged trees and any conflicts</returns>
764
+ /// <returns>The <see cref="MergeTreeResult "/> containing the merged trees and any conflicts</returns>
766
765
public virtual MergeTreeResult MergeCommits(Commit ours, Commit theirs, MergeTreeOptions options)
767
766
{
768
767
Ensure.ArgumentNotNull(ours, "ours");
769
768
Ensure.ArgumentNotNull(theirs, "theirs");
770
769
771
- options = options ?? new MergeTreeOptions();
770
+ var modifiedOptions = new MergeTreeOptions();
772
771
773
772
// We throw away the index after looking at the conflicts, so we'll never need the REUC
774
773
// entries to be there
775
- GitMergeFlag mergeFlags = GitMergeFlag.GIT_MERGE_NORMAL | GitMergeFlag.GIT_MERGE_SKIP_REUC;
776
- if (options.FindRenames)
777
- {
778
- mergeFlags |= GitMergeFlag.GIT_MERGE_FIND_RENAMES;
779
- }
780
- if (options.FailOnConflict)
781
- {
782
- mergeFlags |= GitMergeFlag.GIT_MERGE_FAIL_ON_CONFLICT;
783
- }
774
+ modifiedOptions.SkipReuc = true;
784
775
785
-
786
- var mergeOptions = new GitMergeOpts
776
+ if (options != null)
787
777
{
788
- Version = 1,
789
- MergeFileFavorFlags = options.MergeFileFavor,
790
- MergeTreeFlags = mergeFlags,
791
- RenameThreshold = (uint)options.RenameThreshold,
792
- TargetLimit = (uint)options.TargetLimit,
793
- };
778
+ modifiedOptions.FailOnConflict = options.FailOnConflict;
779
+ modifiedOptions.FindRenames = options.FindRenames;
780
+ modifiedOptions.IgnoreWhitespaceChange = options.IgnoreWhitespaceChange;
781
+ modifiedOptions.MergeFileFavor = options.MergeFileFavor;
782
+ modifiedOptions.RenameThreshold = options.RenameThreshold;
783
+ modifiedOptions.TargetLimit = options.TargetLimit;
784
+ }
794
785
795
786
bool earlyStop;
796
- using (var oneHandle = Proxy.git_object_lookup(repo.Handle, ours.Id, GitObjectType.Commit))
797
- using (var twoHandle = Proxy.git_object_lookup(repo.Handle, theirs.Id, GitObjectType.Commit))
798
- using (var indexHandle = Proxy.git_merge_commits(repo.Handle, oneHandle, twoHandle, mergeOptions, out earlyStop))
787
+ using (var indexHandle = MergeCommits(ours, theirs, modifiedOptions, out earlyStop))
799
788
{
800
789
MergeTreeResult mergeResult;
801
790
@@ -859,6 +848,80 @@ public virtual PackBuilderResults Pack(PackBuilderOptions options, Action<PackBu
859
848
return InternalPack(options, packDelegate);
860
849
}
861
850
851
+ /// <summary>
852
+ /// Perform a three-way merge of two commits, looking up their
853
+ /// commit ancestor. The returned index will contain the results
854
+ /// of the merge and can be examined for conflicts.
855
+ /// </summary>
856
+ /// <param name="ours">The first tree</param>
857
+ /// <param name="theirs">The second tree</param>
858
+ /// <param name="options">The <see cref="MergeTreeOptions"/> controlling the merge</param>
859
+ /// <returns>The <see cref="TransientIndex"/> containing the merged trees and any conflicts, or null if the merge stopped early due to conflicts.
860
+ /// The index must be disposed by the caller.</returns>
861
+ public virtual TransientIndex MergeCommitsIntoIndex(Commit ours, Commit theirs, MergeTreeOptions options)
862
+ {
863
+ Ensure.ArgumentNotNull(ours, "ours");
864
+ Ensure.ArgumentNotNull(theirs, "theirs");
865
+
866
+ options = options ?? new MergeTreeOptions();
867
+
868
+ bool earlyStop;
869
+ var indexHandle = MergeCommits(ours, theirs, options, out earlyStop);
870
+ if (earlyStop)
871
+ {
872
+ if (indexHandle != null)
873
+ {
874
+ indexHandle.Dispose();
875
+ }
876
+ return null;
877
+ }
878
+ var result = new TransientIndex(indexHandle, repo);
879
+ return result;
880
+ }
881
+
882
+ /// <summary>
883
+ /// Perform a three-way merge of two commits, looking up their
884
+ /// commit ancestor. The returned index will contain the results
885
+ /// of the merge and can be examined for conflicts.
886
+ /// </summary>
887
+ /// <param name="ours">The first tree</param>
888
+ /// <param name="theirs">The second tree</param>
889
+ /// <param name="options">The <see cref="MergeTreeOptions"/> controlling the merge</param>
890
+ /// <param name="earlyStop">True if the merge stopped early due to conflicts</param>
891
+ /// <returns>The <see cref="IndexHandle"/> containing the merged trees and any conflicts</returns>
892
+ private IndexHandle MergeCommits(Commit ours, Commit theirs, MergeTreeOptions options, out bool earlyStop)
893
+ {
894
+ GitMergeFlag mergeFlags = GitMergeFlag.GIT_MERGE_NORMAL;
895
+ if (options.SkipReuc)
896
+ {
897
+ mergeFlags |= GitMergeFlag.GIT_MERGE_SKIP_REUC;
898
+ }
899
+ if (options.FindRenames)
900
+ {
901
+ mergeFlags |= GitMergeFlag.GIT_MERGE_FIND_RENAMES;
902
+ }
903
+ if (options.FailOnConflict)
904
+ {
905
+ mergeFlags |= GitMergeFlag.GIT_MERGE_FAIL_ON_CONFLICT;
906
+ }
907
+
908
+ var mergeOptions = new GitMergeOpts
909
+ {
910
+ Version = 1,
911
+ MergeFileFavorFlags = options.MergeFileFavor,
912
+ MergeTreeFlags = mergeFlags,
913
+ RenameThreshold = (uint)options.RenameThreshold,
914
+ TargetLimit = (uint)options.TargetLimit,
915
+ };
916
+ using (var oneHandle = Proxy.git_object_lookup(repo.Handle, ours.Id, GitObjectType.Commit))
917
+ using (var twoHandle = Proxy.git_object_lookup(repo.Handle, theirs.Id, GitObjectType.Commit))
918
+ {
919
+ var indexHandle = Proxy.git_merge_commits(repo.Handle, oneHandle, twoHandle, mergeOptions, out earlyStop);
920
+ return indexHandle;
921
+ }
922
+ }
923
+
924
+
862
925
/// <summary>
863
926
/// Packs objects in the <see cref="ObjectDatabase"/> and write a pack (.pack) and index (.idx) files for them.
864
927
/// For internal use only.
0 commit comments