Skip to content

Commit cf3a1c2

Browse files
committed
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>
1 parent 1881972 commit cf3a1c2

File tree

5 files changed

+88
-81
lines changed

5 files changed

+88
-81
lines changed

src/Resources/Locales/en_US.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@
851851
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">Both staged and unstaged changes of selected file(s) will be stashed!!!</x:String>
852852
<x:String x:Key="Text.Stash.Title" xml:space="preserve">Stash Local Changes</x:String>
853853
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">Apply</x:String>
854+
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">Apply Changes</x:String>
854855
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">Copy Message</x:String>
855856
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">Drop</x:String>
856857
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">Save as Patch...</x:String>

src/Resources/Locales/zh_CN.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@
855855
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">选中文件的所有变更均会被贮藏!</x:String>
856856
<x:String x:Key="Text.Stash.Title" xml:space="preserve">贮藏本地变更</x:String>
857857
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">应用(apply)</x:String>
858+
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">应用(apply)选中变更</x:String>
858859
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">复制描述信息</x:String>
859860
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">删除(drop)</x:String>
860861
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存为补丁...</x:String>

src/Resources/Locales/zh_TW.axaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,7 @@
855855
<x:String x:Key="Text.Stash.TipForSelectedFiles" xml:space="preserve">已選取的檔案中的變更均會被擱置!</x:String>
856856
<x:String x:Key="Text.Stash.Title" xml:space="preserve">擱置本機變更</x:String>
857857
<x:String x:Key="Text.StashCM.Apply" xml:space="preserve">套用 (apply)</x:String>
858+
<x:String x:Key="Text.StashCM.ApplyFileChanges" xml:space="preserve">套用 (apply) 所選變更</x:String>
858859
<x:String x:Key="Text.StashCM.CopyMessage" xml:space="preserve">複製描述訊息</x:String>
859860
<x:String x:Key="Text.StashCM.Drop" xml:space="preserve">刪除 (drop)</x:String>
860861
<x:String x:Key="Text.StashCM.SaveAsPatch" xml:space="preserve">另存為修補檔 (patch)...</x:String>

src/ViewModels/StashesPage.cs

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Threading.Tasks;
45

56
using Avalonia.Threading;
@@ -196,22 +197,7 @@ public void OpenChangeWithExternalDiffTool(Models.Change change)
196197
new Commands.DiffTool(_repo.FullPath, opt).Open();
197198
}
198199

199-
public async Task CheckoutSingleFileAsync(Models.Change change)
200-
{
201-
var revision = _selectedStash.SHA;
202-
if (_untracked.Contains(change) && _selectedStash.Parents.Count == 3)
203-
revision = _selectedStash.Parents[2];
204-
else if (change.Index == Models.ChangeState.Added && _selectedStash.Parents.Count > 1)
205-
revision = _selectedStash.Parents[1];
206-
207-
var log = _repo.CreateLog($"Reset File to '{_selectedStash.Name}'");
208-
await new Commands.Checkout(_repo.FullPath)
209-
.Use(log)
210-
.FileWithRevisionAsync(change.Path, revision);
211-
log.Complete();
212-
}
213-
214-
public async Task CheckoutMultipleFileAsync(List<Models.Change> changes)
200+
public async Task CheckoutFilesAsync(List<Models.Change> changes)
215201
{
216202
var untracked = new List<string>();
217203
var added = new List<string>();
@@ -247,6 +233,34 @@ public async Task CheckoutMultipleFileAsync(List<Models.Change> changes)
247233
log.Complete();
248234
}
249235

