From 9c8bd994491492e80335ea23995446ae2b68cfd0 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 17 Mar 2020 09:05:08 -0400 Subject: [PATCH 1/4] Enlistment: be robust to repos with no 'origin' Signed-off-by: Derrick Stolee --- Scalar.Common/Enlistment.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Scalar.Common/Enlistment.cs b/Scalar.Common/Enlistment.cs index 00fb8558ac..b610bfba2b 100644 --- a/Scalar.Common/Enlistment.cs +++ b/Scalar.Common/Enlistment.cs @@ -36,7 +36,23 @@ protected Enlistment( GitProcess.ConfigResult originResult = gitProcess.GetOriginUrl(); if (!originResult.TryParseAsString(out string originUrl, out string error)) { - throw new InvalidRepoException(this.WorkingDirectoryRoot, "Could not get origin url. git error: " + error); + if (!gitProcess.TryGetRemotes(out string[] remotes, out error)) + { + throw new InvalidRepoException(this.WorkingDirectoryRoot, $"Failed to load remotes with error: {error}"); + } + + if (remotes.Length == 0) + { + originUrl = string.Empty; + } + else + { + GitProcess.ConfigResult remoteResult = gitProcess.GetFromLocalConfig($"remote.{remotes[0]}.url"); + if (!remoteResult.TryParseAsString(out originUrl, out error)) + { + originUrl = string.Empty; + } + } } if (originUrl == null) From 0827468f23854e25baba80033b5efe05720229e1 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 17 Mar 2020 11:01:42 -0400 Subject: [PATCH 2/4] Enlistment: allow repos without 'origin' Signed-off-by: Derrick Stolee --- Scalar.Common/Enlistment.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Scalar.Common/Enlistment.cs b/Scalar.Common/Enlistment.cs index b610bfba2b..2f0961b354 100644 --- a/Scalar.Common/Enlistment.cs +++ b/Scalar.Common/Enlistment.cs @@ -41,26 +41,17 @@ protected Enlistment( throw new InvalidRepoException(this.WorkingDirectoryRoot, $"Failed to load remotes with error: {error}"); } - if (remotes.Length == 0) - { - originUrl = string.Empty; - } - else + if (remotes.Length > 0) { GitProcess.ConfigResult remoteResult = gitProcess.GetFromLocalConfig($"remote.{remotes[0]}.url"); if (!remoteResult.TryParseAsString(out originUrl, out error)) { - originUrl = string.Empty; + originUrl = null; } } } - if (originUrl == null) - { - throw new InvalidRepoException(this.WorkingDirectoryRoot, "Could not get origin url. remote 'origin' is not configured for this repo.'"); - } - - this.RepoUrl = originUrl.Trim(); + this.RepoUrl = originUrl?.Trim() ?? string.Empty; } this.Authentication = authentication ?? new GitAuthentication(gitProcess, this.RepoUrl, this.WorkingDirectoryRoot); From e1b2a9710a5390bb36fb79bbea9717529a700ef7 Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 17 Mar 2020 11:02:04 -0400 Subject: [PATCH 3/4] ScalarEnlistment: properly store working directory when creating without URL Remove the other constructor that allows this by default to avoid this problem in the future. Signed-off-by: Derrick Stolee --- Scalar.Common/InvalidRepoException.cs | 2 +- Scalar.Common/ScalarEnlistment.cs | 16 ++-------------- Scalar.UnitTests/Common/ScalarEnlistmentTests.cs | 2 +- .../Mock/Common/MockScalarEnlistment.cs | 4 ++-- 4 files changed, 6 insertions(+), 18 deletions(-) diff --git a/Scalar.Common/InvalidRepoException.cs b/Scalar.Common/InvalidRepoException.cs index abd959b9ab..4e89453bcf 100644 --- a/Scalar.Common/InvalidRepoException.cs +++ b/Scalar.Common/InvalidRepoException.cs @@ -7,7 +7,7 @@ public class InvalidRepoException : Exception public string RepoPath { get; } public InvalidRepoException(string repoPath, string message) - : base(message) + : base($"path: '{repoPath}', message: '{message}'") { this.RepoPath = repoPath; } diff --git a/Scalar.Common/ScalarEnlistment.cs b/Scalar.Common/ScalarEnlistment.cs index a51fa0a439..31b3c9ebd4 100644 --- a/Scalar.Common/ScalarEnlistment.cs +++ b/Scalar.Common/ScalarEnlistment.cs @@ -10,19 +10,7 @@ public partial class ScalarEnlistment : Enlistment private string gitVersion; private string scalarVersion; - // New enlistment - public ScalarEnlistment(string enlistmentRoot, string repoUrl, string gitBinPath, GitAuthentication authentication) - : this( - enlistmentRoot, - Path.Combine(enlistmentRoot, ScalarConstants.WorkingDirectoryRootName), - repoUrl, - gitBinPath, - authentication) - { - } - - // Existing, configured enlistment - private ScalarEnlistment(string enlistmentRoot, string workingDirectory, string repoUrl, string gitBinPath, GitAuthentication authentication) + public ScalarEnlistment(string enlistmentRoot, string workingDirectory, string repoUrl, string gitBinPath, GitAuthentication authentication) : base( enlistmentRoot, workingDirectory, @@ -74,7 +62,7 @@ public static ScalarEnlistment CreateFromDirectory( if (createWithoutRepoURL) { - return new ScalarEnlistment(enlistmentRoot, string.Empty, gitBinRoot, authentication); + return new ScalarEnlistment(enlistmentRoot, workingDirectory, string.Empty, gitBinRoot, authentication); } return new ScalarEnlistment(enlistmentRoot, workingDirectory, null, gitBinRoot, authentication); diff --git a/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs b/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs index c285c8cfe7..ed9a7a5de3 100644 --- a/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs +++ b/Scalar.UnitTests/Common/ScalarEnlistmentTests.cs @@ -102,7 +102,7 @@ private class TestScalarEnlistment : ScalarEnlistment private MockGitProcess gitProcess; public TestScalarEnlistment() - : base("mock:\\path", "mock://repoUrl", "mock:\\git", authentication: null) + : base("mock:\\path", "mock:\\path", "mock://repoUrl", "mock:\\git", authentication: null) { this.gitProcess = new MockGitProcess(); this.gitProcess.SetExpectedCommandResult( diff --git a/Scalar.UnitTests/Mock/Common/MockScalarEnlistment.cs b/Scalar.UnitTests/Mock/Common/MockScalarEnlistment.cs index 42e69b6865..325e2940f9 100644 --- a/Scalar.UnitTests/Mock/Common/MockScalarEnlistment.cs +++ b/Scalar.UnitTests/Mock/Common/MockScalarEnlistment.cs @@ -10,7 +10,7 @@ public class MockScalarEnlistment : ScalarEnlistment private MockGitProcess gitProcess; public MockScalarEnlistment() - : base(Path.Combine("mock:", "path"), "mock://repoUrl", Path.Combine("mock:", "git"), authentication: null) + : base(Path.Combine("mock:", "path"), Path.Combine("mock:", "path"), "mock://repoUrl", Path.Combine("mock:", "git"), authentication: null) { this.GitObjectsRoot = Path.Combine("mock:", "path", ".git", "objects"); this.LocalObjectsRoot = this.GitObjectsRoot; @@ -18,7 +18,7 @@ public MockScalarEnlistment() } public MockScalarEnlistment(string enlistmentRoot, string repoUrl, string gitBinPath, MockGitProcess gitProcess) - : base(enlistmentRoot, repoUrl, gitBinPath, authentication: null) + : base(enlistmentRoot, enlistmentRoot, repoUrl, gitBinPath, authentication: null) { this.gitProcess = gitProcess; } From d09d345a2be0307c10d781be3afe6a4c6fb3979e Mon Sep 17 00:00:00 2001 From: Derrick Stolee Date: Tue, 17 Mar 2020 13:10:59 -0400 Subject: [PATCH 4/4] Docs: update fetch step about multiple remotes: Signed-off-by: Derrick Stolee --- Scalar/CommandLine/CloneVerb.cs | 1 + docs/advanced.md | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Scalar/CommandLine/CloneVerb.cs b/Scalar/CommandLine/CloneVerb.cs index 588e6cf250..8ad0373bfb 100644 --- a/Scalar/CommandLine/CloneVerb.cs +++ b/Scalar/CommandLine/CloneVerb.cs @@ -427,6 +427,7 @@ private Result TryCreateEnlistment( { enlistment = new ScalarEnlistment( normalizedEnlistementRootPath, + Path.Combine(normalizedEnlistementRootPath, ScalarConstants.WorkingDirectoryRootName), this.RepositoryURL, gitBinPath, authentication: null); diff --git a/docs/advanced.md b/docs/advanced.md index c6b1f6087f..0aa5f77ee3 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -19,9 +19,10 @@ tasks are: commits. After writing a new file, verify the file was computed successfully. This drastically improves the performance of commands like `git log --graph`. -* `fetch`: Fetch the latest data from the remote server. If using the GVFS +* `fetch`: Fetch the latest data from the remote servers. If using the GVFS protocol, download the latest set of commit and tree packs from - the cache server or the origin remote. This will not update your local + the cache server or the origin remote. Otherwise, this step will fetch + the latest objects from each remote. This will not update your local refs, so your `git fetch` commands will report all ref updates. Those `git fetch` commands will be much faster as they will require much less data transfer.