Skip to content

Commit 929eb95

Browse files
love-lingerybeapps
andcommitted
refactor: rewrite Reset to This/Parent Revision feature in commit details panel (#2079)
Better handle for `added/deleted/renamed` file changes Co-authored-by: ybeapps <ybeapps@gmail.com> Signed-off-by: leo <longshuang@msn.cn>
1 parent 7585f0d commit 929eb95

File tree

3 files changed

+143
-17
lines changed

3 files changed

+143
-17
lines changed

src/Commands/Remove.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Collections.Generic;
2+
using System.Text;
3+
4+
namespace SourceGit.Commands
5+
{
6+
public class Remove : Command
7+
{
8+
public Remove(string repo, List<string> files)
9+
{
10+
WorkingDirectory = repo;
11+
Context = repo;
12+
13+
var builder = new StringBuilder();
14+
builder.Append("rm -f --");
15+
foreach (var file in files)
16+
builder.Append(' ').Append(file.Quoted());
17+
18+
Args = builder.ToString();
19+
}
20+
}
21+
}

src/ViewModels/CommitDetail.cs

Lines changed: 121 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
using Avalonia;
99
using Avalonia.Threading;
10-
1110
using CommunityToolkit.Mvvm.ComponentModel;
1211

1312
namespace SourceGit.ViewModels
@@ -254,48 +253,154 @@ public async Task ResetToThisRevisionAsync(string path)
254253
log.Complete();
255254
}
256255

256+
public async Task ResetToThisRevisionAsync(Models.Change change)
257+
{
258+
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'");
259+
260+
if (change.Index == Models.ChangeState.Deleted)
261+
{
262+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
263+
if (File.Exists(fullpath))
264+
await new Commands.Remove(_repo.FullPath, [change.Path])
265+
.Use(log)
266+
.ExecAsync();
267+
}
268+
else if (change.Index == Models.ChangeState.Renamed)
269+
{
270+
var old = Native.OS.GetAbsPath(_repo.FullPath, change.OriginalPath);
271+
if (File.Exists(old))
272+
await new Commands.Remove(_repo.FullPath, [change.OriginalPath])
273+
.Use(log)
274+
.ExecAsync();
275+
276+
await new Commands.Checkout(_repo.FullPath)
277+
.Use(log)
278+
.FileWithRevisionAsync(change.Path, _commit.SHA);
279+
}
280+
else
281+
{
282+
await new Commands.Checkout(_repo.FullPath)
283+
.Use(log)
284+
.FileWithRevisionAsync(change.Path, _commit.SHA);
285+
}
286+
287+
log.Complete();
288+
}
289+
257290
public async Task ResetToParentRevisionAsync(Models.Change change)
258291
{
259292
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'");
260293

261-
if (change.Index == Models.ChangeState.Renamed)
262-
await new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevisionAsync(change.OriginalPath, $"{_commit.SHA}~1");
294+
if (change.Index == Models.ChangeState.Added)
295+
{
296+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
297+
if (File.Exists(fullpath))
298+
await new Commands.Remove(_repo.FullPath, [change.Path])
299+
.Use(log)
300+
.ExecAsync();
301+
}
302+
else if (change.Index == Models.ChangeState.Renamed)
303+
{
304+
var renamed = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
305+
if (File.Exists(renamed))
306+
await new Commands.Remove(_repo.FullPath, [change.Path])
307+
.Use(log)
308+
.ExecAsync();
309+
310+
await new Commands.Checkout(_repo.FullPath)
311+
.Use(log)
312+
.FileWithRevisionAsync(change.OriginalPath, _commit.SHA);
313+
}
314+
else
315+
{
316+
await new Commands.Checkout(_repo.FullPath)
317+
.Use(log)
318+
.FileWithRevisionAsync(change.Path, _commit.SHA);
319+
}
263320

264-
await new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevisionAsync(change.Path, $"{_commit.SHA}~1");
265321
log.Complete();
266322
}
267323

268324
public async Task ResetMultipleToThisRevisionAsync(List<Models.Change> changes)
269325
{
270-
var files = new List<string>();
326+
var checkouts = new List<string>();
327+
var removes = new List<string>();
328+
271329
foreach (var c in changes)
272-
files.Add(c.Path);
330+
{
331+
if (c.Index == Models.ChangeState.Deleted)
332+
{
333+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
334+
if (File.Exists(fullpath))
335+
removes.Add(c.Path);
336+
}
337+
else if (c.Index == Models.ChangeState.Renamed)
338+
{
339+
var old = Native.OS.GetAbsPath(_repo.FullPath, c.OriginalPath);
340+
if (File.Exists(old))
341+
removes.Add(c.OriginalPath);
342+
343+
checkouts.Add(c.Path);
344+
}
345+
else
346+
{
347+
checkouts.Add(c.Path);
348+
}
349+
}
273350

274351
var log = _repo.CreateLog($"Reset Files to '{_commit.SHA}'");
275-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(files, _commit.SHA);
352+
353+
if (removes.Count > 0)
354+
await new Commands.Remove(_repo.FullPath, removes)
355+
.Use(log)
356+
.ExecAsync();
357+
358+
if (checkouts.Count > 0)
359+
await new Commands.Checkout(_repo.FullPath)
360+
.Use(log)
361+
.MultipleFilesWithRevisionAsync(checkouts, _commit.SHA);
362+
276363
log.Complete();
277364
}
278365

279366
public async Task ResetMultipleToParentRevisionAsync(List<Models.Change> changes)
280367
{
281-
var renamed = new List<string>();
282-
var modified = new List<string>();
368+
var checkouts = new List<string>();
369+
var removes = new List<string>();
283370

284371
foreach (var c in changes)
285372
{
286-
if (c.Index == Models.ChangeState.Renamed)
287-
renamed.Add(c.OriginalPath);
373+
if (c.Index == Models.ChangeState.Added)
374+
{
375+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
376+
if (File.Exists(fullpath))
377+
removes.Add(c.Path);
378+
}
379+
else if (c.Index == Models.ChangeState.Renamed)
380+
{
381+
var renamed = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
382+
if (File.Exists(renamed))
383+
removes.Add(c.Path);
384+
385+
checkouts.Add(c.OriginalPath);
386+
}
288387
else
289-
modified.Add(c.Path);
388+
{
389+
checkouts.Add(c.Path);
390+
}
290391
}
291392

292393
var log = _repo.CreateLog($"Reset Files to '{_commit.SHA}~1'");
293394

294-
if (modified.Count > 0)
295-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(modified, $"{_commit.SHA}~1");
395+
if (removes.Count > 0)
396+
await new Commands.Remove(_repo.FullPath, removes)
397+
.Use(log)
398+
.ExecAsync();
296399

297-
if (renamed.Count > 0)
298-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(renamed, $"{_commit.SHA}~1");
400+
if (checkouts.Count > 0)
401+
await new Commands.Checkout(_repo.FullPath)
402+
.Use(log)
403+
.MultipleFilesWithRevisionAsync(checkouts, $"{_commit.SHA}~1");
299404

300405
log.Complete();
301406
}

src/Views/CommitDetail.axaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ public ContextMenu CreateChangeContextMenu(Models.Change change)
335335
resetToThisRevision.Icon = App.CreateMenuIcon("Icons.File.Checkout");
336336
resetToThisRevision.Click += async (_, ev) =>
337337
{
338-
await vm.ResetToThisRevisionAsync(change.Path);
338+
await vm.ResetToThisRevisionAsync(change);
339339
ev.Handled = true;
340340
};
341341

0 commit comments

Comments
 (0)