mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-21 05:10:25 +08:00
feature: add context menu entry Apply Changes to only apply changes of selected file from stash (not reset mode) (#2122)
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
@@ -851,6 +851,7 @@
|
||||
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Both staged and unstaged changes of selected file(s) will be stashed!!!</x:String>
|
||||
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Local Changes</x:String>
|
||||
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
|
||||
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">Apply Changes</x:String>
|
||||
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Copy Message</x:String>
|
||||
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
|
||||
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>
|
||||
|
||||
@@ -855,6 +855,7 @@
|
||||
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">选中文件的所有变更均会被贮藏!</x:String>
|
||||
<x:String x:Key="Text.Stash.Title" xml:space="preserve">贮藏本地变更</x:String>
|
||||
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
|
||||
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">应用(apply)选中变更</x:String>
|
||||
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">复制描述信息</x:String>
|
||||
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
|
||||
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>
|
||||
|
||||
@@ -855,6 +855,7 @@
|
||||
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">已選取的檔案中的變更均會被擱置!</x:String>
|
||||
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String>
|
||||
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
|
||||
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">套用 (apply) 所選變更</x:String>
|
||||
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">複製描述訊息</x:String>
|
||||
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
|
||||
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>
|
||||
|
||||
@@ -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<Models.Change> changes)
|
||||
public async Task CheckoutFilesAsync(List<Models.Change> changes)
|
||||
{
|
||||
var untracked = new List<string>();
|
||||
var added = new List<string>();
|
||||
@@ -247,6 +233,34 @@ namespace SourceGit.ViewModels
|
||||
log.Complete();
|
||||
}
|
||||
|
||||
public async Task ApplySelectedChanges(List<Models.Change> changes)
|
||||
{
|
||||
if (_selectedStash == null)
|
||||
return;
|
||||
|
||||
var opts = new List<Models.DiffOption>();
|
||||
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))
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user