Merge task branch for: fix(ui): DiffModal — Commit-Range ohne HeadCommit zeigt stillen Falsch-Diff

This commit is contained in:
mika kuns
2026-06-09 23:21:56 +02:00
4 changed files with 62 additions and 2 deletions

View File

@@ -422,7 +422,7 @@
"planningBadge": { "active": "PLANUNG", "finalized": "GEPLANT" },
"taskRow": { "createdPrefix": "Erstellt {0}", "stepsText": "{0}/{1} Schritte" },
"tasksIsland": { "completedHeader": "ABGESCHLOSSEN", "completedHeaderCount": "ABGESCHLOSSEN · {0}" },
"diff": { "loadFailed": "Diff konnte nicht geladen werden: {0}", "noChanges": "Keine Änderungen anzuzeigen." },
"diff": { "loadFailed": "Diff konnte nicht geladen werden: {0}", "noChanges": "Keine Änderungen anzuzeigen.", "unavailable": "Diff nicht mehr verfügbar — Commit-Bereich unvollständig." },
"planningDiff": { "hubError": "Kombinierte Vorschau konnte nicht erstellt werden (Hub-Fehler).", "conflict": "Kombinierte Vorschau nicht möglich: Teilaufgabe {0} steht im Konflikt mit einer früheren Teilaufgabe ({1} Dateien)." },
"merge": { "commitMessage": "Merge-Aufgabe: {0}", "workerOfflineBranches": "Worker offline — Branches können nicht aufgelistet werden.", "loadBranchesFailed": "Branches konnten nicht geladen werden: {0}", "merged": "Zusammengeführt.", "conflict": "Merge-Konflikt — Ziel-Branch wiederhergestellt. Manuell oder über Fortsetzen lösen, dann erneut versuchen.", "blocked": "Blockiert: {0}", "unknownStatus": "Unbekannter Status: {0}", "mergeFailed": "Merge fehlgeschlagen: {0}" },
"conflictResolution": { "vsCodeError": "VS Code konnte nicht gestartet werden: {0}. Die Pfade sind oben aufgeführt — kopiere sie manuell.", "subtaskPrefix": "Konflikte in Teilaufgabe: {0}", "targetPrefix": "Zusammenführen in: {0}" },

View File

@@ -422,7 +422,7 @@
"planningBadge": { "active": "PLANNING", "finalized": "PLANNED" },
"taskRow": { "createdPrefix": "Created {0}", "stepsText": "{0}/{1} steps" },
"tasksIsland": { "completedHeader": "COMPLETED", "completedHeaderCount": "COMPLETED · {0}" },
"diff": { "loadFailed": "Failed to load diff: {0}", "noChanges": "No changes to show." },
"diff": { "loadFailed": "Failed to load diff: {0}", "noChanges": "No changes to show.", "unavailable": "Diff no longer available — commit range incomplete." },
"planningDiff": { "hubError": "Could not build combined preview (hub error).", "conflict": "Cannot build combined preview: subtask {0} conflicts with an earlier subtask ({1} files)." },
"merge": { "commitMessage": "Merge task: {0}", "workerOfflineBranches": "Worker offline — cannot list branches.", "loadBranchesFailed": "Failed to load branches: {0}", "merged": "Merged.", "conflict": "Merge conflict — target branch restored. Resolve manually or via Continue, then retry.", "blocked": "Blocked: {0}", "unknownStatus": "Unknown status: {0}", "mergeFailed": "Merge failed: {0}" },
"conflictResolution": { "vsCodeError": "Could not launch VS Code: {0}. Paths are listed above — copy them manually.", "subtaskPrefix": "Conflicts in subtask: {0}", "targetPrefix": "Merging into: {0}" },

View File

@@ -110,6 +110,12 @@ public sealed partial class DiffModalViewModel : ViewModelBase
Files.Clear();
StatusMessage = null;
if (FromCommitRange && (BaseRef is null || HeadCommit is null))
{
StatusMessage = Loc.T("vm.diff.unavailable");
return;
}
string raw;
try
{

View File

@@ -0,0 +1,54 @@
using System.IO;
using ClaudeDo.Localization;
using ClaudeDo.Ui.Localization;
using ClaudeDo.Ui.ViewModels.Modals;
namespace ClaudeDo.Ui.Tests.ViewModels;
public class DiffModalViewModelTests
{
public DiffModalViewModelTests()
{
var dir = AppContext.BaseDirectory;
while (dir is not null && !Directory.Exists(Path.Combine(dir, "src", "ClaudeDo.Localization", "locales")))
dir = Path.GetDirectoryName(dir);
Loc.Current = new Localizer(
LocaleStore.Load(Path.Combine(dir!, "src", "ClaudeDo.Localization", "locales")), "en");
}
[Fact]
public async Task LoadAsync_CommitRange_NullHeadCommit_ShowsUnavailableState()
{
var vm = new DiffModalViewModel(null!)
{
WorktreePath = "/some/repo",
BaseRef = "abc123",
HeadCommit = null,
FromCommitRange = true,
};
await vm.LoadAsync();
Assert.Empty(vm.Files);
Assert.NotNull(vm.StatusMessage);
Assert.Contains("no longer available", vm.StatusMessage, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public async Task LoadAsync_CommitRange_NullBaseRef_ShowsUnavailableState()
{
var vm = new DiffModalViewModel(null!)
{
WorktreePath = "/some/repo",
BaseRef = null,
HeadCommit = "def456",
FromCommitRange = true,
};
await vm.LoadAsync();
Assert.Empty(vm.Files);
Assert.NotNull(vm.StatusMessage);
Assert.Contains("no longer available", vm.StatusMessage, StringComparison.OrdinalIgnoreCase);
}
}