feature: add context menu Save As Patch... for selected stash (#1018)

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-02-24 21:24:53 +08:00
parent 4868ea1a0b
commit 1d037c7c57
No known key found for this signature in database
5 changed files with 53 additions and 0 deletions

View file

@ -37,6 +37,19 @@ namespace SourceGit.Commands
return true; return true;
} }
public static bool ProcessStashChanges(string repo, List<Models.DiffOption> opts, string saveTo)
{
using (var sw = File.Create(saveTo))
{
foreach (var opt in opts)
{
if (!ProcessSingleChange(repo, opt, sw))
return false;
}
}
return true;
}
private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer) private static bool ProcessSingleChange(string repo, Models.DiffOption opt, FileStream writer)
{ {
var starter = new ProcessStartInfo(); var starter = new ProcessStartInfo();

View file

@ -669,6 +669,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String> <x:String x:Key="Text.StashCM.Pop" xml:space="preserve">Pop</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">Drop Stash</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Drop:</x:String> <x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">Drop:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">STASHES</x:String> <x:String x:Key="Text.Stashes" xml:space="preserve">STASHES</x:String>

View file

@ -673,6 +673,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">应用并删除(pop)</x:String> <x:String x:Key="Text.StashCM.Pop" xml:space="preserve">应用并删除(pop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">丢弃贮藏确认</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">丢弃贮藏确认</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">丢弃贮藏 </x:String> <x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">丢弃贮藏 </x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">贮藏列表</x:String> <x:String x:Key="Text.Stashes" xml:space="preserve">贮藏列表</x:String>

View file

@ -672,6 +672,7 @@
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String> <x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String> <x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
<x:String x:Key="Text.StashCM.Pop" xml:space="preserve">套用並刪除 (pop)</x:String> <x:String x:Key="Text.StashCM.Pop" xml:space="preserve">套用並刪除 (pop)</x:String>
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
<x:String x:Key="Text.StashDropConfirm" xml:space="preserve">捨棄擱置變更確認</x:String> <x:String x:Key="Text.StashDropConfirm" xml:space="preserve">捨棄擱置變更確認</x:String>
<x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">捨棄擱置變更:</x:String> <x:String x:Key="Text.StashDropConfirm.Label" xml:space="preserve">捨棄擱置變更:</x:String>
<x:String x:Key="Text.Stashes" xml:space="preserve">擱置變更</x:String> <x:String x:Key="Text.Stashes" xml:space="preserve">擱置變更</x:String>

View file

@ -4,6 +4,7 @@ using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
@ -157,9 +158,45 @@ namespace SourceGit.ViewModels
ev.Handled = true; ev.Handled = true;
}; };
var patch = new MenuItem();
patch.Header = App.Text("StashCM.SaveAsPatch");
patch.Icon = App.CreateMenuIcon("Icons.Diff");
patch.Click += async (_, e) =>
{
var storageProvider = App.GetStorageProvider();
if (storageProvider == null)
return;
var options = new FilePickerSaveOptions();
options.Title = App.Text("StashCM.SaveAsPatch");
options.DefaultExtension = ".patch";
options.FileTypeChoices = [new FilePickerFileType("Patch File") { Patterns = ["*.patch"] }];
var storageFile = await storageProvider.SaveFilePickerAsync(options);
if (storageFile != null)
{
var opts = new List<Models.DiffOption>();
foreach (var c in _changes)
{
if (_untrackedChanges.Contains(c.Path))
opts.Add(new Models.DiffOption("4b825dc642cb6eb9a060e54bf8d69288fbee4904", _selectedStash.Parents[2], c));
else
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
}
var succ = await Task.Run(() => Commands.SaveChangesAsPatch.ProcessStashChanges(_repo.FullPath, opts, storageFile.Path.LocalPath));
if (succ)
App.SendNotification(_repo.FullPath, App.Text("SaveAsPatchSuccess"));
}
e.Handled = true;
};
var menu = new ContextMenu(); var menu = new ContextMenu();
menu.Items.Add(apply); menu.Items.Add(apply);
menu.Items.Add(drop); menu.Items.Add(drop);
menu.Items.Add(new MenuItem { Header = "-" });
menu.Items.Add(patch);
return menu; return menu;
} }