summaryrefslogtreecommitdiff
path: root/makima/src/daemon/task/manager.rs
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2026-01-29 17:22:59 +0000
committersoryu <soryu@soryu.co>2026-01-29 17:23:03 +0000
commit55bf0714a20e651ab70b1eed01ec665cfefac6b4 (patch)
treea25baeb7577f6affd85ae34718a175f3a659af88 /makima/src/daemon/task/manager.rs
parent4f1d67797dd56046665b772702b6b38fda9aa039 (diff)
downloadsoryu-55bf0714a20e651ab70b1eed01ec665cfefac6b4.tar.gz
soryu-55bf0714a20e651ab70b1eed01ec665cfefac6b4.zip
Rename to command mode and update worktree to show committed changes
Diffstat (limited to 'makima/src/daemon/task/manager.rs')
-rw-r--r--makima/src/daemon/task/manager.rs90
1 files changed, 78 insertions, 12 deletions
diff --git a/makima/src/daemon/task/manager.rs b/makima/src/daemon/task/manager.rs
index dd133a2..1e04ca1 100644
--- a/makima/src/daemon/task/manager.rs
+++ b/makima/src/daemon/task/manager.rs
@@ -3329,7 +3329,7 @@ impl TaskManager {
&self,
task_id: Uuid,
) -> Result<(), DaemonError> {
- // Get task's worktree path and branch
+ // Get task's worktree path, branch, and base_branch
// If the task shares a supervisor's worktree, use the supervisor's worktree info
let task_info = {
let tasks = self.tasks.read().await;
@@ -3340,12 +3340,14 @@ impl TaskManager {
tasks.get(&supervisor_task_id).map(|supervisor| (
supervisor.worktree.as_ref().map(|w| w.path.clone()),
supervisor.worktree.as_ref().map(|w| w.branch.clone()),
+ supervisor.base_branch.clone(),
))
} else {
// Use the task's own worktree
Some((
task.worktree.as_ref().map(|w| w.path.clone()),
task.worktree.as_ref().map(|w| w.branch.clone()),
+ task.base_branch.clone(),
))
}
} else {
@@ -3353,10 +3355,10 @@ impl TaskManager {
}
};
- let (worktree_path, branch) = match task_info {
- Some((Some(path), branch)) => (Some(path), branch),
- Some((None, _)) => (None, None),
- None => (None, None),
+ let (worktree_path, branch, base_branch) = match task_info {
+ Some((Some(path), branch, base_branch)) => (Some(path), branch, base_branch),
+ Some((None, _, _)) => (None, None, None),
+ None => (None, None, None),
};
if worktree_path.is_none() {
@@ -3419,7 +3421,7 @@ impl TaskManager {
.output()
.await;
- let status_lines: Vec<(String, String)> = match status_output {
+ let uncommitted_status_lines: Vec<(String, String)> = match status_output {
Ok(output) if output.status.success() => {
String::from_utf8_lossy(&output.stdout)
.lines()
@@ -3436,14 +3438,78 @@ impl TaskManager {
_ => vec![],
};
- // Get numstat for line counts (staged + unstaged)
- let numstat_output = tokio::process::Command::new("git")
- .current_dir(&path)
- .args(["diff", "HEAD", "--numstat"])
- .output()
- .await;
+ // If there are uncommitted changes, use them. Otherwise, compare against base branch.
+ // Track effective_base_branch for reuse in numstat query
+ let (status_lines, effective_base_for_diff) = if !uncommitted_status_lines.is_empty() {
+ (uncommitted_status_lines, None)
+ } else {
+ // No uncommitted changes - try to get committed changes vs base branch
+ // First, try to detect the base branch if not provided
+ let effective_base_branch = if let Some(ref base) = base_branch {
+ Some(base.clone())
+ } else {
+ // Auto-detect the default branch
+ self.worktree_manager.detect_default_branch(&path).await.ok()
+ };
+
+ if let Some(ref base) = effective_base_branch {
+ // Get committed changes using git diff --name-status
+ let diff_base = format!("origin/{}...HEAD", base);
+ let name_status_output = tokio::process::Command::new("git")
+ .current_dir(&path)
+ .args(["diff", "--name-status", &diff_base])
+ .output()
+ .await;
+
+ let committed_status_lines: Vec<(String, String)> = match name_status_output {
+ Ok(output) if output.status.success() => {
+ String::from_utf8_lossy(&output.stdout)
+ .lines()
+ .filter_map(|line| {
+ let parts: Vec<&str> = line.splitn(2, '\t').collect();
+ if parts.len() >= 2 {
+ let status = parts[0].trim().to_string();
+ let file_path = parts[1].to_string();
+ Some((file_path, status))
+ } else {
+ None
+ }
+ })
+ .collect()
+ }
+ _ => vec![],
+ };
+ if !committed_status_lines.is_empty() {
+ (committed_status_lines, Some(base.clone()))
+ } else {
+ (vec![], None)
+ }
+ } else {
+ (vec![], None)
+ }
+ };
+
+ // Get numstat for line counts
+ // If we have effective_base_for_diff, compare against origin/{base_branch}
+ // Otherwise compare against HEAD for uncommitted changes
let mut file_stats: std::collections::HashMap<String, (i32, i32)> = std::collections::HashMap::new();
+
+ let numstat_output = if let Some(ref base) = effective_base_for_diff {
+ let diff_base = format!("origin/{}...HEAD", base);
+ tokio::process::Command::new("git")
+ .current_dir(&path)
+ .args(["diff", "--numstat", &diff_base])
+ .output()
+ .await
+ } else {
+ tokio::process::Command::new("git")
+ .current_dir(&path)
+ .args(["diff", "HEAD", "--numstat"])
+ .output()
+ .await
+ };
+
if let Ok(output) = numstat_output {
if output.status.success() {
for line in String::from_utf8_lossy(&output.stdout).lines() {