diff --git a/LibGit2Sharp.Tests/NetworkFixture.cs b/LibGit2Sharp.Tests/NetworkFixture.cs index d1d221de5..bf497afc8 100644 --- a/LibGit2Sharp.Tests/NetworkFixture.cs +++ b/LibGit2Sharp.Tests/NetworkFixture.cs @@ -196,6 +196,38 @@ public void CanPullIntoEmptyRepo() } } + [Fact] + public void PullWithoutMergeBranchThrows() + { + var scd = BuildSelfCleaningDirectory(); + string clonedRepoPath = Repository.Clone(StandardTestRepoPath, scd.DirectoryPath); + + using (var repo = new Repository(clonedRepoPath)) + { + Branch branch = repo.Branches["master"]; + + // Update the Upstream merge branch + repo.Branches.Update(branch, + b => b.UpstreamBranch = "refs/heads/another_master"); + + bool didPullThrow = false; + MergeFetchHeadNotFoundException thrownException = null; + + try + { + repo.Network.Pull(Constants.Signature, new PullOptions()); + } + catch(MergeFetchHeadNotFoundException ex) + { + didPullThrow = true; + thrownException = ex; + } + + Assert.True(didPullThrow, "Pull did not throw."); + Assert.True(thrownException.Message.Contains("refs/heads/another_master"), "Exception message did not contain expected reference."); + } + } + /* * git ls-remote https://github.com/libgit2/TestGitRepository * 49322bb17d3acc9146f98c97d078513228bbf3c0 HEAD diff --git a/LibGit2Sharp/LibGit2Sharp.csproj b/LibGit2Sharp/LibGit2Sharp.csproj index a5036c4d6..ba00f56df 100644 --- a/LibGit2Sharp/LibGit2Sharp.csproj +++ b/LibGit2Sharp/LibGit2Sharp.csproj @@ -124,6 +124,7 @@ + diff --git a/LibGit2Sharp/MergeFetchHeadNotFoundException.cs b/LibGit2Sharp/MergeFetchHeadNotFoundException.cs new file mode 100644 index 000000000..ff4c9cdb6 --- /dev/null +++ b/LibGit2Sharp/MergeFetchHeadNotFoundException.cs @@ -0,0 +1,49 @@ +using System; +using System.Runtime.Serialization; +using LibGit2Sharp.Core; + +namespace LibGit2Sharp +{ + /// + /// The exception that is thrown when the ref to merge with was as part of a pull operation not fetched. + /// + [Serializable] + public class MergeFetchHeadNotFoundException : NotFoundException + { + /// + /// Initializes a new instance of the class. + /// + public MergeFetchHeadNotFoundException() + { + } + + /// + /// Initializes a new instance of the class with a specified error message. + /// + /// A message that describes the error. + public MergeFetchHeadNotFoundException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class with a specified error message and a reference to the inner exception that is the cause of this exception. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception. If the parameter is not a null reference, the current exception is raised in a catch block that handles the inner exception. + public MergeFetchHeadNotFoundException(string message, Exception innerException) + : base(message, innerException) + { + } + + /// + /// Initializes a new instance of the class with a serialized data. + /// + /// The that holds the serialized object data about the exception being thrown. + /// The that contains contextual information about the source or destination. + protected MergeFetchHeadNotFoundException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } + } +} diff --git a/LibGit2Sharp/Repository.cs b/LibGit2Sharp/Repository.cs index ab91bf3b4..a03c73103 100644 --- a/LibGit2Sharp/Repository.cs +++ b/LibGit2Sharp/Repository.cs @@ -1032,7 +1032,9 @@ internal MergeResult MergeFetchHeads(Signature merger, MergeOptions options) if (fetchHeads.Length == 0) { - throw new LibGit2SharpException("Remote ref to merge from was not fetched."); + var expectedRef = this.Head.UpstreamBranchCanonicalName; + throw new MergeFetchHeadNotFoundException(string.Format(CultureInfo.InvariantCulture, + "The current branch is configured to merge with the reference '{0}' from the remote, but this reference was not fetched.", expectedRef)); } GitMergeHeadHandle[] mergeHeadHandles = fetchHeads.Select(fetchHead =>