diff --git a/src/ModuleCore/Git/GitManager.cs b/src/ModuleCore/Git/GitManager.cs
index 8b2b6f4..cfdf2d8 100644
--- a/src/ModuleCore/Git/GitManager.cs
+++ b/src/ModuleCore/Git/GitManager.cs
@@ -145,6 +145,73 @@ public class GitManager
throw new Exception($"No git repo has been registered with the name {registeredName}");
}
+ ///
+ /// Returns the git root directory for any nested directory if git rev-parse --show-toplevel returns a value.
+ ///
+ /// Path to check if it or any of its parents contain a git repository
+ ///
+ ///
+ /// 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.
+ ///
+ 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",
+ };
+ }
+
///
/// Registers an output for debug output. should be called as soon as the need for output
/// is no longer needed.
@@ -234,4 +301,20 @@ public class GitManager
return _currentBranch.Trim();
}
}
+}
+
+///
+/// The directory details of the directory returned from git rev-parse --show-toplevel
+///
+public class ParsedGitFolderDetails
+{
+ ///
+ /// The full path to the top level folder containing a git repository
+ ///
+ public string Directory { get; init; } = null!;
+
+ ///
+ /// The last folder name of the directory
+ ///
+ public string Folder { get; init; } = null!;
}
\ No newline at end of file
diff --git a/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs b/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs
index 29f629a..7204731 100644
--- a/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs
+++ b/src/PowershellModule/Git/Commands/NewGitRepoCommand.cs
@@ -17,95 +17,21 @@ public sealed class NewGitRepoCommand : PSCmdlet
protected override void BeginProcessing()
{
- GitManager.SetDebugWriter(WriteDebug);
-
- var repoFolder = IsGitRepo(SessionState.Path.CurrentLocation.Path);
-
- if (repoFolder is not null)
+ try
{
+ GitManager.SetDebugWriter(WriteDebug);
+
+ var repoFolder = GitManager.IsGitRepo(SessionState.Path.CurrentLocation.Path);
+
GitManager.Instance.RegisterRepo(repoFolder.Directory, Name ?? repoFolder.Folder);
+
+ GitManager.ClearDebugWriter();
+
+ base.BeginProcessing();
}
- else
+ catch (Exception ex)
{
- // Not sure how we'd hit this path, but in case we do, show some sort of error.
- // TODO: I should probably have IsGitRepo throw instead so I can get the location it tried in the stack track
- WriteError(new ErrorRecord(
- new Exception("Unable to register repo - failed to parse git repo location"),
- "git-parse-failed",
- ErrorCategory.InvalidData,
- null
- )
- );
+ WriteError(new ErrorRecord(ex, ex.Source, ErrorCategory.FromStdErr, null));
}
-
- GitManager.ClearDebugWriter();
-
- base.BeginProcessing();
- }
-
- private ParsedGitFolderDetails? IsGitRepo(string path)
- {
- WriteDebug("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");
- }
-
- 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());
-
- WriteDebug("...location is a git repo (duh).");
-
- var repoFolderInfo = new ParsedGitFolderDetails
- {
- Directory = dirInfo.FullName,
- Folder = dirInfo.Name,
- };
-
- return repoFolderInfo;
- }
-
- if (!gitProcess.StandardError.EndOfStream)
- {
- var errorAsException = new Exception(gitProcess.StandardError.ReadToEnd());
- WriteError(new ErrorRecord(errorAsException, "git-not-found", ErrorCategory.FromStdErr, null));
- }
-
- return null;
- }
-
- ///
- /// The directory details of the directory returned from git rev-parse --show-toplevel
- ///
- private class ParsedGitFolderDetails
- {
- ///
- /// The full path to the top level folder containing a git repository
- ///
- public string Directory { get; init; } = null!;
-
- ///
- /// The last folder name of the directory
- ///
- public string Folder { get; init; } = null!;
}
}
\ No newline at end of file