103 lines
2.5 KiB
TypeScript
103 lines
2.5 KiB
TypeScript
import { existsSync } from 'node:fs';
|
|
import { runGit } from './branchGitCommands.js';
|
|
import {
|
|
type BranchBaseResolutionCache,
|
|
createBranchBaseResolutionCache,
|
|
} from './branchBaseRefCache.js';
|
|
import {
|
|
resolveBranchBaseCommitFromRefs,
|
|
resolveMergeBase,
|
|
} from './branchBaseCandidateResolver.js';
|
|
import {
|
|
readCommitSubject,
|
|
resolveBranchEntryPointFromReflog,
|
|
} from './branchEntryPointResolver.js';
|
|
|
|
type FirstTaktCommit = {
|
|
subject: string;
|
|
};
|
|
|
|
type FindFirstTaktCommitOptions = {
|
|
baseCommit?: string;
|
|
cache?: BranchBaseResolutionCache;
|
|
};
|
|
|
|
function parseFirstCommitLine(output: string): FirstTaktCommit | null {
|
|
if (!output) {
|
|
return null;
|
|
}
|
|
|
|
const firstLine = output.split('\n')[0];
|
|
if (!firstLine) {
|
|
return null;
|
|
}
|
|
|
|
const tabIndex = firstLine.indexOf('\t');
|
|
if (tabIndex === -1) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
subject: firstLine.slice(tabIndex + 1),
|
|
};
|
|
}
|
|
|
|
export function resolveGitCwd(cwd: string, worktreePath?: string): string {
|
|
return worktreePath && existsSync(worktreePath) ? worktreePath : cwd;
|
|
}
|
|
|
|
export { createBranchBaseResolutionCache, resolveMergeBase };
|
|
export type { BranchBaseResolutionCache };
|
|
|
|
export function findFirstTaktCommit(
|
|
gitCwd: string,
|
|
defaultBranch: string,
|
|
branch: string,
|
|
options?: FindFirstTaktCommitOptions,
|
|
): FirstTaktCommit | null {
|
|
let baseCommit: string;
|
|
if (options?.baseCommit) {
|
|
baseCommit = options.baseCommit;
|
|
} else {
|
|
const entryPoint = resolveBranchEntryPointFromReflog(gitCwd, branch);
|
|
if (entryPoint) {
|
|
const subject = readCommitSubject(gitCwd, entryPoint.firstCommit);
|
|
return {
|
|
subject,
|
|
};
|
|
}
|
|
|
|
const resolvedFromRefs = resolveBranchBaseCommitFromRefs(gitCwd, defaultBranch, branch, options?.cache);
|
|
baseCommit = resolvedFromRefs ? resolvedFromRefs : resolveMergeBase(gitCwd, defaultBranch, branch);
|
|
}
|
|
|
|
const output = runGit(gitCwd, [
|
|
'log',
|
|
'--format=%H\t%s',
|
|
'--reverse',
|
|
'--first-parent',
|
|
'--grep=^takt:',
|
|
`${baseCommit}..${branch}`,
|
|
]);
|
|
|
|
return parseFirstCommitLine(output);
|
|
}
|
|
|
|
export function resolveBranchBaseCommit(
|
|
gitCwd: string,
|
|
defaultBranch: string,
|
|
branch: string,
|
|
cache?: BranchBaseResolutionCache,
|
|
): string {
|
|
const entryPoint = resolveBranchEntryPointFromReflog(gitCwd, branch);
|
|
if (entryPoint) {
|
|
return entryPoint.baseCommit;
|
|
}
|
|
|
|
const baseCommitFromRefs = resolveBranchBaseCommitFromRefs(gitCwd, defaultBranch, branch, cache);
|
|
if (baseCommitFromRefs) {
|
|
return baseCommitFromRefs;
|
|
}
|
|
return resolveMergeBase(gitCwd, defaultBranch, branch);
|
|
}
|