diff --git a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs index b554cfb59..04ed2010f 100644 --- a/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs +++ b/GVFS/GVFS.FunctionalTests/Tests/EnlistmentPerFixture/CloneTests.cs @@ -73,6 +73,31 @@ public void CloneCreatesCorrectFilesInRoot() } } + [TestCase] + public void CloneWithNonExistentBranchFailsWithBranchError() + { + string newEnlistmentRoot = GVFSFunctionalTestEnlistment.GetUniqueEnlistmentRoot(); + + ProcessStartInfo processInfo = new ProcessStartInfo(GVFSTestConfig.PathToGVFS); + processInfo.Arguments = $"clone {GVFSTestConfig.RepoToClone} {newEnlistmentRoot} --branch nonexistent/branch/that/does/not/exist"; + processInfo.WindowStyle = ProcessWindowStyle.Hidden; + processInfo.CreateNoWindow = true; + processInfo.WorkingDirectory = Path.GetDirectoryName(this.Enlistment.EnlistmentRoot); + processInfo.UseShellExecute = false; + processInfo.RedirectStandardOutput = true; + + ProcessResult result = ProcessHelper.Run(processInfo); + result.ExitCode.ShouldEqual(GVFSGenericError); + + // The clone should surface the real, actionable failure... + result.Output.ShouldContain("Remote branch nonexistent/branch/that/does/not/exist not found in upstream origin"); + + // ...and NOT the misleading downstream exception that used to be thrown when + // a LibGit2RepoInvoker was constructed against a src folder that was never created. + result.Output.ShouldNotContain(false, "Couldn't open repo"); + result.Output.ShouldNotContain(false, "InvalidDataException"); + } + private void SubfolderCloneShouldFail() { ProcessStartInfo processInfo = new ProcessStartInfo(GVFSTestConfig.PathToGVFS); diff --git a/GVFS/GVFS/CommandLine/CloneVerb.cs b/GVFS/GVFS/CommandLine/CloneVerb.cs index e64749d8c..acf75cc0b 100644 --- a/GVFS/GVFS/CommandLine/CloneVerb.cs +++ b/GVFS/GVFS/CommandLine/CloneVerb.cs @@ -152,7 +152,7 @@ public override void Execute() CacheServerInfo cacheServer = null; ServerGVFSConfig serverGVFSConfig = null; - bool trustPackIndexes; + bool trustPackIndexes = false; using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { @@ -248,10 +248,17 @@ public override void Execute() { tracer.RelatedError(cloneResult.ErrorMessage); } - - using (var repo = new LibGit2RepoInvoker(tracer, enlistment.WorkingDirectoryBackingRoot)) + else { - trustPackIndexes = repo.GetConfigBoolOrDefault(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + // Only inspect the freshly-cloned repo when the clone succeeded. On a failed + // clone the 'src' working directory was never created, so constructing a + // LibGit2RepoInvoker here would log a misleading "Couldn't open repo" warning + // and throw an InvalidDataException that masks the real failure (e.g. the + // "Remote branch ... not found in upstream origin" error surfaced below). + using (var repo = new LibGit2RepoInvoker(tracer, enlistment.WorkingDirectoryBackingRoot)) + { + trustPackIndexes = repo.GetConfigBoolOrDefault(GVFSConstants.GitConfig.TrustPackIndexes, GVFSConstants.GitConfig.TrustPackIndexesDefault); + } } }