fix(ui): resizable modal, drop branch column, show committed diff

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-05-19 11:08:52 +02:00
parent ca71275fc4
commit bc15c16e44
8 changed files with 55 additions and 26 deletions

View File

@@ -20,6 +20,7 @@ public sealed partial class WorktreeModalViewModel : ViewModelBase
public ObservableCollection<WorktreeNodeViewModel> Root { get; } = new();
[ObservableProperty] private string _worktreePath = "";
[ObservableProperty] private string? _baseCommit;
// Set by the view (same pattern as DiffModalViewModel.CloseAction)
public Action? CloseAction { get; set; }
@@ -37,7 +38,13 @@ public sealed partial class WorktreeModalViewModel : ViewModelBase
Root.Clear();
string stdout;
try { stdout = await _git.GetStatusPorcelainAsync(WorktreePath, ct); }
bool committedMode = !string.IsNullOrEmpty(BaseCommit);
try
{
stdout = committedMode
? await _git.GetCommittedFilesAsync(WorktreePath, BaseCommit!, ct)
: await _git.GetStatusPorcelainAsync(WorktreePath, ct);
}
catch { return; }
if (string.IsNullOrWhiteSpace(stdout)) return;
@@ -46,14 +53,27 @@ public sealed partial class WorktreeModalViewModel : ViewModelBase
foreach (var line in stdout.Split('\n', StringSplitOptions.RemoveEmptyEntries))
{
if (line.Length < 4) continue;
string? path;
string? status;
// porcelain format: XY<space>path (XY = two-char status)
var xy = line[..2];
// Pick staged char first, fall back to unstaged
var statusChar = xy[0] != ' ' ? xy[0] : xy[1];
var status = statusChar != ' ' ? statusChar.ToString() : null;
var path = line[3..].Trim().Replace('\\', '/');
if (committedMode)
{
// diff --name-status format: <status>\t<path>
var tab = line.IndexOf('\t');
if (tab < 0) continue;
var statusChar = line[0];
status = statusChar != ' ' ? statusChar.ToString() : null;
path = line[(tab + 1)..].Trim().Replace('\\', '/');
}
else
{
// porcelain format: XY<space>path
if (line.Length < 4) continue;
var xy = line[..2];
var statusChar = xy[0] != ' ' ? xy[0] : xy[1];
status = statusChar != ' ' ? statusChar.ToString() : null;
path = line[3..].Trim().Replace('\\', '/');
}
var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
if (segments.Length == 0) continue;