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

Skip to content
This repository was archived by the owner on Feb 3, 2023. It is now read-only.

Commit c7e11bb

Browse files
committed
Introduce new merge functionality, including Pull, merge options, and
merging branches. This includes a refactoring of the merge logic to support the new scenarios. New functionality includes: - Deprecate Network.Fetchheads, Repository.MergeHeads as these should be internal only. - Introduce ability to pull the configured upstream branch for the current branch - Introduce ability to merge a branch into the current branch. - Introduce options to control merge behavior. The current exposed options include whether to commit the merge commit and the allowed merge types.
1 parent fb978a0 commit c7e11bb

33 files changed

+709
-212
lines changed

LibGit2Sharp.Tests/FetchHeadFixture.cs

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

LibGit2Sharp.Tests/LibGit2Sharp.Tests.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@
7777
<Compile Include="ConflictFixture.cs" />
7878
<Compile Include="SubmoduleFixture.cs" />
7979
<Compile Include="IgnoreFixture.cs" />
80-
<Compile Include="FetchHeadFixture.cs" />
8180
<Compile Include="ArchiveFixture.cs" />
8281
<Compile Include="MergeFixture.cs" />
8382
<Compile Include="CleanFixture.cs" />

LibGit2Sharp.Tests/MergeFixture.cs

Lines changed: 178 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ public void ANewRepoIsFullyMerged()
1515
using (var repo = new Repository(repoPath))
1616
{
1717
Assert.Equal(true, repo.Index.IsFullyMerged);
18-
Assert.Empty(repo.MergeHeads);
1918
}
2019
}
2120

@@ -25,7 +24,6 @@ public void AFullyMergedRepoOnlyContainsStagedIndexEntries()
2524
using (var repo = new Repository(StandardTestRepoWorkingDirPath))
2625
{
2726
Assert.Equal(true, repo.Index.IsFullyMerged);
28-
Assert.Empty(repo.MergeHeads);
2927

3028
foreach (var entry in repo.Index)
3129
{
@@ -73,12 +71,6 @@ public void CanRetrieveTheBranchBeingMerged()
7371
Touch(repo.Info.Path, "MERGE_HEAD", string.Format("{0}{1}{2}{1}", firstBranch, "\n", secondBranch));
7472

7573
Assert.Equal(CurrentOperation.Merge, repo.Info.CurrentOperation);
76-
77-
MergeHead[] mergedHeads = repo.MergeHeads.ToArray();
78-
Assert.Equal("MERGE_HEAD[0]", mergedHeads[0].Name);
79-
Assert.Equal(firstBranch, mergedHeads[0].Tip.Id.Sha);
80-
Assert.Equal("MERGE_HEAD[1]", mergedHeads[1].Name);
81-
Assert.Null(mergedHeads[1].Tip);
8274
}
8375
}
8476

@@ -298,6 +290,180 @@ public void ConflictingMergeReposBinary()
298290
}
299291
}
300292

