perf(release): 复用分支补丁核对并固定比较快照

This commit is contained in:
2026-10-12 20:27:22 +08:00
parent 3cf079f527
commit f59dd33097
+18 -5
View File
@@ -42,6 +42,15 @@ export function inspectRepository(repository, { fetch = false } = {}) {
const output = git(repository.path, 'for-each-ref', '--format=%(refname)%00%(objectname)%00%(symref)', `refs/remotes/${remote}/`);
const cache = new Map();
const knownEquivalent = new Set();
const mergeBases = new Map();
const isolatedEquivalence = new Map();
const mergeBase = sha => {
if (!mergeBases.has(sha)) {
try { mergeBases.set(sha, git(repository.path, 'merge-base', result.targetSha, sha)); }
catch (error) { if (error.status === 1 && !String(error.stderr || '').trim()) mergeBases.set(sha, null); else throw error; }
}
return mergeBases.get(sha);
};
for (const line of output.split('\n').filter(Boolean)) {
const [ref, sha, symbolicRef] = line.split('\0');
if (symbolicRef || ref === targetRef) continue;
@@ -49,20 +58,24 @@ export function inspectRepository(repository, { fetch = false } = {}) {
try {
let comparison = cache.get(sha);
if (!comparison) {
const range = `${targetRef}..${ref}`;
// Pin the inventory SHAs so another fetch cannot change this comparison midway.
const range = `${result.targetSha}..${sha}`;
const ahead = Number(git(repository.path, 'rev-list', '--count', range));
comparison = { ahead, unmergedCommits: [], equivalentCommits: [], mergeCommits: [] };
if (ahead > 0) {
const cherry = git(repository.path, 'cherry', targetRef, ref);
const cherry = git(repository.path, 'cherry', result.targetSha, sha);
const equivalence = new Map(cherry.split('\n').filter(Boolean).map(line => [line.slice(2), line[0]]));
comparison.mergeCommits = commits(repository.path, range, '--merges');
for (const commit of commits(repository.path, range, '--no-merges')) {
if (equivalence.get(commit.sha) === '-') knownEquivalent.add(commit.sha);
// If the branch merged the target, Git's merge base can hide older
// upstream patches. Compare the individual incoming commit too.
if (comparison.mergeCommits.length && !knownEquivalent.has(commit.sha)) {
const isolated = git(repository.path, 'cherry', targetRef, commit.sha);
for (const line of isolated.split('\n')) if (line.startsWith('- ')) knownEquivalent.add(line.slice(2));
if (comparison.mergeCommits.length && !knownEquivalent.has(commit.sha) && mergeBase(sha) !== mergeBase(commit.sha)) {
if (!isolatedEquivalence.has(commit.sha)) {
const isolated = git(repository.path, 'cherry', result.targetSha, commit.sha);
isolatedEquivalence.set(commit.sha, isolated.split('\n').includes('- ' + commit.sha));
}
if (isolatedEquivalence.get(commit.sha)) knownEquivalent.add(commit.sha);
}
// A changed SHA alone does not mean the change is absent from the target branch.
const list = knownEquivalent.has(commit.sha) ? comparison.equivalentCommits : comparison.unmergedCommits;