private static void ExitWithError(params string[] messages) { foreach (string message in messages) { Console.Error.WriteLine(message); } tracer.RelatedError(string.Join("\r\n", messages)); Environment.Exit(1); }
private static bool CheckLayoutVersionWasIncremented(JsonEtwTracer tracer, string enlistmentRoot, DiskLayoutUpgrade upgrade) { string error; int actualMajorVersion; int actualMinorVersion; if (!TryGetDiskLayoutVersion(tracer, enlistmentRoot, out actualMajorVersion, out actualMinorVersion, out error)) { tracer.RelatedError(error); return(false); } int expectedMajorVersion = upgrade.IsMajorUpgrade ? upgrade.SourceMajorVersion + 1 : upgrade.SourceMajorVersion; int expectedMinorVersion = upgrade.IsMajorUpgrade ? 0 : upgrade.SourceMinorVersion + 1; if (actualMajorVersion != expectedMajorVersion || actualMinorVersion != expectedMinorVersion) { throw new InvalidDataException(string.Format( "Disk layout upgrade did not increment layout version. Expected: {0}.{1}, Actual: {2}.{3}", expectedMajorVersion, expectedMinorVersion, actualMajorVersion, actualMinorVersion)); } return(true); }
private Result TryClone(JsonEtwTracer tracer, GVFSEnlistment enlistment) { this.CheckGitVersion(enlistment); Result pipeResult; using (NamedPipeServer pipeServer = this.StartNamedPipe(enlistment, out pipeResult)) { if (!pipeResult.Success) { return(pipeResult); } HttpGitObjects httpGitObjects = new HttpGitObjects(tracer, enlistment, Environment.ProcessorCount); this.ValidateGVFSVersion(enlistment, httpGitObjects, tracer); GitRefs refs = httpGitObjects.QueryInfoRefs(this.SingleBranch ? this.Branch : null); if (refs == null) { return(new Result("Could not query info/refs from: " + Uri.EscapeUriString(enlistment.RepoUrl))); } if (this.Branch == null) { this.Branch = refs.GetDefaultBranch(); EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Informational, "CloneDefaultRemoteBranch", metadata); } else { if (!refs.HasBranch(this.Branch)) { EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Warning, "CloneBranchDoesNotExist", metadata); string errorMessage = string.Format("Remote branch {0} not found in upstream origin", this.Branch); return(new Result(errorMessage)); } } if (!enlistment.TryCreateEnlistmentFolders()) { string error = "Could not create enlistment directory"; tracer.RelatedError(error); return(new Result(error)); } this.CheckAntiVirusExclusion(enlistment); CloneHelper cloneHelper = new CloneHelper(tracer, enlistment, httpGitObjects); return(cloneHelper.CreateClone(refs, this.Branch)); } }
private Result TryClone(JsonEtwTracer tracer, GVFSEnlistment enlistment, CacheServerInfo cacheServer, RetryConfig retryConfig) { Result pipeResult; using (NamedPipeServer pipeServer = this.StartNamedPipe(tracer, enlistment, out pipeResult)) { if (!pipeResult.Success) { return(pipeResult); } using (GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig)) { GitRefs refs = objectRequestor.QueryInfoRefs(this.SingleBranch ? this.Branch : null); if (refs == null) { return(new Result("Could not query info/refs from: " + Uri.EscapeUriString(enlistment.RepoUrl))); } if (this.Branch == null) { this.Branch = refs.GetDefaultBranch(); EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Informational, "CloneDefaultRemoteBranch", metadata); } else { if (!refs.HasBranch(this.Branch)) { EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Warning, "CloneBranchDoesNotExist", metadata); string errorMessage = string.Format("Remote branch {0} not found in upstream origin", this.Branch); return(new Result(errorMessage)); } } if (!enlistment.TryCreateEnlistmentFolders()) { string error = "Could not create enlistment directory"; tracer.RelatedError(error); return(new Result(error)); } CloneHelper cloneHelper = new CloneHelper(tracer, enlistment, objectRequestor); return(cloneHelper.CreateClone(refs, this.Branch)); } } }
public void Execute() { GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath); EventLevel verbosity; Keywords keywords; this.ParseEnumArgs(out verbosity, out keywords); JsonEtwTracer tracer = this.CreateTracer(enlistment, verbosity, keywords); CacheServerInfo cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cacheServer.Url, enlistment.GitObjectsRoot, new EventMetadata { { "IsElevated", ProcessHelper.IsAdminElevated() }, }); AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) => { this.UnhandledGVFSExceptionHandler(tracer, sender, e); }; RetryConfig retryConfig; string error; if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error)) { this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error); } InProcessMount mountHelper = new InProcessMount(tracer, enlistment, cacheServer, retryConfig, this.ShowDebugWindow); try { mountHelper.Mount(verbosity, keywords); } catch (Exception ex) { tracer.RelatedError("Failed to mount: {0}", ex.ToString()); this.ReportErrorAndExit("Failed to mount: {0}", ex.Message); } }
private static bool TryFindUpgrade(JsonEtwTracer tracer, string enlistmentRoot, out DiskLayoutUpgrade upgrade) { int majorVersion; int minorVersion; string error; if (!TryGetDiskLayoutVersion(tracer, enlistmentRoot, out majorVersion, out minorVersion, out error)) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedError(error); upgrade = null; return(false); } Dictionary <int, DiskLayoutUpgrade.MinorUpgrade> minorVersionUpgradesForCurrentMajorVersion; if (MinorVersionUpgrades.TryGetValue(majorVersion, out minorVersionUpgradesForCurrentMajorVersion)) { DiskLayoutUpgrade.MinorUpgrade minorUpgrade; if (minorVersionUpgradesForCurrentMajorVersion.TryGetValue(minorVersion, out minorUpgrade)) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedInfo( "Upgrading from disk layout {0}.{1} to {0}.{2}", majorVersion, minorVersion, minorVersion + 1); upgrade = minorUpgrade; return(true); } } DiskLayoutUpgrade.MajorUpgrade majorUpgrade; if (MajorVersionUpgrades.TryGetValue(majorVersion, out majorUpgrade)) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedInfo("Upgrading from disk layout {0} to {1}", majorVersion, majorVersion + 1); upgrade = majorUpgrade; return(true); } // return true to indicate that we succeeded, and no upgrader was found upgrade = null; return(true); }
public void Execute() { GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath); EventLevel verbosity; Keywords keywords; this.ParseEnumArgs(out verbosity, out keywords); JsonEtwTracer tracer = this.CreateTracer(enlistment, verbosity, keywords); RetryConfig retryConfig; string error; if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error)) { this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error); } CacheServerInfo cacheServer; if (!CacheServerInfo.TryDetermineCacheServer(null, tracer, enlistment, retryConfig, out cacheServer, out error)) { this.ReportErrorAndExit(error); } tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cacheServer.Url); InProcessMount mountHelper = new InProcessMount(tracer, enlistment, cacheServer, retryConfig, this.ShowDebugWindow); try { mountHelper.Mount(verbosity, keywords); } catch (Exception ex) { tracer.RelatedError("Failed to mount: {0}", ex.ToString()); this.ReportErrorAndExit("Failed to mount: {0}", ex.Message); } }
public static bool TryRunAllUpgrades(string enlistmentRoot) { using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "DiskLayoutUpgrade")) { try { DiskLayoutUpgrade upgrade = null; while (TryFindUpgrade(tracer, enlistmentRoot, out upgrade)) { if (upgrade == null) { return(true); } if (!upgrade.TryUpgrade(tracer, enlistmentRoot)) { return(false); } if (!CheckLayoutVersionWasIncremented(tracer, enlistmentRoot, upgrade)) { return(false); } } return(false); } catch (Exception e) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedError(e.ToString()); return(false); } finally { RepoMetadata.Shutdown(); } } }
private static bool TryFindUpgrade(JsonEtwTracer tracer, string enlistmentRoot, out DiskLayoutUpgrade upgrade) { int version; string error; if (!TryGetDiskLayoutVersion(tracer, enlistmentRoot, out version, out error)) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedError(error); upgrade = null; return(false); } if (AllUpgrades.TryGetValue(version, out upgrade)) { StartLogFile(enlistmentRoot, tracer); tracer.RelatedInfo("Upgrading from disk layout {0} to {1}", version, version + 1); return(true); } return(true); }
public override void Execute() { int exitCode = 0; this.CheckGVFltRunning(); this.CheckNotInsideExistingRepo(); string fullPath = GVFSEnlistment.ToFullPath(this.EnlistmentRootPath, this.GetDefaultEnlistmentRoot()); if (fullPath == null) { this.ReportErrorAndExit("Unable to write to directory " + this.EnlistmentRootPath); } this.EnlistmentRootPath = fullPath; this.CacheServerUrl = Enlistment.StripObjectsEndpointSuffix(this.CacheServerUrl); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, enlistment.CacheServerUrl, new EventMetadata { { "Branch", this.Branch }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch } }); this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Cache Server: " + (enlistment.CacheServerUrl == enlistment.RepoUrl ? "None" : enlistment.CacheServerUrl)); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment); return(cloneResult.Success); }, "Cloning"); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { PrefetchVerb prefetch = new PrefetchVerb(); prefetch.EnlistmentRootPath = this.EnlistmentRootPath; prefetch.Commits = true; prefetch.Execute(); } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { MountVerb mount = new MountVerb(); mount.EnlistmentRootPath = this.EnlistmentRootPath; mount.SkipMountedCheck = true; mount.SkipVersionCheck = true; mount.ServiceName = this.ServiceName; mount.Execute(); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString()); } Environment.Exit(exitCode); }
public override void Execute() { int exitCode = 0; this.EnlistmentRootPath = this.GetCloneRoot(); this.CheckGVFltHealthy(); this.CheckNotInsideExistingRepo(); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); string authErrorMessage = null; if (!this.ShowStatusWhileRunning( () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage), "Authenticating")) { this.ReportErrorAndExit("Unable to clone because authentication failed"); } RetryConfig retryConfig; string error; if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error)) { this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error); } retryConfig.Timeout = TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes); GVFSConfig gvfsConfig; CacheServerInfo cacheServer; using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig)) { gvfsConfig = configRequestor.QueryGVFSConfig(); } if (!CacheServerInfo.TryDetermineCacheServer(this.CacheServerUrl, enlistment, gvfsConfig.CacheServers, out cacheServer, out error)) { this.ReportErrorAndExit(error); } tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cacheServer.Url, new EventMetadata { { "Branch", this.Branch }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch } }); this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Cache Server: " + cacheServer); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); this.ValidateClientVersions(tracer, enlistment, gvfsConfig); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig); return(cloneResult.Success); }, "Cloning"); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { PrefetchVerb prefetch = new PrefetchVerb(); prefetch.EnlistmentRootPath = this.EnlistmentRootPath; prefetch.Commits = true; prefetch.Execute(); } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { MountVerb mount = new MountVerb(); mount.EnlistmentRootPath = this.EnlistmentRootPath; mount.SkipMountedCheck = true; mount.SkipVersionCheck = true; mount.ServiceName = this.ServiceName; mount.Execute(); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString()); } Environment.Exit(exitCode); }
protected override void Execute(GVFSEnlistment enlistment) { using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Prefetch")) { if (this.Verbose) { tracer.AddDiagnosticConsoleEventListener(EventLevel.Informational, Keywords.Any); } string cacheServerUrl = CacheServerResolver.GetUrlFromConfig(enlistment); tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Prefetch), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cacheServerUrl); RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); CacheServerInfo cacheServer = this.ResolvedCacheServer; GVFSConfig gvfsConfig = this.GVFSConfig; if (!this.SkipVersionCheck) { string authErrorMessage; if (!this.ShowStatusWhileRunning( () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage), "Authenticating")) { this.ReportErrorAndExit(tracer, "Unable to prefetch because authentication failed"); } if (gvfsConfig == null) { gvfsConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); } if (cacheServer == null) { CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ResolveNameFromRemote(cacheServerUrl, gvfsConfig); } this.ValidateClientVersions(tracer, enlistment, gvfsConfig, showWarnings: false); this.Output.WriteLine("Configured cache server: " + cacheServer); } this.InitializeLocalCacheAndObjectsPaths(tracer, enlistment, retryConfig, gvfsConfig, cacheServer); try { EventMetadata metadata = new EventMetadata(); metadata.Add("Commits", this.Commits); metadata.Add("Files", this.Files); metadata.Add("Folders", this.Folders); metadata.Add("FoldersListFile", this.FoldersListFile); metadata.Add("HydrateFiles", this.HydrateFiles); tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata); GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig); if (this.Commits) { if (!string.IsNullOrWhiteSpace(this.Files) || !string.IsNullOrWhiteSpace(this.Folders) || !string.IsNullOrWhiteSpace(this.FoldersListFile)) { this.ReportErrorAndExit(tracer, "You cannot prefetch commits and blobs at the same time."); } if (this.HydrateFiles) { this.ReportErrorAndExit(tracer, "You can only specify --hydrate with --files or --folders"); } PhysicalFileSystem fileSystem = new PhysicalFileSystem(); using (FileBasedLock prefetchLock = new FileBasedLock( fileSystem, tracer, Path.Combine(enlistment.GitPackRoot, PrefetchCommitsAndTreesLock), enlistment.EnlistmentRoot, cleanupStaleLock: false, overwriteExistingLock: true)) { this.WaitUntilLockIsAcquired(tracer, prefetchLock); this.PrefetchCommits(tracer, enlistment, objectRequestor, cacheServer); } } else { this.PrefetchBlobs(tracer, enlistment, objectRequestor, cacheServer); } } catch (VerbAbortedException) { throw; } catch (AggregateException aggregateException) { this.Output.WriteLine( "Cannot prefetch {0}. " + ConsoleHelper.GetGVFSLogMessage(enlistment.EnlistmentRoot), enlistment.EnlistmentRoot); foreach (Exception innerException in aggregateException.Flatten().InnerExceptions) { tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "Exception", innerException.ToString() } }, $"Unhandled {innerException.GetType().Name}: {innerException.Message}"); } Environment.ExitCode = (int)ReturnCode.GenericError; } catch (Exception e) { this.Output.WriteLine( "Cannot prefetch {0}. " + ConsoleHelper.GetGVFSLogMessage(enlistment.EnlistmentRoot), enlistment.EnlistmentRoot); tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "Exception", e.ToString() } }, $"Unhandled {e.GetType().Name}: {e.Message}"); Environment.ExitCode = (int)ReturnCode.GenericError; } } }
public override void Execute() { int exitCode = 0; this.EnlistmentRootPath = this.GetCloneRoot(); this.CheckGVFltHealthy(); this.CheckNotInsideExistingRepo(); this.BlockEmptyCacheServerUrl(this.CacheServerUrl); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); CacheServerInfo cacheServer = null; using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, this.CacheServerUrl, enlistment.GitObjectsRoot, new EventMetadata { { "Branch", this.Branch }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch }, { "Unattended", this.Unattended }, { "IsElevated", ProcessHelper.IsAdminElevated() }, }); CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Cache Server: " + cacheServer); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); string authErrorMessage = null; if (!this.ShowStatusWhileRunning( () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage), "Authenticating")) { this.ReportErrorAndExit(tracer, "Unable to clone because authentication failed"); } RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); GVFSConfig gvfsConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); cacheServer = this.ResolveCacheServerUrlIfNeeded(tracer, cacheServer, cacheServerResolver, gvfsConfig); this.ValidateClientVersions(tracer, enlistment, gvfsConfig, showWarnings: true); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig); return(cloneResult.Success); }, "Cloning"); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { this.Execute <PrefetchVerb>( this.EnlistmentRootPath, verb => { verb.Commits = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; }); } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { this.Execute <MountVerb>( this.EnlistmentRootPath, verb => { verb.SkipMountedCheck = true; verb.SkipVersionCheck = true; }); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString()); } Environment.Exit(exitCode); }
public void Execute() { // CmdParser doesn't strip quotes, and Path.Combine will throw this.GitBinPath = this.GitBinPath.Replace("\"", string.Empty); if (!GitProcess.GitExists(this.GitBinPath)) { Console.WriteLine( "Could not find git.exe {0}", !string.IsNullOrWhiteSpace(this.GitBinPath) ? "at " + this.GitBinPath : "on %PATH%"); return; } if (this.Commit != null && this.Branch != null) { Console.WriteLine("Cannot specify both a commit sha and a branch name to checkout."); return; } this.CacheServerUrl = Enlistment.StripObjectsEndpointSuffix(this.CacheServerUrl); this.SearchThreadCount = this.SearchThreadCount > 0 ? this.SearchThreadCount : Environment.ProcessorCount; this.DownloadThreadCount = this.DownloadThreadCount > 0 ? this.DownloadThreadCount : Environment.ProcessorCount; this.IndexThreadCount = this.IndexThreadCount > 0 ? this.IndexThreadCount : Environment.ProcessorCount; this.CheckoutThreadCount = this.CheckoutThreadCount > 0 ? this.CheckoutThreadCount : Environment.ProcessorCount; this.GitBinPath = !string.IsNullOrWhiteSpace(this.GitBinPath) ? this.GitBinPath : GitProcess.GetInstalledGitBinPath(); Enlistment enlistment = (Enlistment)GVFSEnlistment.CreateFromCurrentDirectory(this.CacheServerUrl, this.GitBinPath) ?? GitEnlistment.CreateFromCurrentDirectory(this.CacheServerUrl, this.GitBinPath); if (enlistment == null) { Console.WriteLine("Must be run within a .git repo or GVFS enlistment"); return; } string commitish = this.Commit ?? this.Branch ?? DefaultBranch; EventLevel maxVerbosity = this.Silent ? EventLevel.LogAlways : EventLevel.Informational; using (JsonEtwTracer tracer = new JsonEtwTracer("Microsoft.Git.FastFetch", "FastFetch")) { tracer.AddConsoleEventListener(maxVerbosity, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, enlistment.CacheServerUrl, new EventMetadata { { "TargetCommitish", commitish }, }); FetchHelper fetchHelper = this.GetFetchHelper(tracer, enlistment); fetchHelper.MaxRetries = this.MaxRetries; if (!FetchHelper.TryLoadPathWhitelist(this.PathWhitelist, this.PathWhitelistFile, tracer, fetchHelper.PathWhitelist)) { Environment.ExitCode = 1; return; } try { bool isBranch = this.Commit == null; fetchHelper.FastFetch(commitish, isBranch); if (fetchHelper.HasFailures) { Environment.ExitCode = 1; } } catch (AggregateException e) { Environment.ExitCode = 1; foreach (Exception ex in e.Flatten().InnerExceptions) { tracer.RelatedError(ex.ToString()); } } catch (Exception e) { Environment.ExitCode = 1; tracer.RelatedError(e.ToString()); } EventMetadata stopMetadata = new EventMetadata(); stopMetadata.Add("Success", Environment.ExitCode == 0); tracer.Stop(stopMetadata); } if (Debugger.IsAttached) { Console.ReadKey(); } }
protected override void Execute(GVFSEnlistment enlistment) { using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Prefetch")) { if (this.Verbose) { tracer.AddDiagnosticConsoleEventListener(EventLevel.Informational, Keywords.Any); } else { tracer.AddPrettyConsoleEventListener(EventLevel.Error, Keywords.Any); } tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Prefetch), EventLevel.Informational, Keywords.Any); RetryConfig retryConfig; string error; if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error)) { tracer.RelatedError("Failed to determine GVFS timeout and max retries: " + error); Environment.Exit((int)ReturnCode.GenericError); } retryConfig.Timeout = TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes); CacheServerInfo cache; if (!CacheServerInfo.TryDetermineCacheServer(null, tracer, enlistment, retryConfig, out cache, out error)) { tracer.RelatedError(error); Environment.ExitCode = (int)ReturnCode.GenericError; return; } tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cache.Url); try { EventMetadata metadata = new EventMetadata(); metadata.Add("Commits", this.Commits); metadata.Add("PathWhitelist", this.PathWhitelist); metadata.Add("PathWhitelistFile", this.PathWhitelistFile); tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata); GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cache, retryConfig); if (this.Commits) { this.PrefetchCommits(tracer, enlistment, objectRequestor); } else { this.PrefetchBlobs(tracer, enlistment, objectRequestor); } } catch (VerbAbortedException) { throw; } catch (AggregateException aggregateException) { this.Output.WriteLine( "Cannot prefetch {0}. " + ConsoleHelper.GetGVFSLogMessage(enlistment.EnlistmentRoot), enlistment.EnlistmentRoot); foreach (Exception innerException in aggregateException.Flatten().InnerExceptions) { tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "ErrorMessage", $"Unhandled {innerException.GetType().Name}: {innerException.Message}" }, { "Exception", innerException.ToString() } }); } Environment.ExitCode = (int)ReturnCode.GenericError; } catch (Exception e) { this.Output.WriteLine( "Cannot prefetch {0}. " + ConsoleHelper.GetGVFSLogMessage(enlistment.EnlistmentRoot), enlistment.EnlistmentRoot); tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "ErrorMessage", $"Unhandled {e.GetType().Name}: {e.Message}" }, { "Exception", e.ToString() } }); } } }
protected override void Execute(GVFSEnlistment enlistment) { using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Prefetch")) { if (this.Verbose) { tracer.AddDiagnosticConsoleEventListener(EventLevel.Informational, Keywords.Any); } else { tracer.AddPrettyConsoleEventListener(EventLevel.Error, Keywords.Any); } tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Prefetch), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, enlistment.CacheServerUrl); try { EventMetadata metadata = new EventMetadata(); metadata.Add("Commits", this.Commits); metadata.Add("PathWhitelist", this.PathWhitelist); metadata.Add("PathWhitelistFile", this.PathWhitelistFile); tracer.RelatedEvent(EventLevel.Informational, "PerformPrefetch", metadata); if (this.Commits) { if (!string.IsNullOrEmpty(this.PathWhitelistFile) || !string.IsNullOrWhiteSpace(this.PathWhitelist)) { this.ReportErrorAndExit("Cannot supply both --commits (-c) and --folders (-f)"); } PrefetchHelper prefetchHelper = new PrefetchHelper( tracer, enlistment, DownloadThreadCount); if (this.Verbose) { prefetchHelper.TryPrefetchCommitsAndTrees(); } else { this.ShowStatusWhileRunning( () => { return(prefetchHelper.TryPrefetchCommitsAndTrees()); }, "Fetching commits and trees"); } return; } FetchHelper fetchHelper = new FetchHelper( tracer, enlistment, ChunkSize, SearchThreadCount, DownloadThreadCount, IndexThreadCount); if (!FetchHelper.TryLoadPathWhitelist(tracer, this.PathWhitelist, this.PathWhitelistFile, enlistment, fetchHelper.PathWhitelist)) { Environment.ExitCode = (int)ReturnCode.GenericError; return; } GitProcess gitProcess = new GitProcess(enlistment); GitProcess.Result result = gitProcess.RevParse(GVFSConstants.HeadCommitName); if (result.HasErrors) { tracer.RelatedError(result.Errors); this.Output.WriteLine(result.Errors); Environment.ExitCode = (int)ReturnCode.GenericError; return; } string headCommitId = result.Output; Func <bool> doPrefetch = () => { try { fetchHelper.FastFetch(headCommitId.Trim(), isBranch: false); return(!fetchHelper.HasFailures); } catch (FetchHelper.FetchException e) { tracer.RelatedError(e.Message); return(false); } }; if (this.Verbose) { doPrefetch(); } else { this.ShowStatusWhileRunning(doPrefetch, "Fetching blobs"); } if (fetchHelper.HasFailures) { Environment.ExitCode = 1; } } catch (AggregateException aggregateException) { this.Output.WriteLine("Cannot prefetch @ {0}:", enlistment.EnlistmentRoot); foreach (Exception innerException in aggregateException.Flatten().InnerExceptions) { tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "ErrorMessage", $"Unhandled {innerException.GetType().Name}: {innerException.Message}" }, { "Exception", innerException.ToString() } }); } Environment.ExitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.Output.WriteLine("Cannot prefetch @ {0}:", enlistment.EnlistmentRoot); tracer.RelatedError( new EventMetadata { { "Verb", typeof(PrefetchVerb).Name }, { "ErrorMessage", $"Unhandled {e.GetType().Name}: {e.Message}" }, { "Exception", e.ToString() } }); } } }
private Result TryClone(JsonEtwTracer tracer, GVFSEnlistment enlistment) { this.CheckVolumeSupportsDeleteNotifications(tracer, enlistment); this.CheckGitVersion(enlistment); Result pipeResult; using (NamedPipeServer pipeServer = this.StartNamedPipe(enlistment, out pipeResult)) { if (!pipeResult.Success) { return(pipeResult); } using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment)) { GVFSConfig config = configRequestor.QueryGVFSConfig(); this.ValidateGVFSVersion(enlistment, config, tracer); } using (GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, Environment.ProcessorCount)) { GitRefs refs = objectRequestor.QueryInfoRefs(this.SingleBranch ? this.Branch : null); if (refs == null) { return(new Result("Could not query info/refs from: " + Uri.EscapeUriString(enlistment.RepoUrl))); } if (this.Branch == null) { this.Branch = refs.GetDefaultBranch(); EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Informational, "CloneDefaultRemoteBranch", metadata); } else { if (!refs.HasBranch(this.Branch)) { EventMetadata metadata = new EventMetadata(); metadata.Add("Branch", this.Branch); tracer.RelatedEvent(EventLevel.Warning, "CloneBranchDoesNotExist", metadata); string errorMessage = string.Format("Remote branch {0} not found in upstream origin", this.Branch); return(new Result(errorMessage)); } } if (!enlistment.TryCreateEnlistmentFolders()) { string error = "Could not create enlistment directory"; tracer.RelatedError(error); return(new Result(error)); } // Only check Defender exclusions if not mounting, otherwise let mount take care of it. if (this.NoMount) { this.CheckAntiVirusExclusion(enlistment); } CloneHelper cloneHelper = new CloneHelper(tracer, enlistment, objectRequestor); return(cloneHelper.CreateClone(refs, this.Branch)); } } }
private int ExecuteWithExitCode() { // CmdParser doesn't strip quotes, and Path.Combine will throw this.GitBinPath = this.GitBinPath.Replace("\"", string.Empty); if (!GitProcess.GitExists(this.GitBinPath)) { Console.WriteLine( "Could not find git.exe {0}", !string.IsNullOrWhiteSpace(this.GitBinPath) ? "at " + this.GitBinPath : "on %PATH%"); return(ExitFailure); } if (this.Commit != null && this.Branch != null) { Console.WriteLine("Cannot specify both a commit sha and a branch name."); return(ExitFailure); } this.SearchThreadCount = this.SearchThreadCount > 0 ? this.SearchThreadCount : Environment.ProcessorCount; this.DownloadThreadCount = this.DownloadThreadCount > 0 ? this.DownloadThreadCount : Math.Min(Environment.ProcessorCount, MaxDefaultDownloadThreads); this.IndexThreadCount = this.IndexThreadCount > 0 ? this.IndexThreadCount : Environment.ProcessorCount; this.CheckoutThreadCount = this.CheckoutThreadCount > 0 ? this.CheckoutThreadCount : Environment.ProcessorCount; this.GitBinPath = !string.IsNullOrWhiteSpace(this.GitBinPath) ? this.GitBinPath : GitProcess.GetInstalledGitBinPath(); GitEnlistment enlistment = GitEnlistment.CreateFromCurrentDirectory(this.GitBinPath); if (enlistment == null) { Console.WriteLine("Must be run within a git repo"); return(ExitFailure); } string commitish = this.Commit ?? this.Branch; if (string.IsNullOrWhiteSpace(commitish)) { GitProcess.Result result = new GitProcess(enlistment).GetCurrentBranchName(); if (result.HasErrors || string.IsNullOrWhiteSpace(result.Output)) { Console.WriteLine("Could not retrieve current branch name: " + result.Errors); return(ExitFailure); } commitish = result.Output.Trim(); } Guid parentActivityId = Guid.Empty; if (!string.IsNullOrWhiteSpace(this.ParentActivityId) && !Guid.TryParse(this.ParentActivityId, out parentActivityId)) { Console.WriteLine("The ParentActivityId provided (" + this.ParentActivityId + ") is not a valid GUID."); } using (JsonEtwTracer tracer = new JsonEtwTracer("Microsoft.Git.FastFetch", parentActivityId, "FastFetch", useCriticalTelemetryFlag: false)) { if (this.Verbose) { tracer.AddDiagnosticConsoleEventListener(EventLevel.Informational, Keywords.Any); } else { tracer.AddPrettyConsoleEventListener(EventLevel.Error, Keywords.Any); } string fastfetchLogFile = Enlistment.GetNewLogFileName(enlistment.FastFetchLogRoot, "fastfetch"); tracer.AddLogFileEventListener(fastfetchLogFile, EventLevel.Informational, Keywords.Any); CacheServerInfo cacheServer = new CacheServerInfo(this.GetRemoteUrl(enlistment), null); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, cacheServer.Url, new EventMetadata { { "TargetCommitish", commitish }, { "Checkout", this.Checkout }, }); RetryConfig retryConfig = new RetryConfig(this.MaxAttempts, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); FetchHelper fetchHelper = this.GetFetchHelper(tracer, enlistment, cacheServer, retryConfig); string error; if (!FetchHelper.TryLoadFolderList(enlistment, this.FolderList, this.FolderListFile, fetchHelper.FolderList, out error)) { tracer.RelatedError(error); Console.WriteLine(error); return(ExitFailure); } bool isSuccess; try { Func <bool> doPrefetch = () => { try { bool isBranch = this.Commit == null; fetchHelper.FastFetch(commitish, isBranch); return(!fetchHelper.HasFailures); } catch (FetchHelper.FetchException e) { tracer.RelatedError(e.Message); return(false); } }; if (this.Verbose) { isSuccess = doPrefetch(); } else { isSuccess = ConsoleHelper.ShowStatusWhileRunning( doPrefetch, "Fetching", output: Console.Out, showSpinner: !Console.IsOutputRedirected, gvfsLogEnlistmentRoot: null); Console.WriteLine(); Console.WriteLine("See the full log at " + fastfetchLogFile); } isSuccess &= !fetchHelper.HasFailures; } catch (AggregateException e) { isSuccess = false; foreach (Exception ex in e.Flatten().InnerExceptions) { tracer.RelatedError(ex.ToString()); } } catch (Exception e) { isSuccess = false; tracer.RelatedError(e.ToString()); } EventMetadata stopMetadata = new EventMetadata(); stopMetadata.Add("Success", isSuccess); tracer.Stop(stopMetadata); return(isSuccess ? ExitSuccess : ExitFailure); } }
public override void Execute() { int exitCode = 0; this.ValidatePathParameter(this.EnlistmentRootPath); this.ValidatePathParameter(this.LocalCacheRoot); this.EnlistmentRootPath = this.GetCloneRoot(); if (!string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (Path.GetFullPath(this.LocalCacheRoot).StartsWith( Path.Combine(this.EnlistmentRootPath, GVFSConstants.WorkingDirectoryRootName), StringComparison.OrdinalIgnoreCase)) { this.ReportErrorAndExit("'--local-cache-path' cannot be inside the src folder"); } } this.CheckNTFSVolume(); this.CheckNotInsideExistingRepo(); this.BlockEmptyCacheServerUrl(this.CacheServerUrl); try { GVFSEnlistment enlistment; Result cloneResult = new Result(false); CacheServerInfo cacheServer = null; GVFSConfig gvfsConfig = null; using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone")) { cloneResult = this.TryCreateEnlistment(out enlistment); if (cloneResult.Success) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone), EventLevel.Informational, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, this.CacheServerUrl, new EventMetadata { { "Branch", this.Branch }, { "LocalCacheRoot", this.LocalCacheRoot }, { "SingleBranch", this.SingleBranch }, { "NoMount", this.NoMount }, { "NoPrefetch", this.NoPrefetch }, { "Unattended", this.Unattended }, { "IsElevated", ProcessHelper.IsAdminElevated() }, }); CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment); cacheServer = cacheServerResolver.ParseUrlOrFriendlyName(this.CacheServerUrl); string error; string resolvedLocalCacheRoot; if (string.IsNullOrWhiteSpace(this.LocalCacheRoot)) { if (!LocalCacheResolver.TryGetDefaultLocalCacheRoot(enlistment, out resolvedLocalCacheRoot, out error)) { this.ReportErrorAndExit(tracer, "Cannot clone, error determining local cache path: " + error); } } else { resolvedLocalCacheRoot = Path.GetFullPath(this.LocalCacheRoot); } this.Output.WriteLine("Clone parameters:"); this.Output.WriteLine(" Repo URL: " + enlistment.RepoUrl); this.Output.WriteLine(" Branch: " + (string.IsNullOrWhiteSpace(this.Branch) ? "Default" : this.Branch)); this.Output.WriteLine(" Cache Server: " + cacheServer); this.Output.WriteLine(" Local Cache: " + resolvedLocalCacheRoot); this.Output.WriteLine(" Destination: " + enlistment.EnlistmentRoot); string authErrorMessage = null; if (!this.ShowStatusWhileRunning( () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage), "Authenticating")) { this.ReportErrorAndExit(tracer, "Cannot clone because authentication failed"); } RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes)); gvfsConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig); cacheServer = this.ResolveCacheServer(tracer, cacheServer, cacheServerResolver, gvfsConfig); this.ValidateClientVersions(tracer, enlistment, gvfsConfig, showWarnings: true); this.ShowStatusWhileRunning( () => { cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig, gvfsConfig, resolvedLocalCacheRoot); return(cloneResult.Success); }, "Cloning"); } if (!cloneResult.Success) { tracer.RelatedError(cloneResult.ErrorMessage); } } if (cloneResult.Success) { if (!this.NoPrefetch) { ReturnCode result = this.Execute <PrefetchVerb>( this.EnlistmentRootPath, verb => { verb.Commits = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.GVFSConfig = gvfsConfig; }); if (result != ReturnCode.Success) { this.Output.WriteLine("\r\nError during prefetch @ {0}", this.EnlistmentRootPath); exitCode = (int)result; } } if (this.NoMount) { this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: "); this.Output.WriteLine("gvfs mount"); } else { this.Execute <MountVerb>( this.EnlistmentRootPath, verb => { verb.SkipMountedCheck = true; verb.SkipVersionCheck = true; verb.ResolvedCacheServer = cacheServer; verb.DownloadedGVFSConfig = gvfsConfig; }); } } else { this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath); this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage); exitCode = (int)ReturnCode.GenericError; } } catch (AggregateException e) { this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath); foreach (Exception ex in e.Flatten().InnerExceptions) { this.Output.WriteLine("Exception: {0}", ex.ToString()); } exitCode = (int)ReturnCode.GenericError; } catch (VerbAbortedException) { throw; } catch (Exception e) { this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString()); } Environment.Exit(exitCode); }