refactor(git-provider): move IsGitRepo to GitManager, refactor NewGitRepoCommand

This commit is contained in:
Scott 2026-08-25 08:41:29 +10:00
commit cf446fc5dc
2 changed files with 91 additions and 82 deletions

View file

@ -145,6 +145,73 @@ public class GitManager
throw new Exception($"No git repo has been registered with the name {registeredName}");
}
/// <summary>
/// Returns the git root directory for any nested directory if git rev-parse --show-toplevel returns a value.
/// </summary>
/// <param name="path">Path to check if it or any of its parents contain a git repository</param>
/// <returns></returns>
/// <exception cref="Exception">
/// Git fails to start, returns an error (ie: the directory is not in a git repo), or the git process does not return
/// any output or error.
/// </exception>
public static ParsedGitFolderDetails IsGitRepo(string path)
{
_debugWriterDelegate?.Invoke("Checking if current directory is a git repository...");
var ps = new ProcessStartInfo("git",
["-C", path, "rev-parse", "--show-toplevel"])
{
RedirectStandardOutput = true,
RedirectStandardError = true,
};
// If the user doesn't have git on their path, this will throw an exception that I don't have to do anything
// special with, it'll be unhandled and powershell will handle it
var gitProcess = Process.Start(ps);
// This probably shouldn't be possible? Not really sure of the conditions where the process could be started
// but return null, but I'm going to consider that unrecoverable error territory
if (gitProcess is null)
{
throw new Exception("git failed to start")
{
Source = "git-process",
};
}
gitProcess.WaitForExit();
if (!gitProcess.StandardOutput.EndOfStream)
{
var directory = gitProcess.StandardOutput.ReadToEnd();
// Gotta trim what we get as it might already have a newline character at the end
var dirInfo = new DirectoryInfo(directory.Trim());
_debugWriterDelegate?.Invoke("...location is a git repo (duh).");
var repoFolderInfo = new ParsedGitFolderDetails
{
Directory = dirInfo.FullName,
Folder = dirInfo.Name,
};
return repoFolderInfo;
}
if (!gitProcess.StandardError.EndOfStream)
{
throw new Exception(gitProcess.StandardError.ReadToEnd())
{
Source = "git-not-found",
};
}
throw new Exception("Unable to determine if directory is repository: git command returned no output or errors.")
{
Source = "git-parse-failed",
};
}
/// <summary>
/// Registers an output for debug output. <see cref="ClearDebugWriter" /> should be called as soon as the need for output
/// is no longer needed.
@ -234,4 +301,20 @@ public class GitManager
return _currentBranch.Trim();
}
}
}
/// <summary>
/// The directory details of the directory returned from git rev-parse --show-toplevel
/// </summary>
public class ParsedGitFolderDetails
{
/// <summary>
/// The full path to the top level folder containing a git repository
/// </summary>
public string Directory { get; init; } = null!;
/// <summary>
/// The last folder name of the directory
/// </summary>
public string Folder { get; init; } = null!;
}