Extract push_run_branches helper from rewind.rs and fork.rs

Both rewind_to_entry and fork_from_entry had nearly identical 25-line
blocks resolving the repo path, checking for a remote tracking branch,
and pushing run+meta refspecs. Extract Store::repo_dir() and a shared
push_run_branches() helper to eliminate the duplication.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Bryan Helmkamp 2026-03-28 01:34:24 -04:00
parent b4a7223a6d
commit c6c48b2e5e
4 changed files with 54 additions and 46 deletions

View file

@ -106,6 +106,13 @@ impl Store {
&self.repo
}
pub fn repo_dir(&self) -> &Path {
self.repo
.workdir()
.or_else(|| self.repo.path().parent())
.unwrap_or(self.repo.path())
}
/// Store bytes as a git blob.
pub fn write_blob(&self, content: &[u8]) -> Result<Oid> {
Ok(self.repo.blob(content)?)

View file

@ -202,6 +202,32 @@ pub fn push_branch(repo: &Path, remote: &str, branch: &str) -> Result<()> {
run_git_push(git_cmd(repo).args(["push", remote, branch]))
}
/// Push run and metadata branches to origin if a remote tracking branch exists.
///
/// Callers supply pre-built refspecs so they control force-push (`+` prefix).
pub fn push_run_branches(
store: &Store,
probe_branch: &str,
run_refspec: Option<&str>,
meta_refspec: &str,
label: &str,
) -> anyhow::Result<()> {
let repo_path = store.repo_dir();
let remote_ref = format!("refs/remotes/origin/{probe_branch}");
if store.repo().find_reference(&remote_ref).is_err() {
return Ok(());
}
eprintln!("Pushing {label} branches to origin...");
if let Some(refspec) = run_refspec {
push_branch(repo_path, "origin", refspec)
.map_err(|e| anyhow::anyhow!("failed to push run branch: {e}"))?;
}
push_branch(repo_path, "origin", meta_refspec)
.map_err(|e| anyhow::anyhow!("failed to push metadata branch: {e}"))?;
eprintln!("Remote refs updated.");
Ok(())
}
/// Error from [`blocking_push_with_timeout`].
pub enum BlockingPushError {
/// The git push itself failed.

View file

@ -134,29 +134,16 @@ fn fork_from_entry(
.map_err(|e| anyhow::anyhow!("failed to write metadata entries: {e}"))?;
if push {
let repo_path = store
.repo()
.workdir()
.or_else(|| store.repo().path().parent())
.unwrap_or(store.repo().path());
let source_run_branch = format!("{}{source_run_id}", crate::git::RUN_BRANCH_PREFIX);
let remote_ref = format!("refs/remotes/origin/{source_run_branch}");
let has_remote_tracking = store.repo().find_reference(&remote_ref).is_ok();
if has_remote_tracking {
eprintln!("Pushing new branches to origin...");
let run_refspec = format!("refs/heads/{new_run_branch}:refs/heads/{new_run_branch}");
crate::git::push_branch(repo_path, "origin", &run_refspec)
.map_err(|e| anyhow::anyhow!("failed to push run branch: {e}"))?;
let meta_refspec = format!("refs/heads/{new_meta_branch}:refs/heads/{new_meta_branch}");
crate::git::push_branch(repo_path, "origin", &meta_refspec)
.map_err(|e| anyhow::anyhow!("failed to push metadata branch: {e}"))?;
eprintln!("Remote refs updated.");
}
let run_refspec = format!("refs/heads/{new_run_branch}:refs/heads/{new_run_branch}");
let meta_refspec = format!("refs/heads/{new_meta_branch}:refs/heads/{new_meta_branch}");
crate::git::push_run_branches(
store,
&source_run_branch,
Some(&run_refspec),
&meta_refspec,
"new",
)?;
}
Ok(new_run_id)

View file

@ -280,30 +280,18 @@ fn rewind_to_entry(store: &Store, run_id: &str, entry: &TimelineEntry, push: boo
}
if push {
let repo_path = store
.repo()
.workdir()
.or_else(|| store.repo().path().parent())
.unwrap_or(store.repo().path());
let remote_ref = format!("refs/remotes/origin/{run_branch}");
let has_remote_tracking = store.repo().find_reference(&remote_ref).is_ok();
if has_remote_tracking {
eprintln!("Force-pushing rewound branches to origin...");
if entry.run_commit_sha.is_some() {
let refspec = format!("+refs/heads/{run_branch}:refs/heads/{run_branch}");
crate::git::push_branch(repo_path, "origin", &refspec)
.map_err(|e| anyhow::anyhow!("failed to push run branch: {e}"))?;
}
let meta_refspec = format!("+refs/heads/{meta_branch}:refs/heads/{meta_branch}");
crate::git::push_branch(repo_path, "origin", &meta_refspec)
.map_err(|e| anyhow::anyhow!("failed to push metadata branch: {e}"))?;
eprintln!("Remote refs updated.");
}
let run_refspec = entry
.run_commit_sha
.as_ref()
.map(|_| format!("+refs/heads/{run_branch}:refs/heads/{run_branch}"));
let meta_refspec = format!("+refs/heads/{meta_branch}:refs/heads/{meta_branch}");
crate::git::push_run_branches(
store,
&run_branch,
run_refspec.as_deref(),
&meta_refspec,
"rewound",
)?;
}
Ok(())