From 1c005983c70812bf63d286770dbc65da2de9af79 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 1 Mar 2024 11:34:32 +0800 Subject: [PATCH] fix: wrong discard behavior with changes both in worktree and staged --- src/Commands/Discard.cs | 11 +++++++++- src/ViewModels/Discard.cs | 15 +++++++++++-- src/ViewModels/WorkingCopy.cs | 38 +++++++++++++++++++++++++++------ src/Views/TextDiffView.axaml.cs | 12 +++-------- 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/Commands/Discard.cs b/src/Commands/Discard.cs index 0480c7e6..95f118c9 100644 --- a/src/Commands/Discard.cs +++ b/src/Commands/Discard.cs @@ -8,7 +8,7 @@ namespace SourceGit.Commands { new Clean(repo).Exec(); } - public static void Changes(string repo, List changes) { + public static void ChangesInWorkTree(string repo, List changes) { var needClean = new List(); var needCheckout = new List(); @@ -30,5 +30,14 @@ namespace SourceGit.Commands { new Checkout(repo).Files(needCheckout.GetRange(i, count)); } } + + public static void ChangesInStaged(string repo, List changes) { + for (int i = 0; i < changes.Count; i += 10) { + var count = Math.Min(10, changes.Count - i); + var files = new List(); + for (int j = 0; j < count; j++) files.Add(changes[i + j].Path); + new Restore(repo, files, "--staged --worktree").Exec(); + } + } } } diff --git a/src/ViewModels/Discard.cs b/src/ViewModels/Discard.cs index 8e5e9f95..be2dedc0 100644 --- a/src/ViewModels/Discard.cs +++ b/src/ViewModels/Discard.cs @@ -13,9 +13,17 @@ namespace SourceGit.ViewModels { private set; } - public Discard(Repository repo, List changes = null) { + public Discard(Repository repo) { + _repo = repo; + + Mode = new DiscardModeAll(); + View = new Views.Discard { DataContext = this }; + } + + public Discard(Repository repo, List changes, bool isUnstaged) { _repo = repo; _changes = changes; + _isUnstaged = isUnstaged; if (_changes == null) { Mode = new DiscardModeAll(); @@ -35,8 +43,10 @@ namespace SourceGit.ViewModels { return Task.Run(() => { if (_changes == null) { Commands.Discard.All(_repo.FullPath); + } else if (_isUnstaged) { + Commands.Discard.ChangesInWorkTree(_repo.FullPath, _changes); } else { - Commands.Discard.Changes(_repo.FullPath, _changes); + Commands.Discard.ChangesInStaged(_repo.FullPath, _changes); } CallUIThread(() => _repo.SetWatcherEnabled(true)); @@ -46,5 +56,6 @@ namespace SourceGit.ViewModels { private Repository _repo = null; private List _changes = null; + private bool _isUnstaged = true; } } diff --git a/src/ViewModels/WorkingCopy.cs b/src/ViewModels/WorkingCopy.cs index 01c23125..47ef5bd0 100644 --- a/src/ViewModels/WorkingCopy.cs +++ b/src/ViewModels/WorkingCopy.cs @@ -271,12 +271,20 @@ namespace SourceGit.ViewModels { IsUnstaging = false; } - public void Discard(List changes) { + public void Discard(List changes, bool isUnstaged) { if (PopupHost.CanCreatePopup()) { - if (changes.Count == _count) { - PopupHost.ShowPopup(new Discard(_repo)); + if (isUnstaged) { + if (changes.Count == _unstaged.Count && _staged.Count == 0) { + PopupHost.ShowPopup(new Discard(_repo)); + } else { + PopupHost.ShowPopup(new Discard(_repo, changes, true)); + } } else { - PopupHost.ShowPopup(new Discard(_repo, changes)); + if (changes.Count == _staged.Count && _unstaged.Count == 0) { + PopupHost.ShowPopup(new Discard(_repo)); + } else { + PopupHost.ShowPopup(new Discard(_repo, changes, false)); + } } } } @@ -397,7 +405,7 @@ namespace SourceGit.ViewModels { discard.Header = App.Text("FileCM.Discard"); discard.Icon = App.CreateMenuIcon("Icons.Undo"); discard.Click += (_, e) => { - Discard(changes); + Discard(changes, true); e.Handled = true; }; @@ -483,7 +491,7 @@ namespace SourceGit.ViewModels { discard.Header = App.Text("FileCM.DiscardMulti", changes.Count); discard.Icon = App.CreateMenuIcon("Icons.Undo"); discard.Click += (_, e) => { - Discard(changes); + Discard(changes, true); e.Handled = true; }; @@ -561,6 +569,14 @@ namespace SourceGit.ViewModels { e.Handled = true; }; + var discard = new MenuItem(); + discard.Header = App.Text("FileCM.Discard"); + discard.Icon = App.CreateMenuIcon("Icons.Undo"); + discard.Click += (_, e) => { + Discard(changes, false); + e.Handled = true; + }; + var stash = new MenuItem(); stash.Header = App.Text("FileCM.Stash"); stash.Icon = App.CreateMenuIcon("Icons.Stashes"); @@ -604,6 +620,7 @@ namespace SourceGit.ViewModels { menu.Items.Add(openWith); menu.Items.Add(new MenuItem() { Header = "-" }); menu.Items.Add(unstage); + menu.Items.Add(discard); menu.Items.Add(stash); menu.Items.Add(patch); menu.Items.Add(new MenuItem() { Header = "-" }); @@ -617,6 +634,14 @@ namespace SourceGit.ViewModels { e.Handled = true; }; + var discard = new MenuItem(); + discard.Header = App.Text("FileCM.DiscardMulti", changes.Count); + discard.Icon = App.CreateMenuIcon("Icons.Undo"); + discard.Click += (_, e) => { + Discard(changes, false); + e.Handled = true; + }; + var stash = new MenuItem(); stash.Header = App.Text("FileCM.StashMulti", changes.Count); stash.Icon = App.CreateMenuIcon("Icons.Stashes"); @@ -649,6 +674,7 @@ namespace SourceGit.ViewModels { }; menu.Items.Add(unstage); + menu.Items.Add(discard); menu.Items.Add(stash); menu.Items.Add(patch); } diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index f6c05526..a3d4288b 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -680,7 +680,7 @@ namespace SourceGit.Views { discard.Icon = App.CreateMenuIcon("Icons.Undo"); discard.Click += (_, e) => { var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; - workcopy.Discard(new List { change }); + workcopy.Discard(new List { change }, true); e.Handled = true; }; @@ -700,14 +700,8 @@ namespace SourceGit.Views { discard.Header = App.Text("FileCM.DiscardSelectedLines"); discard.Icon = App.CreateMenuIcon("Icons.Undo"); discard.Click += (_, e) => { - var repoView = this.FindAncestorOfType(); - if (repoView == null) return; - - var repo = repoView.DataContext as ViewModels.Repository; - repo.SetWatcherEnabled(false); - new Commands.Restore(repo.FullPath, new List { change.Path }, "--staged --worktree").Exec(); - repo.RefreshWorkingCopyChanges(); - repo.SetWatcherEnabled(true); + var workcopy = workcopyView.DataContext as ViewModels.WorkingCopy; + workcopy.Discard(new List { change }, false); e.Handled = true; };