diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 42a52910..ea8b7d1d 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -851,6 +851,7 @@ Both staged and unstaged changes of selected file(s) will be stashed!!! Stash Local Changes Apply + Apply Changes Copy Message Drop Save as Patch... diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index f885a131..29094248 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -855,6 +855,7 @@ 选中文件的所有变更均会被贮藏! 贮藏本地变更 应用(apply) + 应用(apply)选中变更 复制描述信息 删除(drop) 另存为补丁... diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 7e25d272..0dc4afc4 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -855,6 +855,7 @@ 已選取的檔案中的變更均會被擱置! 擱置本機變更 套用 (apply) + 套用 (apply) 所選變更 複製描述訊息 刪除 (drop) 另存為修補檔 (patch)... diff --git a/src/ViewModels/StashesPage.cs b/src/ViewModels/StashesPage.cs index 96f01c7a..a2a47c27 100644 --- a/src/ViewModels/StashesPage.cs +++ b/src/ViewModels/StashesPage.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Threading.Tasks; using Avalonia.Threading; @@ -196,22 +197,7 @@ namespace SourceGit.ViewModels new Commands.DiffTool(_repo.FullPath, opt).Open(); } - public async Task CheckoutSingleFileAsync(Models.Change change) - { - var revision = _selectedStash.SHA; - if (_untracked.Contains(change) && _selectedStash.Parents.Count == 3) - revision = _selectedStash.Parents[2]; - else if (change.Index == Models.ChangeState.Added && _selectedStash.Parents.Count > 1) - revision = _selectedStash.Parents[1]; - - var log = _repo.CreateLog($"Reset File to '{_selectedStash.Name}'"); - await new Commands.Checkout(_repo.FullPath) - .Use(log) - .FileWithRevisionAsync(change.Path, revision); - log.Complete(); - } - - public async Task CheckoutMultipleFileAsync(List changes) + public async Task CheckoutFilesAsync(List changes) { var untracked = new List(); var added = new List(); @@ -247,6 +233,34 @@ namespace SourceGit.ViewModels log.Complete(); } + public async Task ApplySelectedChanges(List changes) + { + if (_selectedStash == null) + return; + + var opts = new List(); + foreach (var c in changes) + { + if (_untracked.Contains(c) && _selectedStash.Parents.Count == 3) + opts.Add(new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], c)); + else + opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c)); + } + + var saveTo = Path.GetTempFileName(); + var succ = await Commands.SaveChangesAsPatch.ProcessStashChangesAsync(_repo.FullPath, opts, saveTo); + if (!succ) + return; + + var log = _repo.CreateLog($"Apply changes from '{_selectedStash.Name}'"); + await new Commands.Apply(_repo.FullPath, saveTo, true, string.Empty, string.Empty) + .Use(log) + .ExecAsync(); + + log.Complete(); + File.Delete(saveTo); + } + private void RefreshVisible() { if (string.IsNullOrEmpty(_searchFilter)) diff --git a/src/Views/StashesPage.axaml.cs b/src/Views/StashesPage.axaml.cs index ee53fe28..9a38d48d 100644 --- a/src/Views/StashesPage.axaml.cs +++ b/src/Views/StashesPage.axaml.cs @@ -134,6 +134,8 @@ namespace SourceGit.Views if (DataContext is ViewModels.StashesPage { SelectedChanges: { Count: > 0 } selected } vm && sender is ChangeCollectionView view) { + var menu = new ContextMenu(); + if (selected.Count == 1) { var change = selected[0]; @@ -159,91 +161,79 @@ namespace SourceGit.Views ev.Handled = true; }; - var resetToThisRevision = new MenuItem(); - resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision"); - resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); - resetToThisRevision.Click += async (_, ev) => - { - await vm.CheckoutSingleFileAsync(change); - ev.Handled = true; - }; - - var copyPath = new MenuItem(); - copyPath.Header = App.Text("CopyPath"); - copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); - copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C"; - copyPath.Click += async (_, ev) => - { - await App.CopyTextAsync(change.Path); - ev.Handled = true; - }; - - var copyFullPath = new MenuItem(); - copyFullPath.Header = App.Text("CopyFullPath"); - copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C"; - copyFullPath.Click += async (_, ev) => - { - await App.CopyTextAsync(fullPath); - ev.Handled = true; - }; - - var menu = new ContextMenu(); menu.Items.Add(openWithMerger); menu.Items.Add(explore); menu.Items.Add(new MenuItem { Header = "-" }); - menu.Items.Add(resetToThisRevision); - menu.Items.Add(new MenuItem { Header = "-" }); - menu.Items.Add(copyPath); - menu.Items.Add(copyFullPath); - menu.Open(view); } - else - { - var resetToThisRevision = new MenuItem(); - resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision"); - resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout"); - resetToThisRevision.Click += async (_, ev) => - { - await vm.CheckoutMultipleFileAsync(selected); - ev.Handled = true; - }; - var copyPath = new MenuItem(); - copyPath.Header = App.Text("CopyPath"); - copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); - copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C"; - copyPath.Click += async (_, ev) => + var applyChanges = new MenuItem(); + applyChanges.Header = App.Text("StashCM.ApplyFileChanges"); + applyChanges.Icon = App.CreateMenuIcon("Icons.Diff"); + applyChanges.Click += async (_, ev) => + { + await vm.ApplySelectedChanges(selected); + ev.Handled = true; + }; + + var checkoutFiles = new MenuItem(); + checkoutFiles.Header = App.Text("ChangeCM.CheckoutThisRevision"); + checkoutFiles.Icon = App.CreateMenuIcon("Icons.File.Checkout"); + checkoutFiles.Click += async (_, ev) => + { + await vm.CheckoutFilesAsync(selected); + ev.Handled = true; + }; + + var copyPath = new MenuItem(); + copyPath.Header = App.Text("CopyPath"); + copyPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C"; + copyPath.Click += async (_, ev) => + { + if (selected.Count == 1) + { + await App.CopyTextAsync(selected[0].Path); + } + else { var builder = new StringBuilder(); foreach (var c in selected) builder.AppendLine(c.Path); await App.CopyTextAsync(builder.ToString()); - ev.Handled = true; - }; + } - var copyFullPath = new MenuItem(); - copyFullPath.Header = App.Text("CopyFullPath"); - copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); - copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C"; - copyFullPath.Click += async (_, ev) => + ev.Handled = true; + }; + + var copyFullPath = new MenuItem(); + copyFullPath.Header = App.Text("CopyFullPath"); + copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy"); + copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C"; + copyFullPath.Click += async (_, ev) => + { + if (selected.Count == 1) + { + await App.CopyTextAsync(vm.GetAbsPath(selected[0].Path)); + } + else { var builder = new StringBuilder(); foreach (var c in selected) builder.AppendLine(vm.GetAbsPath(c.Path)); await App.CopyTextAsync(builder.ToString()); - ev.Handled = true; - }; + } - var menu = new ContextMenu(); - menu.Items.Add(resetToThisRevision); - menu.Items.Add(new MenuItem { Header = "-" }); - menu.Items.Add(copyPath); - menu.Items.Add(copyFullPath); - menu.Open(view); - } + ev.Handled = true; + }; + + menu.Items.Add(applyChanges); + menu.Items.Add(checkoutFiles); + menu.Items.Add(new MenuItem { Header = "-" }); + menu.Items.Add(copyPath); + menu.Items.Add(copyFullPath); + menu.Open(view); } e.Handled = true;