backport
Version:
A CLI tool that automates the process of backporting commits
86 lines • 3.25 kB
JavaScript
import { SpawnError, spawnPromise } from '../child-process-promisified.js';
import { getRepoPath } from '../env.js';
import { getShortSha } from '../github/commit-formatters.js';
import { logger } from '../logger.js';
export async function gitAddAll({ options }) {
const cwd = getRepoPath(options);
return spawnPromise('git', ['add', '--all'], cwd);
}
async function gitCommit({ options, commitAuthor, message, }) {
const cwd = getRepoPath(options);
return spawnPromise('git', [
`-c`,
`user.name="${commitAuthor.name}"`,
`-c`,
`user.email="${commitAuthor.email}"`,
'commit',
...(message ? [`--message=${message}`] : ['--no-edit']),
...(options.noVerify ? ['--no-verify'] : []), // bypass pre-commit and commit-msg hooks
...(options.signoff ? ['--signoff'] : []),
], cwd);
}
export async function commitChanges({ options, commit, commitAuthor, }) {
try {
await gitCommit({ options, commitAuthor });
}
catch (error) {
const isSpawnError = error instanceof SpawnError;
if (isSpawnError) {
if (error.context.stdout.includes('nothing to commit')) {
logger.info(`Could not run "git commit". Probably because the changes were manually committed`, error);
return;
}
// manually set the commit message if the inferred commit message is empty
// this can happen if the user runs `git reset HEAD` and thereby aborts the cherrypick process
if (error.context.stderr.includes('Aborting commit due to empty commit message')) {
await gitCommit({
options,
commitAuthor,
message: commit.sourceCommit.message,
});
return;
}
}
// rethrow error if it can't be handled
throw error;
}
}
export async function getIsCommitInBranch(options, commitSha) {
try {
const cwd = getRepoPath(options);
await spawnPromise('git', ['merge-base', '--is-ancestor', commitSha, 'HEAD'], cwd);
return true;
}
catch (error) {
logger.warn('getIsCommitInBranch threw', error);
return false;
}
}
export async function getIsMergeCommit(options, sha) {
const cwd = getRepoPath(options);
try {
const res = await spawnPromise('git', ['rev-list', '-1', '--merges', `${sha}~1..${sha}`], cwd);
return res.stdout !== '';
}
catch (error) {
const shortSha = getShortSha(sha);
logger.info(`Could not determine if ${shortSha} is a merge commit. Will assume it is not`, error);
return false;
}
}
export async function getShasInMergeCommit(options, sha) {
try {
const cwd = getRepoPath(options);
const res = await spawnPromise('git', ['--no-pager', 'log', `${sha}^1..${sha}^2`, '--pretty=format:%H'], cwd);
return res.stdout.split('\n');
}
catch (error) {
const isSpawnError = error instanceof SpawnError;
// swallow error
if (isSpawnError && error.context.code === 128) {
return [];
}
throw error;
}
}
//# sourceMappingURL=commit.js.map