feat(cli): add branch push check before PR creation
This commit is contained in:
@@ -23,6 +23,8 @@ import type { Config } from "./src/types";
|
||||
import {
|
||||
getDefaultBranch,
|
||||
getBranchName,
|
||||
getBranchPushStatus,
|
||||
pushCurrentBranch,
|
||||
getBranchCommits,
|
||||
getBranchDiff,
|
||||
detectPlatform,
|
||||
@@ -524,6 +526,30 @@ async function handlePR(draft: boolean): Promise<void> {
|
||||
` ${commits.length} commit${commits.length > 1 ? "s" : ""} on this branch`,
|
||||
);
|
||||
|
||||
const pushStatus = await getBranchPushStatus();
|
||||
if (!pushStatus.pushed) {
|
||||
const target = pushStatus.upstream ?? `origin/${branchName}`;
|
||||
const answer = await ask(
|
||||
` Branch is not pushed to ${CYAN}${target}${RESET}. Push now? [${GREEN}Y${RESET}/n] `,
|
||||
);
|
||||
|
||||
if (answer.toLowerCase() === "n") {
|
||||
console.log(" Aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(` Pushing ${CYAN}${branchName}${RESET}...`);
|
||||
try {
|
||||
await pushCurrentBranch(branchName, pushStatus.upstream);
|
||||
console.log(` ${GREEN}Pushed ${branchName}.${RESET}`);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
` ${RED}Push failed: ${err instanceof Error ? err.message : err}${RESET}`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const diff = await getBranchDiff(baseBranch);
|
||||
if (!diff) {
|
||||
console.error(` ${RED}Error: No diff from base branch.${RESET}`);
|
||||
|
||||
@@ -25,6 +25,38 @@ export async function getBranchName(): Promise<string> {
|
||||
return result.trim();
|
||||
}
|
||||
|
||||
export async function getBranchPushStatus(): Promise<{
|
||||
pushed: boolean;
|
||||
upstream: string | null;
|
||||
}> {
|
||||
try {
|
||||
const upstream = (await Bun.$`git rev-parse --abbrev-ref --symbolic-full-name @{u}`.quiet().text()).trim();
|
||||
const localHead = (await Bun.$`git rev-parse HEAD`.quiet().text()).trim();
|
||||
const remoteHead = (await Bun.$`git rev-parse @{u}`.quiet().text()).trim();
|
||||
return { pushed: localHead === remoteHead, upstream };
|
||||
} catch {
|
||||
return { pushed: false, upstream: null };
|
||||
}
|
||||
}
|
||||
|
||||
export async function pushCurrentBranch(branch: string, upstream: string | null): Promise<void> {
|
||||
const args = upstream
|
||||
? ["push"]
|
||||
: ["push", "-u", "origin", branch];
|
||||
|
||||
const proc = Bun.spawn(["git", ...args], {
|
||||
stdout: "pipe",
|
||||
stderr: "pipe",
|
||||
});
|
||||
const exitCode = await proc.exited;
|
||||
const stdout = await new Response(proc.stdout).text();
|
||||
const stderr = await new Response(proc.stderr).text();
|
||||
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(stderr.trim() || stdout.trim() || `git push failed (exit code ${exitCode})`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getBranchCommits(base: string): Promise<string[]> {
|
||||
try {
|
||||
const result =
|
||||
|
||||
Reference in New Issue
Block a user