fix(merge): pass the stash consent to the conflict resolver so it opens on a dirty target
The resolver restarts the merge via StartConflictMerge, which had no autostash. After a stash-retry approve reported 'conflict', the restart hit the same dirty target, got 'dirty_target' and the resolver silently never opened. Thread the consent through the hub, client, coordinator and resolver; surface a refusal in the footer instead of dropping it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
ff7197c410
commit
feb0afa33a
@@ -30,9 +30,14 @@ public class ConflictResolverViewModelTests
|
||||
public string? ContinuedPlanningParent;
|
||||
public string? AbortedPlanningParent;
|
||||
|
||||
public override Task<MergeResultDto> StartConflictMergeAsync(string taskId, string targetBranch)
|
||||
/// <summary>Models a target working tree with uncommitted changes: refused unless the caller consented to the stash.</summary>
|
||||
public bool DirtyTarget;
|
||||
|
||||
public override Task<MergeResultDto> StartConflictMergeAsync(string taskId, string targetBranch, bool autostash = false)
|
||||
{
|
||||
StartCalled = true;
|
||||
if (DirtyTarget && !autostash)
|
||||
return Task.FromResult(new MergeResultDto("dirty_target", System.Array.Empty<string>(), "target working tree has uncommitted changes"));
|
||||
return Task.FromResult(new MergeResultDto("conflict", new[] { "README.md" }, null));
|
||||
}
|
||||
|
||||
@@ -63,6 +68,19 @@ public class ConflictResolverViewModelTests
|
||||
public override Task AbortConflictMergeAsync(string taskId) { Aborted = true; return Task.CompletedTask; }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenAsync_DirtyTarget_OpensOnlyWithStashConsent()
|
||||
{
|
||||
// Regression: a dirty target refused the resolver's own merge restart, so it never opened.
|
||||
var refused = new ConflictResolverViewModel(new FakeWorker { DirtyTarget = true }, "task-1");
|
||||
Assert.False(await refused.OpenAsync("main"));
|
||||
Assert.Equal("target working tree has uncommitted changes", refused.Error);
|
||||
|
||||
var consented = new ConflictResolverViewModel(new FakeWorker { DirtyTarget = true }, "task-1");
|
||||
Assert.True(await consented.OpenAsync("main", autostash: true));
|
||||
Assert.Null(consented.Error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenAsync_LoadsConflicts_AndBlocksContinueUntilResolved()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user