use super::half_push::reviewed_target;
use balls::error::Result;
use balls::store::Store;
use balls::{git, git_state};
use std::path::Path;
pub(super) fn push_recorded_targets(store: &Store, remote: &str, repo_main: &str) -> Result<()> {
let subjects = git_state::log_subjects(&store.state_worktree_dir(), "balls/tasks")?;
let mut seen = std::collections::HashSet::new();
for subj in &subjects {
let Some((_, branch)) = reviewed_target(subj) else { continue };
if branch == repo_main || !seen.insert(branch.clone()) {
continue;
}
if !git_state::branch_exists(&store.root, &branch)
|| target_already_synced(&store.root, remote, &branch)
{
continue;
}
if let Err(e) = git::git_push(&store.root, remote, &branch) {
eprintln!("warning: failed to push per-task target branch {branch}: {e}");
}
}
Ok(())
}
fn target_already_synced(root: &Path, remote: &str, branch: &str) -> bool {
if !git_state::has_remote_branch(root, remote, branch) {
return false;
}
let local = git::git_resolve_sha(root, &format!("refs/heads/{branch}"));
let tracked = git::git_resolve_sha(root, &format!("refs/remotes/{remote}/{branch}"));
matches!((local, tracked), (Ok(l), Ok(r)) if l == r)
}