236+
public async Task ApplySelectedChanges(List<Models.Change> changes)
237+
{
238+
if (_selectedStash == null)
239+
return;
240+
241+
var opts = new List<Models.DiffOption>();
242+
foreach (var c in changes)
243+
{
244+
if (_untracked.Contains(c) && _selectedStash.Parents.Count == 3)
245+
opts.Add(new Models.DiffOption(Models.Commit.EmptyTreeSHA1, _selectedStash.Parents[2], c));
246+
else
247+
opts.Add(new Models.DiffOption(_selectedStash.Parents[0], _selectedStash.SHA, c));
248+
}
249+
250+
var saveTo = Path.GetTempFileName();
251+
var succ = await Commands.SaveChangesAsPatch.ProcessStashChangesAsync(_repo.FullPath, opts, saveTo);
252+
if (!succ)
253+
return;
254+
255+
var log = _repo.CreateLog($"Apply changes from '{_selectedStash.Name}'");
256+
await new Commands.Apply(_repo.FullPath, saveTo, true, string.Empty, string.Empty)
257+
.Use(log)
258+
.ExecAsync();
259+
260+
log.Complete();
261+
File.Delete(saveTo);
262+
}
263+
250264
private void RefreshVisible()
251265
{
252266
if (string.IsNullOrEmpty(_searchFilter))

src/Views/StashesPage.axaml.cs

Lines changed: 55 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e
134134
if (DataContext is ViewModels.StashesPage { SelectedChanges: { Count: > 0 } selected } vm &&
135135
sender is ChangeCollectionView view)
136136
{
137+
var menu = new ContextMenu();
138+
137139
if (selected.Count == 1)
138140
{
139141
var change = selected[0];
@@ -159,91 +161,79 @@ private void OnChangeContextRequested(object sender, ContextRequestedEventArgs e
159161
ev.Handled = true;
160162
};
161163

162-
var resetToThisRevision = new MenuItem();
163-
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
164-
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
165-
resetToThisRevision.Click += async (_, ev) =>
166-
{
167-
await vm.CheckoutSingleFileAsync(change);
168-
ev.Handled = true;
169-
};
170-
171-
var copyPath = new MenuItem();
172-
copyPath.Header = App.Text("CopyPath");
173-
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
174-
copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
175-
copyPath.Click += async (_, ev) =>
176-
{
177-
await App.CopyTextAsync(change.Path);
178-
ev.Handled = true;
179-
};
180-
181-
var copyFullPath = new MenuItem();
182-
copyFullPath.Header = App.Text("CopyFullPath");
183-
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
184-
copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
185-
copyFullPath.Click += async (_, ev) =>
186-
{
187-
await App.CopyTextAsync(fullPath);
188-
ev.Handled = true;
189-
};
190-
191-
var menu = new ContextMenu();
192164
menu.Items.Add(openWithMerger);
193165
menu.Items.Add(explore);
194166
menu.Items.Add(new MenuItem { Header = "-" });
195-
menu.Items.Add(resetToThisRevision);
196-
menu.Items.Add(new MenuItem { Header = "-" });
197-
menu.Items.Add(copyPath);
198-
menu.Items.Add(copyFullPath);
199-
menu.Open(view);
200167
}
201-
else
168+
169+
var applyChanges = new MenuItem();
170+
applyChanges.Header = App.Text("StashCM.ApplyFileChanges");
171+
applyChanges.Icon = App.CreateMenuIcon("Icons.Diff");
172+
applyChanges.Click += async (_, ev) =>
202173
{
203-
var resetToThisRevision = new MenuItem();
204-
resetToThisRevision.Header = App.Text("ChangeCM.CheckoutThisRevision");
205-
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
206-
resetToThisRevision.Click += async (_, ev) =>
207-
{
208-
await vm.CheckoutMultipleFileAsync(selected);
209-
ev.Handled = true;
210-
};
174+
await vm.ApplySelectedChanges(selected);
175+
ev.Handled = true;
176+
};
211177

212-
var copyPath = new MenuItem();
213-
copyPath.Header = App.Text("CopyPath");
214-
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
215-
copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
216-
copyPath.Click += async (_, ev) =>
178+
var checkoutFiles = new MenuItem();
179+
checkoutFiles.Header = App.Text("ChangeCM.CheckoutThisRevision");
180+
checkoutFiles.Icon = App.CreateMenuIcon("Icons.File.Checkout");
181+
checkoutFiles.Click += async (_, ev) =>
182+
{
183+
await vm.CheckoutFilesAsync(selected);
184+
ev.Handled = true;
185+
};
186+
187+
var copyPath = new MenuItem();
188+
copyPath.Header = App.Text("CopyPath");
189+
copyPath.Icon = App.CreateMenuIcon("Icons.Copy");
190+
copyPath.Tag = OperatingSystem.IsMacOS() ? "⌘+C" : "Ctrl+C";
191+
copyPath.Click += async (_, ev) =>
192+
{
193+
if (selected.Count == 1)
194+
{
195+
await App.CopyTextAsync(selected[0].Path);
196+
}
197+
else
217198
{
218199
var builder = new StringBuilder();
219200
foreach (var c in selected)
220201
builder.AppendLine(c.Path);
221202

222203
await App.CopyTextAsync(builder.ToString());
223-
ev.Handled = true;
224-
};
204+
}
205+
206+
ev.Handled = true;
207+
};
225208

226-
var copyFullPath = new MenuItem();
227-
copyFullPath.Header = App.Text("CopyFullPath");
228-
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
229-
copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
230-
copyFullPath.Click += async (_, ev) =>
209+
var copyFullPath = new MenuItem();
210+
copyFullPath.Header = App.Text("CopyFullPath");
211+
copyFullPath.Icon = App.CreateMenuIcon("Icons.Copy");
212+
copyFullPath.Tag = OperatingSystem.IsMacOS() ? "⌘+⇧+C" : "Ctrl+Shift+C";
213+
copyFullPath.Click += async (_, ev) =>
214+
{
215+
if (selected.Count == 1)
216+
{
217+
await App.CopyTextAsync(vm.GetAbsPath(selected[0].Path));
218+
}
219+
else
231220
{
232221
var builder = new StringBuilder();
233222
foreach (var c in selected)
234223
builder.AppendLine(vm.GetAbsPath(c.Path));
235224

236225
await App.CopyTextAsync(builder.ToString());
237-
ev.Handled = true;
238-
};
226+
}
239227

240-
var menu = new ContextMenu();
241-
menu.Items.Add(resetToThisRevision);
242-
menu.Items.Add(new MenuItem { Header = "-" });
243-
menu.Items.Add(copyPath);
244-
menu.Items.Add(copyFullPath);
245-
menu.Open(view);
246-
}
228+
ev.Handled = true;
229+
};
230+
231+
menu.Items.Add(applyChanges);
232+
menu.Items.Add(checkoutFiles);
233+
menu.Items.Add(new MenuItem { Header = "-" });
234+
menu.Items.Add(copyPath);
235+
menu.Items.Add(copyFullPath);
236+
menu.Open(view);
247237
}
248238

249239
e.Handled = true;

0 commit comments

Comments
 (0)