huskies: merge 1176 bug base_branch fallback hardcodes master instead of auto-detecting
This commit is contained in:
@@ -17,6 +17,14 @@ use crate::config::ProjectConfig;
|
||||
/// causing `git cherry-pick merge-queue/…` to fail with "bad revision".
|
||||
static MERGE_LOCK: Mutex<()> = Mutex::new(());
|
||||
|
||||
/// Resolve the base branch for `project_root` from config, or auto-detect it.
|
||||
fn resolve_base_branch(project_root: &Path) -> String {
|
||||
let configured = crate::config::ProjectConfig::load(project_root)
|
||||
.ok()
|
||||
.and_then(|c| c.base_branch);
|
||||
crate::worktree::resolve_base_branch(project_root, configured.as_deref())
|
||||
}
|
||||
|
||||
pub(crate) fn run_squash_merge(
|
||||
project_root: &Path,
|
||||
branch: &str,
|
||||
@@ -31,10 +39,7 @@ pub(crate) fn run_squash_merge(
|
||||
// A zero-commit branch produces an empty squash and a silent "nothing to
|
||||
// commit" failure. Catch it early with a grep-able error before any merge
|
||||
// work starts.
|
||||
let base_branch = crate::config::ProjectConfig::load(project_root)
|
||||
.ok()
|
||||
.and_then(|c| c.base_branch.clone())
|
||||
.unwrap_or_else(|| "master".to_string());
|
||||
let base_branch = resolve_base_branch(project_root);
|
||||
|
||||
let ahead_out = Command::new("git")
|
||||
.args(["rev-list", "--count", &format!("{base_branch}..{branch}")])
|
||||
@@ -316,11 +321,6 @@ pub(crate) fn run_squash_merge(
|
||||
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
let base_branch = crate::config::ProjectConfig::load(project_root)
|
||||
.ok()
|
||||
.and_then(|c| c.base_branch.clone())
|
||||
.unwrap_or_else(|| "master".to_string());
|
||||
|
||||
if current_branch != base_branch {
|
||||
all_output.push_str(&format!(
|
||||
"=== VERIFICATION FAILED: expected branch '{base_branch}' but HEAD is on \
|
||||
|
||||
@@ -178,6 +178,79 @@ async fn squash_merge_clean_merge_succeeds() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn squash_merge_succeeds_on_main_based_repo_with_base_branch_unset() {
|
||||
use std::fs;
|
||||
use tempfile::tempdir;
|
||||
|
||||
let tmp = tempdir().unwrap();
|
||||
let repo = tmp.path();
|
||||
|
||||
// Repo whose default branch is `main` — no `master` branch exists at all,
|
||||
// and no `.huskies/project.toml` sets `base_branch`. run_squash_merge must
|
||||
// auto-detect `main` instead of assuming `master` (bug 1176).
|
||||
Command::new("git")
|
||||
.args(["init", "-b", "main"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["commit", "--allow-empty", "-m", "init"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
Command::new("git")
|
||||
.args(["checkout", "-b", "feature/story-main_test"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
fs::write(repo.join("new_file.txt"), "new content").unwrap();
|
||||
Command::new("git")
|
||||
.args(["add", "."])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["commit", "-m", "add new file"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
Command::new("git")
|
||||
.args(["checkout", "main"])
|
||||
.current_dir(repo)
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
let result = run_squash_merge(repo, "feature/story-main_test", "main_test").unwrap();
|
||||
|
||||
assert!(
|
||||
matches!(
|
||||
result,
|
||||
super::MergeResult::Success {
|
||||
conflicts_resolved: false,
|
||||
..
|
||||
}
|
||||
),
|
||||
"clean merge should succeed on a main-based repo; got: {result:?}"
|
||||
);
|
||||
assert!(
|
||||
repo.join("new_file.txt").exists(),
|
||||
"merged file should exist on main"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn squash_merge_nonexistent_branch_fails() {
|
||||
use tempfile::tempdir;
|
||||
|
||||
@@ -189,10 +189,10 @@ pub(super) async fn run_agent_spawn(
|
||||
let wt_info = {
|
||||
let wt_path = crate::worktree::worktree_path(&project_root_clone, &sid);
|
||||
let branch = format!("feature/story-{sid}");
|
||||
let base_branch = config_clone
|
||||
.base_branch
|
||||
.clone()
|
||||
.unwrap_or_else(|| crate::worktree::detect_base_branch(&project_root_clone));
|
||||
let base_branch = crate::worktree::resolve_base_branch(
|
||||
&project_root_clone,
|
||||
config_clone.base_branch.as_deref(),
|
||||
);
|
||||
let deadline =
|
||||
tokio::time::Instant::now() + std::time::Duration::from_secs(worktree_wait_secs);
|
||||
loop {
|
||||
@@ -260,6 +260,7 @@ pub(super) async fn run_agent_spawn(
|
||||
}
|
||||
|
||||
let (command, mut args, mut prompt) = match config_clone.render_agent_args(
|
||||
&project_root_clone,
|
||||
&wt_path_str,
|
||||
&sid,
|
||||
Some(&aname),
|
||||
|
||||
Reference in New Issue
Block a user