mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-09-11 22:53:00 +00:00
Reject unusable remote default branches with a --target-branch hint
Target resolution accepted any remote default HEAD that passed the ref selector grammar, then failed inside GitRunTarget::validate with a generic branch-grammar error when the default branch was something like heads/main or tags/release. Validate the default branch as a working branch name up front and point the user at --target-branch, since they passed no branch at all. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
e2d95be8b7
commit
7d050ed0f6
1 changed files with 35 additions and 1 deletions
|
|
@ -195,7 +195,7 @@ impl NativeGit {
|
|||
let records = self
|
||||
.records(root, &repository, &["HEAD".into()], cancel)
|
||||
.await?;
|
||||
default_head(&records)?
|
||||
default_target_branch(&records)?
|
||||
};
|
||||
let target = GitRunTarget {
|
||||
repo: repository.to_string(),
|
||||
|
|
@ -402,6 +402,20 @@ fn default_head(records: &str) -> anyhow::Result<(String, String)> {
|
|||
))
|
||||
}
|
||||
|
||||
/// The remote default branch as a run target. `GitRunTarget` requires a bare
|
||||
/// working branch name, which is stricter than the ref grammar `default_head`
|
||||
/// accepts for workflow acquisition; report the mismatch with the flag that
|
||||
/// resolves it instead of a generic branch-grammar error.
|
||||
fn default_target_branch(records: &str) -> anyhow::Result<(String, String)> {
|
||||
let (branch, sha) = default_head(records)?;
|
||||
if !repository::is_valid_git_branch_name(&branch) {
|
||||
bail!(
|
||||
"remote default branch `{branch}` cannot name a run target branch; pass --target-branch to select a working branch"
|
||||
);
|
||||
}
|
||||
Ok((branch, sha))
|
||||
}
|
||||
|
||||
/// The fully qualified refs a validated `--workflow-ref` may name. A bare name
|
||||
/// may be a branch or a tag; a `refs/heads/` or `refs/tags/` name is exactly
|
||||
/// one.
|
||||
|
|
@ -953,6 +967,26 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_workflow_default_target_branch_requires_a_working_branch_name() {
|
||||
let sha = "1234567890123456789012345678901234567890";
|
||||
for (head, valid) in [
|
||||
("trunk", true),
|
||||
("topic/slash", true),
|
||||
("heads/main", false),
|
||||
("tags/release", false),
|
||||
(sha, false),
|
||||
] {
|
||||
let records = format!("ref: refs/heads/{head}\tHEAD\n{sha}\tHEAD\n");
|
||||
assert_eq!(default_head(&records).unwrap().0, head);
|
||||
let target = default_target_branch(&records);
|
||||
assert_eq!(target.is_ok(), valid, "{head}");
|
||||
if !valid {
|
||||
assert!(target.unwrap_err().to_string().contains("--target-branch"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_workflow_matches_records_exactly_and_rejects_host_symlinks() {
|
||||
let sha = "1234567890123456789012345678901234567890";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue