diff --git a/src/Commands/Restore.cs b/src/Commands/Restore.cs new file mode 100644 index 00000000..c0aeafd5 --- /dev/null +++ b/src/Commands/Restore.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Text; + +namespace SourceGit.Commands { + public class Restore : Command { + public Restore(string repo, List files, string extra) { + WorkingDirectory = repo; + Context = repo; + + StringBuilder builder = new StringBuilder(); + builder.Append("restore "); + if (!string.IsNullOrEmpty(extra)) builder.Append(extra).Append(" "); + builder.Append("--"); + foreach (var f in files) builder.Append(' ').Append('"').Append(f).Append('"'); + Args = builder.ToString(); + } + } +} diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index af22366f..69821e2d 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -458,8 +458,6 @@ namespace SourceGit.ViewModels { } public void RefreshWorkingCopyChanges() { - _watcher.MarkWorkingCopyRefreshed(); - var changes = new Commands.QueryLocalChanges(FullPath, _includeUntracked).Result(); var hasUnsolvedConflict = _workingCopy.SetData(changes); @@ -484,6 +482,8 @@ namespace SourceGit.ViewModels { HasUnsolvedConflict = hasUnsolvedConflict; OnPropertyChanged(nameof(WorkingCopyChangesCount)); }); + + _watcher.MarkWorkingCopyRefreshed(); } public void RefreshStashes() { diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index c370a5f3..fe0253e2 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -676,7 +676,24 @@ namespace SourceGit.Views { workcopy.UnstageChanges(new List { change }); e.Handled = true; }; + + var discard = new MenuItem(); + 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); + e.Handled = true; + }; + menu.Items.Add(unstage); + menu.Items.Add(discard); } } else { var repoView = this.FindAncestorOfType(); @@ -762,7 +779,36 @@ namespace SourceGit.Views { repo.SetWatcherEnabled(true); e.Handled = true; }; + + var discard = new MenuItem(); + discard.Header = App.Text("FileCM.DiscardSelectedLines"); + discard.Icon = App.CreateMenuIcon("Icons.Undo"); + discard.Click += (_, e) => { + var repo = repoView.DataContext as ViewModels.Repository; + repo.SetWatcherEnabled(false); + + var tmpFile = Path.GetTempFileName(); + if (change.WorkTree == Models.ChangeState.Untracked) { + TextDiff.GenerateNewPatchFromSelection(change, null, selection, true, tmpFile); + } else if (UseCombined) { + var treeGuid = new Commands.QueryStagedFileBlobGuid(ctx.RepositoryPath, change.Path).Result(); + TextDiff.GeneratePatchFromSelection(change, treeGuid, selection, true, tmpFile); + } else { + var treeGuid = new Commands.QueryStagedFileBlobGuid(ctx.RepositoryPath, change.Path).Result(); + TextDiff.GeneratePatchFromSelectionSingleSide(change, treeGuid, selection, true, isOldSide, tmpFile); + } + + new Commands.Apply(ctx.RepositoryPath, tmpFile, true, "nowarn", "--cache --index --reverse").Exec(); + new Commands.Apply(ctx.RepositoryPath, tmpFile, true, "nowarn", "--reverse").Exec(); + File.Delete(tmpFile); + + repo.RefreshWorkingCopyChanges(); + repo.SetWatcherEnabled(true); + e.Handled = true; + }; + menu.Items.Add(unstage); + menu.Items.Add(discard); } }