diff --git a/CodeEdit/Features/Git/Client/GitClient+CommitHistory.swift b/CodeEdit/Features/Git/Client/GitClient+CommitHistory.swift index 929a437ff..f2522ba1b 100644 --- a/CodeEdit/Features/Git/Client/GitClient+CommitHistory.swift +++ b/CodeEdit/Features/Git/Client/GitClient+CommitHistory.swift @@ -34,8 +34,7 @@ extension GitClient { "log -z --pretty=%h¦%H¦%s¦%aN¦%ae¦%cn¦%ce¦%aD¦%b¦%D¦ \(maxCountString) \(branchNameString) \(fileLocalPath)" .trimmingCharacters(in: .whitespacesAndNewlines) ) - let remote = try await run("ls-remote --get-url") - let remoteURL = URL(string: remote.trimmingCharacters(in: .whitespacesAndNewlines)) + let remoteURL = try await getRemoteURL() return output .split(separator: "\0") diff --git a/CodeEdit/Features/Git/Client/GitClient+Remote.swift b/CodeEdit/Features/Git/Client/GitClient+Remote.swift index b3f1b67d6..04307430b 100644 --- a/CodeEdit/Features/Git/Client/GitClient+Remote.swift +++ b/CodeEdit/Features/Git/Client/GitClient+Remote.swift @@ -31,6 +31,23 @@ extension GitClient { func removeRemote(name: String) async throws { _ = try await run("remote rm \(name)") } + + /// Get the URL of the remote + /// > Note: If a git repository has multiple remotes, by default the `origin` remote + /// > will be used, unless there’s an upstream branch configured for the current branch. + /// > (Reference: https://git-scm.com/docs/git-ls-remote, https://git-scm.com/docs/git-fetch) + /// - Returns: A URL if a remote is configured, nil otherwise + /// - Throws: `GitClientError.outputError` if the underlying git command fails unexpectedly + func getRemoteURL() async throws -> URL? { + do { + let remote = try await run("ls-remote --get-url") + return URL(string: remote.trimmingCharacters(in: .whitespacesAndNewlines)) + } catch GitClientError.noRemoteConfigured { + return nil + } catch { + throw error + } + } } func parseGitRemotes(from output: String) -> [GitRemote] { diff --git a/CodeEdit/Features/Git/Client/GitClient.swift b/CodeEdit/Features/Git/Client/GitClient.swift index a8f68dec9..67162f665 100644 --- a/CodeEdit/Features/Git/Client/GitClient.swift +++ b/CodeEdit/Features/Git/Client/GitClient.swift @@ -13,12 +13,14 @@ class GitClient { case outputError(String) case notGitRepository case failedToDecodeURL + case noRemoteConfigured var description: String { switch self { case .outputError(let string): string case .notGitRepository: "Not a git repository" case .failedToDecodeURL: "Failed to decode URL" + case .noRemoteConfigured: "No remote configured" } } } @@ -63,6 +65,10 @@ class GitClient { throw GitClientError.notGitRepository } + if output.contains("fatal: No remote configured") { + throw GitClientError.noRemoteConfigured + } + if output.hasPrefix("fatal:") { throw GitClientError.outputError(output) }