diff --git a/CodeEdit/Features/Git/Client/GitClient+Status.swift b/CodeEdit/Features/Git/Client/GitClient+Status.swift index 5afac5de8..f704104eb 100644 --- a/CodeEdit/Features/Git/Client/GitClient+Status.swift +++ b/CodeEdit/Features/Git/Client/GitClient+Status.swift @@ -38,4 +38,9 @@ extension GitClient { func discardChanges(for file: URL) async throws { _ = try await run("restore \(file.relativePath)") } + + /// Discard unstaged changes + func discardAllChanges() async throws { + _ = try await run("restore .") + } } diff --git a/CodeEdit/Features/Git/SourceControlManager.swift b/CodeEdit/Features/Git/SourceControlManager.swift index 76d1b1a5d..681cbd4a3 100644 --- a/CodeEdit/Features/Git/SourceControlManager.swift +++ b/CodeEdit/Features/Git/SourceControlManager.swift @@ -152,6 +152,19 @@ final class SourceControlManager: ObservableObject { } } + /// Discard changes for repository + func discardAllChanges() { + Task { + do { + try await gitClient.discardAllChanges() + // TODO: Refresh content of active and unmodified document, + // requires CodeEditTextView changes + } catch { + await showAlertForError(title: "Failed to discard changes", error: error) + } + } + } + /// Commit files selected by user func commit(message: String) async throws { var filesToCommit: [CEWorkspaceFile] = [] diff --git a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/SourceControlToolbarBottom.swift b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/SourceControlToolbarBottom.swift index bb814d443..89ab0add5 100644 --- a/CodeEdit/Features/NavigatorArea/SourceControlNavigator/SourceControlToolbarBottom.swift +++ b/CodeEdit/Features/NavigatorArea/SourceControlNavigator/SourceControlToolbarBottom.swift @@ -8,6 +8,8 @@ import SwiftUI struct SourceControlToolbarBottom: View { + @EnvironmentObject private var workspace: WorkspaceDocument + var body: some View { HStack(spacing: 0) { sourceControlMenu @@ -23,8 +25,11 @@ struct SourceControlToolbarBottom: View { private var sourceControlMenu: some View { Menu { - Button("Discard Changes...") {} - .disabled(true) // TODO: Implementation Needed + Button("Discard All Changes...") { + if discardChangesDialog() { + workspace.sourceControlManager?.discardAllChanges() + } + } Button("Stash Changes...") {} .disabled(true) // TODO: Implementation Needed Button("Commit...") {} @@ -38,4 +43,17 @@ struct SourceControlToolbarBottom: View { .menuIndicator(.hidden) .frame(maxWidth: 30) } + + /// Renders a Discard Changes Dialog + func discardChangesDialog() -> Bool { + let alert = NSAlert() + + alert.messageText = "Do you want to discard all uncommitted, local changes?" + alert.informativeText = "This operation cannot be undone." + alert.alertStyle = .warning + alert.addButton(withTitle: "Discard") + alert.addButton(withTitle: "Cancel") + + return alert.runModal() == .alertFirstButtonReturn + } }