293+
[Theory]
294+
[InlineData(true, FastForwardStrategy.Default, fastForwardBranchInitialId, MergeStatus.FastForward)]
295+
[InlineData(true, FastForwardStrategy.FastForwardOnly, fastForwardBranchInitialId, MergeStatus.FastForward)]
296+
[InlineData(false, FastForwardStrategy.Default, fastForwardBranchInitialId, MergeStatus.FastForward)]
297+
[InlineData(false, FastForwardStrategy.FastForwardOnly, fastForwardBranchInitialId, MergeStatus.FastForward)]
298+
public void CanFastForwardCommit(bool fromDetachedHead, FastForwardStrategy fastForwardStrategy, string expectedCommitId, MergeStatus expectedMergeStatus)
299+
{
300+
string path = CloneMergeTestRepo();
301+
using (var repo = new Repository(path))
302+
{
303+
if(fromDetachedHead)
304+
{
305+
repo.Checkout(repo.Head.Tip.Id.Sha);
306+
}
307+
308+
Commit commitToMerge = repo.Branches["fast_forward"].Tip;
309+
310+
MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = fastForwardStrategy });
311+
312+
Assert.Equal(expectedMergeStatus, result.Status);
313+
Assert.Equal(expectedCommitId, result.Commit.Id.Sha);
314+
Assert.False(repo.Index.RetrieveStatus().Any());
315+
Assert.Equal(fromDetachedHead, repo.Info.IsHeadDetached);
316+
}
317+
}
318+
319+
[Theory]
320+
[InlineData(true, FastForwardStrategy.Default, MergeStatus.NonFastForward)]
321+
[InlineData(true, FastForwardStrategy.NoFastFoward, MergeStatus.NonFastForward)]
322+
[InlineData(false, FastForwardStrategy.Default, MergeStatus.NonFastForward)]
323+
[InlineData(false, FastForwardStrategy.NoFastFoward, MergeStatus.NonFastForward)]
324+
public void CanNonFastForwardMergeCommit(bool fromDetachedHead, FastForwardStrategy fastForwardStrategy, MergeStatus expectedMergeStatus)
325+
{
326+
string path = CloneMergeTestRepo();
327+
using (var repo = new Repository(path))
328+
{
329+
if (fromDetachedHead)
330+
{
331+
repo.Checkout(repo.Head.Tip.Id.Sha);
332+
}
333+
334+
Commit commitToMerge = repo.Branches["normal_merge"].Tip;
335+
336+
MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = fastForwardStrategy });
337+
338+
Assert.Equal(expectedMergeStatus, result.Status);
339+
Assert.False(repo.Index.RetrieveStatus().Any());
340+
Assert.Equal(fromDetachedHead, repo.Info.IsHeadDetached);
341+
}
342+
}
343+
344+
[Fact]
345+
public void FastForwardNonFastForwardableMergeThrows()
346+
{
347+
string path = CloneMergeTestRepo();
348+
using (var repo = new Repository(path))
349+
{
350+
Commit commitToMerge = repo.Branches["normal_merge"].Tip;
351+
Assert.Throws<NonFastForwardException>(() => repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = FastForwardStrategy.FastForwardOnly }));
352+
}
353+
}
354+
355+
[Fact]
356+
public void CanMergeAndNotCommit()
357+
{
358+
string path = CloneMergeTestRepo();
359+
using (var repo = new Repository(path))
360+
{
361+
Commit commitToMerge = repo.Branches["normal_merge"].Tip;
362+
363+
MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { CommitOnSuccess = false});
364+
365+
Assert.Equal(MergeStatus.NonFastForward, result.Status);
366+
Assert.Equal(null, result.Commit);
367+
368+
RepositoryStatus repoStatus = repo.Index.RetrieveStatus();
369+
370+
// Verify that there is a staged entry.
371+
Assert.Equal(1, repoStatus.Count());
372+
Assert.Equal(FileStatus.Staged, repo.Index.RetrieveStatus("b.txt"));
373+
}
374+
}
375+
376+
[Fact]
377+
public void CanForceNonFastForwardMerge()
378+
{
379+
string path = CloneMergeTestRepo();
380+
using (var repo = new Repository(path))
381+
{
382+
Commit commitToMerge = repo.Branches["fast_forward"].Tip;
383+
384+
MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = FastForwardStrategy.NoFastFoward });
385+
386+
Assert.Equal(MergeStatus.NonFastForward, result.Status);
387+
Assert.Equal("f58f780d5a0ae392efd4a924450b1bbdc0577d32", result.Commit.Id.Sha);
388+
Assert.False(repo.Index.RetrieveStatus().Any());
389+
}
390+
}
391+
392+
[Fact]
393+
public void VerifyUpToDateMerge()
394+
{
395+
string path = CloneMergeTestRepo();
396+
using (var repo = new Repository(path))
397+
{
398+
Commit commitToMerge = repo.Branches["master"].Tip;
399+
400+
MergeResult result = repo.Merge(commitToMerge, Constants.Signature, new MergeOptions() { FastForwardStrategy = FastForwardStrategy.NoFastFoward });
401+
402+
Assert.Equal(MergeStatus.UpToDate, result.Status);
403+
Assert.Equal(null, result.Commit);
404+
Assert.False(repo.Index.RetrieveStatus().Any());
405+
}
406+
}
407+
408+
[Theory]
409+
[InlineData("refs/heads/normal_merge", FastForwardStrategy.Default, MergeStatus.NonFastForward)]
410+
[InlineData("normal_merge", FastForwardStrategy.Default, MergeStatus.NonFastForward)]
411+
[InlineData("625186280ed2a6ec9b65d250ed90cf2e4acef957", FastForwardStrategy.Default, MergeStatus.NonFastForward)]
412+
[InlineData("fast_forward", FastForwardStrategy.Default, MergeStatus.FastForward)]
413+
public void CanMergeCommittish(string committish, FastForwardStrategy strategy, MergeStatus expectedMergeStatus)
414+
{
415+
string path = CloneMergeTestRepo();
416+
using (var repo = new Repository(path))
417+
{
418+
MergeResult result = repo.Merge(committish, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy });
419+
420+
Assert.Equal(expectedMergeStatus, result.Status);
421+
Assert.False(repo.Index.RetrieveStatus().Any());
422+
}
423+
}
424+
425+
[Theory]
426+
[InlineData("refs/heads/normal_merge", FastForwardStrategy.Default, MergeStatus.NonFastForward)]
427+
[InlineData("fast_forward", FastForwardStrategy.Default, MergeStatus.FastForward)]
428+
public void CanMergeBranch(string branchName, FastForwardStrategy strategy, MergeStatus expectedMergeStatus)
429+
{
430+
string path = CloneMergeTestRepo();
431+
using (var repo = new Repository(path))
432+
{
433+
Branch branch = repo. Branches[branchName];
434+
MergeResult result = repo.Merge(branch, Constants.Signature, new MergeOptions() { FastForwardStrategy = strategy });
435+
436+
Assert.Equal(expectedMergeStatus, result.Status);
437+
Assert.False(repo.Index.RetrieveStatus().Any());
438+
}
439+
}
440+
441+
[Fact]
442+
public void CanMergeIntoOrphanedBranch()
443+
{
444+
string path = CloneMergeTestRepo();
445+
using (var repo = new Repository(path))
446+
{
447+
repo.Refs.Add("HEAD", "refs/heads/orphan", true);
448+
449+
// Remove entries from the working directory
450+
foreach(var entry in repo.Index.RetrieveStatus())
451+
{
452+
repo.Index.Unstage(entry.FilePath);
453+
repo.Index.Remove(entry.FilePath, true);
454+
}
455+
456+
// Assert that we have an empty working directory.
457+
Assert.False(repo.Index.RetrieveStatus().Any());
458+
459+
MergeResult result = repo.Merge("master", Constants.Signature);
460+
461+
Assert.Equal(MergeStatus.FastForward, result.Status);
462+
Assert.Equal(masterBranchInitialId, result.Commit.Id.Sha);
463+
Assert.False(repo.Index.RetrieveStatus().Any());
464+
}
465+
}
466+
301467
private Commit AddFileCommitToRepo(IRepository repository, string filename, string content = null)
302468
{
303469
Touch(repository.Info.WorkingDirectory, filename, content);
@@ -306,5 +472,9 @@ private Commit AddFileCommitToRepo(IRepository repository, string filename, stri
306472

307473
return repository.Commit("New commit", Constants.Signature, Constants.Signature);
308474
}
475+
476+
// Commit IDs of the checked in merge_testrepo
477+
private const string masterBranchInitialId = "83cebf5389a4adbcb80bda6b68513caee4559802";
478+
private const string fastForwardBranchInitialId = "4dfaa1500526214ae7b33f9b2c1144ca8b6b1f53";
309479
}
310480
}

0 commit comments

Comments
 (0)