private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, ProcessHelper.GetCurrentProcessLocation(), authentication: null); if (enlistment == null) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment", enlistmentRootPath); } } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); return(GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath)); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.GetProgramLocation(GVFSPlatform.Instance.Constants.ProgramLocaterCommand, GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); return(GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath, authentication: null)); }
private bool IsValidRepo(string repoRoot) { WindowsGitInstallation windowsGitInstallation = new WindowsGitInstallation(); string gitBinPath = windowsGitInstallation.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath, authentication: null); } catch (InvalidRepoException e) { EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(repoRoot), repoRoot); metadata.Add(nameof(gitBinPath), gitBinPath); metadata.Add(nameof(hooksPath), hooksPath); metadata.Add("Exception", e.ToString()); this.tracer.RelatedInfo(metadata, $"{nameof(this.IsValidRepo)}: Found invalid repo"); return(false); } return(true); }
protected bool TrySetGitConfig(ITracer tracer, string enlistmentRoot, Dictionary <string, string> configSettings) { GVFSEnlistment enlistment; try { enlistment = GVFSEnlistment.CreateFromDirectory( enlistmentRoot, GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(), authentication: null); } catch (InvalidRepoException e) { EventMetadata metadata = new EventMetadata(); metadata.Add("Exception", e.ToString()); metadata.Add(nameof(enlistmentRoot), enlistmentRoot); tracer.RelatedError(metadata, $"{nameof(this.TrySetGitConfig)}: Failed to create GVFSEnlistment from directory"); return(false); } GitProcess git = enlistment.CreateGitProcess(); foreach (string key in configSettings.Keys) { GitProcess.Result result = git.SetInLocalConfig(key, configSettings[key]); if (result.ExitCodeIsFailure) { tracer.RelatedError("Could not set git config setting {0}. Error: {1}", key, result.Errors); return(false); } } return(true); }
private bool IsValidRepo(string repoRoot) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); string hooksVersion = null; string error = null; if (GVFSPlatform.Instance.TryGetGVFSHooksVersion(out hooksVersion, out error)) { try { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( repoRoot, gitBinPath, authentication: null); } catch (InvalidRepoException e) { EventMetadata metadata = new EventMetadata(); metadata.Add(nameof(repoRoot), repoRoot); metadata.Add(nameof(gitBinPath), gitBinPath); metadata.Add("Exception", e.ToString()); this.tracer.RelatedInfo(metadata, $"{nameof(this.IsValidRepo)}: Found invalid repo"); return(false); } } else { this.tracer.RelatedError($"{nameof(this.IsValidRepo)}: {nameof(GVFSPlatform.Instance.TryGetGVFSHooksVersion)} failed. {error}"); return(false); } return(true); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath, GitAuthentication authentication) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory( enlistmentRootPath, gitBinPath, authentication, createWithoutRepoURL: !this.validateOriginURL); } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { GVFSPlatform.Register(new WindowsPlatform()); string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); return(GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath)); }
public override IssueType HasIssue(List <string> messages) { GitProcess git = new GitProcess(this.Enlistment); GitProcess.Result result = git.GetOriginUrl(); if (result.HasErrors) { if (result.Errors.Length == 0) { messages.Add("Remote 'origin' is not configured for this repo. You can fix this by running 'git remote add origin <repourl>'"); return(IssueType.CantFix); } else if (result.Errors.Contains("--local")) { // example error: '--local can only be used inside a git repository' // Corrupting the git config does not cause git to not recognize the current folder as "not a git repository". // This is a symptom of deeper issues such as missing HEAD file or refs folders. messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again."); return(IssueType.CantFix); } messages.Add("Could not read origin url: " + result.Errors); return(IssueType.Fixable); } // At this point, we've confirmed that the repo url can be gotten, so we have to // reinitialize the GitProcess with a valid repo url for 'git credential fill' string repoUrl = null; try { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( this.Enlistment.EnlistmentRoot, this.Enlistment.GitBinPath, this.Enlistment.GVFSHooksRoot); git = new GitProcess(enlistment); repoUrl = enlistment.RepoUrl; } catch (InvalidRepoException) { messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again."); return(IssueType.CantFix); } string username; string password; if (!git.TryGetCredentials(this.Tracer, repoUrl, out username, out password)) { messages.Add("Authentication failed. Run 'gvfs log' for more info."); messages.Add(".git\\config is valid and remote 'origin' is set, but may have a typo:"); messages.Add(result.Output.Trim()); return(IssueType.CantFix); } return(IssueType.None); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath, GitAuthentication authentication) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } string hooksPath = null; if (GVFSPlatform.Instance.UnderConstruction.RequiresDeprecatedGitHooksLoader) { // On Windows, the soon-to-be deprecated GitHooksLoader tries to call out to the hooks process without // its full path, so we have to pass the path along to our background git processes via the PATH // environment variable. On Mac this is not needed because we just copy our own hook directly into // the .git/hooks folder, and once Windows does the same, this hooksPath can be removed (from here // and all the classes that handle it on the way to GitProcess) hooksPath = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); if (hooksPath == null) { this.ReportErrorAndExit("Could not find " + GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); } } GVFSEnlistment enlistment = null; try { if (this.validateOriginURL) { enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath, authentication); } else { enlistment = GVFSEnlistment.CreateWithoutRepoUrlFromDirectory(enlistmentRootPath, gitBinPath, hooksPath, authentication); } if (enlistment == null) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment", enlistmentRootPath); } } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
public override IssueType HasIssue(List <string> messages) { GitProcess git = new GitProcess(this.Enlistment); GitProcess.ConfigResult originResult = git.GetOriginUrl(); string error; string originUrl; if (!originResult.TryParseAsString(out originUrl, out error)) { if (error.Contains("--local")) { // example error: '--local can only be used inside a git repository' // Corrupting the git config does not cause git to not recognize the current folder as "not a git repository". // This is a symptom of deeper issues such as missing HEAD file or refs folders. messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again."); return(IssueType.CantFix); } messages.Add("Could not read origin url: " + error); return(IssueType.Fixable); } if (originUrl == null) { messages.Add("Remote 'origin' is not configured for this repo. You can fix this by running 'git remote add origin <repourl>'"); return(IssueType.CantFix); } // We've validated the repo URL, so now make sure we can authenticate try { GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( this.Enlistment.EnlistmentRoot, this.Enlistment.GitBinPath, this.Enlistment.GVFSHooksRoot, authentication: null); string authError; if (!enlistment.Authentication.TryInitialize(this.Tracer, enlistment, out authError)) { messages.Add("Authentication failed. Run 'gvfs log' for more info."); messages.Add(".git\\config is valid and remote 'origin' is set, but may have a typo:"); messages.Add(originUrl.Trim()); return(IssueType.CantFix); } } catch (InvalidRepoException) { messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again."); return(IssueType.CantFix); } return(IssueType.None); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } string hooksPath; if (GVFSPlatform.Instance.IsUnderConstruction) { hooksPath = "hooksUnderConstruction"; } else { hooksPath = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); if (hooksPath == null) { this.ReportErrorAndExit("Could not find " + GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); } } GVFSEnlistment enlistment = null; try { if (this.validateOriginURL) { enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath); } else { enlistment = GVFSEnlistment.CreateWithoutRepoUrlFromDirectory(enlistmentRootPath, gitBinPath, hooksPath); } if (enlistment == null) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment", enlistmentRootPath); } } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); if (string.IsNullOrWhiteSpace(gitBinPath)) { this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError); } if (string.IsNullOrWhiteSpace(enlistmentRootPath)) { enlistmentRootPath = Environment.CurrentDirectory; } string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); if (hooksPath == null) { this.ReportErrorAndExit("Could not find " + GVFSConstants.GVFSHooksExecutableName); } GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, null, gitBinPath, hooksPath); if (enlistment == null) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment", enlistmentRootPath); } } catch (InvalidRepoException e) { this.ReportErrorAndExit( "Error: '{0}' is not a valid GVFS enlistment. {1}", enlistmentRootPath, e.Message); } return(enlistment); }
private bool IsValidRepo(string repoRoot) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
protected bool TrySetGitConfig(ITracer tracer, string enlistmentRoot, Dictionary <string, string> configSettings, out string errorMessage) { errorMessage = null; GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory( enlistmentRoot, GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(), ProcessHelper.GetCurrentProcessLocation()); GitProcess git = enlistment.CreateGitProcess(); foreach (string key in configSettings.Keys) { GitProcess.Result result = git.SetInLocalConfig(key, configSettings[key]); if (result.HasErrors) { tracer.RelatedError("Could not set git config setting {0}. Error: {1}", key, result.Errors); return(false); } } return(true); }
private bool IsValidRepo(string repoRoot) { string gitBinPath = GitProcess.GetInstalledGitBinPath(); string hooksPath = this.GetGVFSHooksPathAndCheckVersion(tracer: null); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
private bool IsValidRepo(string repoRoot) { WindowsGitInstallation windowsGitInstallation = new WindowsGitInstallation(); string gitBinPath = windowsGitInstallation.GetInstalledGitBinPath(); string hooksPath = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName); GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath, authentication: null); } catch (InvalidRepoException) { return(false); } if (enlistment == null) { return(false); } return(true); }
private GVFSEnlistment CreateEnlistment(string enlistmentRootPath) { string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(); return(GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, authentication: null)); }
public override void Execute() { this.ValidatePathParameter(this.EnlistmentRootPathParameter); this.CheckGVFSHooksVersion(tracer: null, hooksVersion: out _); if (!Directory.Exists(this.EnlistmentRootPathParameter)) { this.ReportErrorAndExit($"Path '{this.EnlistmentRootPathParameter}' does not exist"); } string errorMessage; string enlistmentRoot; if (!GVFSPlatform.Instance.TryGetGVFSEnlistmentRoot(this.EnlistmentRootPathParameter, out enlistmentRoot, out errorMessage)) { this.ReportErrorAndExit("'gvfs repair' must be run within a GVFS enlistment"); } GVFSEnlistment enlistment = null; try { enlistment = GVFSEnlistment.CreateFromDirectory( this.EnlistmentRootPathParameter, GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(), authentication: null, createWithoutRepoURL: true); } catch (InvalidRepoException e) { this.ReportErrorAndExit($"Failed to initialize enlistment, error: {e.Message}"); } if (!this.Confirmed) { this.Output.WriteLine( @"WARNING: THIS IS AN EXPERIMENTAL FEATURE This command detects and repairs issues that prevent a GVFS repo from mounting. A few such checks are currently implemented, and some of them can be repaired. More repairs and more checks are coming soon. Without --confirm, it will non-invasively check if repairs are necessary. To actually execute any necessary repair(s), run 'gvfs repair --confirm' "); } string error; if (!DiskLayoutUpgrade.TryCheckDiskLayoutVersion(tracer: null, enlistmentRoot: enlistment.EnlistmentRoot, error: out error)) { this.ReportErrorAndExit(error); } if (!ConsoleHelper.ShowStatusWhileRunning( () => { // Don't use 'gvfs status' here. The repo may be corrupt such that 'gvfs status' cannot run normally, // causing repair to continue when it shouldn't. using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName)) { if (!pipeClient.Connect()) { return(true); } } return(false); }, "Checking that GVFS is not mounted", this.Output, showSpinner: true, gvfsLogEnlistmentRoot: null)) { this.ReportErrorAndExit("You can only run 'gvfs repair' if GVFS is not mounted. Run 'gvfs unmount' and try again."); } this.Output.WriteLine(); using (JsonTracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "RepairVerb", enlistment.GetEnlistmentId(), mountId: null)) { tracer.AddLogFileEventListener( GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Repair), EventLevel.Verbose, Keywords.Any); tracer.WriteStartEvent( enlistment.EnlistmentRoot, enlistment.RepoUrl, "N/A", new EventMetadata { { "Confirmed", this.Confirmed }, { "IsElevated", GVFSPlatform.Instance.IsElevated() }, { "NamedPipename", enlistment.NamedPipeName }, { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter }, }); List <RepairJob> jobs = new List <RepairJob>(); // Repair databases jobs.Add(new BackgroundOperationDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new RepoMetadataDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new VFSForGitDatabaseRepairJob(tracer, this.Output, enlistment)); jobs.Add(new BlobSizeDatabaseRepairJob(tracer, this.Output, enlistment)); // Repair .git folder files jobs.Add(new GitHeadRepairJob(tracer, this.Output, enlistment)); jobs.Add(new GitIndexRepairJob(tracer, this.Output, enlistment)); jobs.Add(new GitConfigRepairJob(tracer, this.Output, enlistment)); Dictionary <RepairJob, List <string> > healthy = new Dictionary <RepairJob, List <string> >(); Dictionary <RepairJob, List <string> > cantFix = new Dictionary <RepairJob, List <string> >(); Dictionary <RepairJob, List <string> > fixable = new Dictionary <RepairJob, List <string> >(); foreach (RepairJob job in jobs) { List <string> messages = new List <string>(); switch (job.HasIssue(messages)) { case RepairJob.IssueType.None: healthy[job] = messages; break; case RepairJob.IssueType.CantFix: cantFix[job] = messages; break; case RepairJob.IssueType.Fixable: fixable[job] = messages; break; } } foreach (RepairJob job in healthy.Keys) { this.WriteMessage(tracer, string.Format("{0, -30}: Healthy", job.Name)); this.WriteMessages(tracer, healthy[job]); } if (healthy.Count > 0) { this.Output.WriteLine(); } foreach (RepairJob job in cantFix.Keys) { this.WriteMessage(tracer, job.Name); this.WriteMessages(tracer, cantFix[job]); this.Indent(); this.WriteMessage(tracer, "'gvfs repair' does not currently support fixing this problem"); this.Output.WriteLine(); } foreach (RepairJob job in fixable.Keys) { this.WriteMessage(tracer, job.Name); this.WriteMessages(tracer, fixable[job]); this.Indent(); if (this.Confirmed) { List <string> repairMessages = new List <string>(); switch (job.TryFixIssues(repairMessages)) { case RepairJob.FixResult.Success: this.WriteMessage(tracer, "Repair succeeded"); break; case RepairJob.FixResult.ManualStepsRequired: this.WriteMessage(tracer, "Repair succeeded, but requires some manual steps before remounting."); break; case RepairJob.FixResult.Failure: this.WriteMessage(tracer, "Repair failed. " + ConsoleHelper.GetGVFSLogMessage(enlistment.EnlistmentRoot)); break; } this.WriteMessages(tracer, repairMessages); } else { this.WriteMessage(tracer, "Run 'gvfs repair --confirm' to attempt a repair"); } this.Output.WriteLine(); } } }