UNPKG

backport

Version:

A CLI tool that automates the process of backporting commits

83 lines 3.5 kB
import { BackportError } from '../backport-error.js'; import { SpawnError, spawnPromise } from '../child-process-promisified.js'; import { getRepoPath } from '../env.js'; import { logger } from '../logger.js'; import { ora } from '../ora.js'; export async function fetchBranch(options, branch) { const cwd = getRepoPath(options); await spawnPromise('git', ['fetch', options.repoOwner, `${branch}:${branch}`, '--force'], cwd); } // How the commit flows: // ${sourceBranch} -> ${backportBranch} -> ${targetBranch} // master -> backport/7.x/pr-1234 -> 7.x export async function createBackportBranch({ options, sourceBranch, backportBranch, targetBranch, }) { const spinner = ora(options.interactive, 'Pulling latest changes').start(); const cwd = getRepoPath(options); try { await spawnPromise('git', ['reset', '--hard'], cwd); await spawnPromise('git', ['clean', '-d', '--force'], cwd); // create tmp branch. This can be necessary when fetching to the currently selected branch const tmpBranchName = '__backport_tool_tmp'; await spawnPromise('git', ['checkout', '-B', tmpBranchName], cwd); // fetch target branch await fetchBranch(options, targetBranch); // checkout backport branch and point it to target branch await spawnPromise('git', [ 'checkout', '-B', backportBranch, `${options.repoOwner}/${targetBranch}`, '--no-track', ], cwd); // delete tmp branch (if it still exists) try { await spawnPromise('git', ['branch', '-D', tmpBranchName], cwd); } catch (error) { logger.debug(`Could not delete temporary branch "${tmpBranchName}": ${error}`); } // fetch commits for source branch await fetchBranch(options, sourceBranch); } catch (error) { spinner.fail(); if (error instanceof SpawnError) { const invalidRemoteRef = error.context.stderr .toLowerCase() .match(/couldn't find remote ref (.*)/) ?.at(1); const invalidCommit = error.context.stderr .toLowerCase() .match(/'(.+) is not a commit and a branch .+ cannot be created from it/) ?.at(1); const invalidBranch = invalidRemoteRef ?? invalidCommit; if (invalidBranch) { throw new BackportError({ code: 'branch-not-found-exception', branchName: invalidBranch, }); } const invalidRefSpec = error.context.stderr .toLowerCase() .match(/invalid refspec (.*)/) ?.at(1); if (invalidRefSpec) { throw new BackportError({ code: 'branch-not-found-exception', branchName: invalidRefSpec, }); } } throw error; } spinner.succeed(); } export async function deleteBackportBranch({ options, backportBranch, }) { const spinner = ora(options.interactive).start(); const cwd = getRepoPath(options); await spawnPromise('git', ['reset', '--hard'], cwd); await spawnPromise('git', ['checkout', options.sourceBranch], cwd); await spawnPromise('git', ['branch', '--delete', '--force', backportBranch], cwd); spinner.stop(); } //# sourceMappingURL=branch.js.map