Skip to content

Commit 769c220

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 769c220

File tree

3 files changed

+150
-17
lines changed

3 files changed

+150
-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: 128 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
@@ -249,53 +248,166 @@ public async Task SaveChangesAsPatchAsync(List<Models.Change> changes, string sa
249248

250249
public async Task ResetToThisRevisionAsync(string path)
251250
{
251+
var c = _changes?.Find(x => x.Path.Equals(path, StringComparison.Ordinal));
252+
if (c != null)
253+
{
254+
await ResetToThisRevisionAsync(c);
255+
return;
256+
}
257+
252258
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'");
253259
await new Commands.Checkout(_repo.FullPath).Use(log).FileWithRevisionAsync(path, _commit.SHA);
254260
log.Complete();
255261
}
256262

263+
public async Task ResetToThisRevisionAsync(Models.Change change)
264+
{
265+
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}'");
266+
267+
if (change.Index == Models.ChangeState.Deleted)
268+
{
269+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, change.Path);
270+
if (File.Exists(fullpath))
271+
await new Commands.Remove(_repo.FullPath, [change.Path])
272+
.Use(log)
273+
.ExecAsync();
274+
}
275+
else if (change.Index == Models.ChangeState.Renamed)
276+
{
277+
var old = Native.OS.GetAbsPath(_repo.FullPath, change.OriginalPath);
278+
if (File.Exists(old))
279+
await new Commands.Remove(_repo.FullPath, [change.OriginalPath])
280+
.Use(log)
281+
.ExecAsync();
282+
283+
await new Commands.Checkout(_repo.FullPath)
284+
.Use(log)
285+
.FileWithRevisionAsync(change.Path, _commit.SHA);
286+
}
287+
else
288+
{
289+
await new Commands.Checkout(_repo.FullPath)
290+
.Use(log)
291+
.FileWithRevisionAsync(change.Path, _commit.SHA);
292+
}
293+
294+
log.Complete();
295+
}
296+
257297
public async Task ResetToParentRevisionAsync(Models.Change change)
258298
{
259299
var log = _repo.CreateLog($"Reset File to '{_commit.SHA}~1'");
260300

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

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

268331
public async Task ResetMultipleToThisRevisionAsync(List<Models.Change> changes)
269332
{
270-
var files = new List<string>();
333+
var checkouts = new List<string>();
334+
var removes = new List<string>();
335+
271336
foreach (var c in changes)
272-
files.Add(c.Path);
337+
{
338+
if (c.Index == Models.ChangeState.Deleted)
339+
{
340+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
341+
if (File.Exists(fullpath))
342+
removes.Add(c.Path);
343+
}
344+
else if (c.Index == Models.ChangeState.Renamed)
345+
{
346+
var old = Native.OS.GetAbsPath(_repo.FullPath, c.OriginalPath);
347+
if (File.Exists(old))
348+
removes.Add(c.OriginalPath);
349+
350+
checkouts.Add(c.Path);
351+
}
352+
else
353+
{
354+
checkouts.Add(c.Path);
355+
}
356+
}
273357

274358
var log = _repo.CreateLog($"Reset Files to '{_commit.SHA}'");
275-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(files, _commit.SHA);
359+
360+
if (removes.Count > 0)
361+
await new Commands.Remove(_repo.FullPath, removes)
362+
.Use(log)
363+
.ExecAsync();
364+
365+
if (checkouts.Count > 0)
366+
await new Commands.Checkout(_repo.FullPath)
367+
.Use(log)
368+
.MultipleFilesWithRevisionAsync(checkouts, _commit.SHA);
369+
276370
log.Complete();
277371
}
278372

279373
public async Task ResetMultipleToParentRevisionAsync(List<Models.Change> changes)
280374
{
281-
var renamed = new List<string>();
282-
var modified = new List<string>();
375+
var checkouts = new List<string>();
376+
var removes = new List<string>();
283377

284378
foreach (var c in changes)
285379
{
286-
if (c.Index == Models.ChangeState.Renamed)
287-
renamed.Add(c.OriginalPath);
380+
if (c.Index == Models.ChangeState.Added)
381+
{
382+
var fullpath = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
383+
if (File.Exists(fullpath))
384+
removes.Add(c.Path);
385+
}
386+
else if (c.Index == Models.ChangeState.Renamed)
387+
{
388+
var renamed = Native.OS.GetAbsPath(_repo.FullPath, c.Path);
389+
if (File.Exists(renamed))
390+
removes.Add(c.Path);
391+
392+
checkouts.Add(c.OriginalPath);
393+
}
288394
else
289-
modified.Add(c.Path);
395+
{
396+
checkouts.Add(c.Path);
397+
}
290398
}
291399

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

294-
if (modified.Count > 0)
295-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(modified, $"{_commit.SHA}~1");
402+
if (removes.Count > 0)
403+
await new Commands.Remove(_repo.FullPath, removes)
404+
.Use(log)
405+
.ExecAsync();
296406

297-
if (renamed.Count > 0)
298-
await new Commands.Checkout(_repo.FullPath).Use(log).MultipleFilesWithRevisionAsync(renamed, $"{_commit.SHA}~1");
407+
if (checkouts.Count > 0)
408+
await new Commands.Checkout(_repo.FullPath)
409+
.Use(log)
410+
.MultipleFilesWithRevisionAsync(checkouts, $"{_commit.SHA}~1");
299411

300412
log.Complete();
301413
}

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)