Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/commands/list/collect_progressive_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -645,12 +645,31 @@ impl Task for WorkingTreeConflictsTask {
let base = ctx.require_default_branch(Self::KIND)?;
let repo = ctx.repo();

// Quick check if working tree is dirty via git status
let status_output = repo
.run_command(&["status", "--porcelain"])
.map_err(|e| ctx.error(Self::KIND, e))?;

let is_dirty = !status_output.trim().is_empty();
// Refresh the index and check dirty state. On some systems (especially macOS),
// git's index cache may not immediately reflect file modifications made within
// the same timestamp granularity. Retry logic handles "racy git" timing issues.
let is_dirty = {
let mut attempts = 0;
loop {
// Refresh index to pick up mtime changes
let _ = repo.run_command(&["update-index", "--refresh"]);

let status_output = repo
.run_command(&["status", "--porcelain"])
.map_err(|e| ctx.error(Self::KIND, e))?;

let dirty = !status_output.trim().is_empty();

// If dirty or we've tried enough times, use this result
if dirty || attempts >= 3 {
break dirty;
}

// Wait briefly before retry (filesystem timestamp granularity issue)
std::thread::sleep(std::time::Duration::from_millis(10));
attempts += 1;
}
};

if !is_dirty {
// Clean working tree - return None to signal "use commit-based check"
Expand Down