Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,18 +210,20 @@ Examples:
Examples:
ez submit
ez submit --draft
ez submit --no-draft
ez submit --repo owner/repo
ez submit --remote fork --repo owner/repo

Note: --draft only affects newly created PRs. Existing PRs are not changed.
--no-draft creates new PRs as ready AND marks existing draft PRs as ready.
--remote and --repo apply to the first (bottom) branch only; children inherit.
Use `ez ready` to undraft an existing PR.")]
Use `ez ready` to undraft a single PR, or `ez submit --no-draft` for the whole stack.")]
Submit {
/// Create draft PRs (only affects new PRs, not existing ones)
#[arg(long)]
draft: bool,

/// Override draft config to create ready-for-review PRs
/// Override draft config and mark all PRs in the stack as ready for review
#[arg(long)]
no_draft: bool,

Expand Down
38 changes: 34 additions & 4 deletions src/cmd/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,16 @@ pub fn push_or_update_pr(

// Detect cross-repo repoint: if the target repo for the new PR differs from
// where the existing PR lives, close the old and create in the new repo.
// Target repo: --repo override > branch's target_pr_repo (set by sync) > parent's effective repo.
//
// Repoint triggers:
// 1. --repo CLI override targets a different repo
// 2. target_pr_repo hint (set by sync when parent was merged)
// 3. Parent's effective_pr_repo differs AND parent's PR was merged
// (the child should follow to the repo where the parent landed).
//
// When the parent is still an active managed branch with an open PR,
// a repo mismatch is intentional (fork workflow: child on fork, parent
// PR on upstream) and should NOT trigger repoint.
let (existing_pr, effective_repo, did_repoint) = if let Some(ref pr) = existing_pr {
let pr_current_repo = lookup_repo.clone();
let target_pr_repo_hint = state
Expand All @@ -264,9 +273,30 @@ pub fn push_or_update_pr(
let target_repo = if resolved_override.is_some() {
resolved_override.clone()
} else {
target_pr_repo_hint
.or_else(|| state.effective_pr_repo(parent))
.or_else(|| effective_repo.clone())
target_pr_repo_hint.or_else(|| {
// Infer from parent only when the parent's PR has been merged.
// Check: parent is either trunk (removed from stack) or its PR
// is merged/closed. If parent still has an open PR, the repo
// mismatch is intentional (fork workflow).
let parent_pr_merged = if state.is_trunk(parent) {
true // parent was removed from stack after merge
} else if let Ok(parent_meta) = state.get_branch(parent) {
parent_meta.pr_number.is_some_and(|_n| {
let parent_repo = state.effective_pr_repo(parent);
github::get_pr_status_in_repo(parent, parent_repo.as_deref())
.ok()
.flatten()
.is_some_and(|info| info.merged)
})
} else {
false
};
if parent_pr_merged {
state.effective_pr_repo(parent)
} else {
None
}
})
};
let needs_repoint = force_repoint || {
match (&pr_current_repo, &target_repo) {
Expand Down
23 changes: 23 additions & 0 deletions src/cmd/submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,30 @@ pub fn run(
false, // force_repoint: submit auto-detects repoint needs
)?;

// --no-draft: undraft existing draft PRs across the stack.
let pr_number = state.get_branch(branch).ok().and_then(|m| m.pr_number);
if no_draft {
if let Some(num) = pr_number {
let effective_repo = state.effective_pr_repo(branch);
// Check if the PR is currently a draft.
if let Ok(Some(pr_info)) =
github::get_pr_status_in_repo(branch, effective_repo.as_deref())
{
if pr_info.is_draft {
match github::set_pr_ready_in_repo(
num,
true,
effective_repo.as_deref(),
) {
Ok(()) => ui::info(&format!("Marked PR #{num} as ready")),
Err(e) => ui::warn(&format!(
"Could not undraft PR #{num}: {e}"
)),
}
}
}
}
}
ui::receipt(&serde_json::json!({
"cmd": "submit",
"branch": branch,
Expand Down