dont push empty bundles

This commit is contained in:
darshanime 2026-07-13 14:09:25 +05:30
parent 3f843303fa
commit 7a2ed3a023
2 changed files with 116 additions and 58 deletions

83
dist/index.js vendored
View file

@ -41983,42 +41983,69 @@ async function uploadBranchDelta(settings) {
} }
const repoPath = settings.repositoryPath; const repoPath = settings.repositoryPath;
const sha = settings.commit; const sha = settings.commit;
const grant = await requestBranchUpload(plan.repoKey, plan.refKey, sha); await exec_exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha]);
if (grant.kind !== 'grant') {
info(`Branch delta upload skipped (${grant.kind})`);
return;
}
if (!(await hasBaseRefs(repoPath))) {
info('No base refs to diff against; branch delta skipped');
return;
}
const tmp = tempBundlePath('branch');
try { try {
await exec_exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha]); if (!(await hasBaseRefs(repoPath))) {
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo info('No base refs to diff against; branch delta skipped');
// has hundreds of base refs, and that many args overflows the Windows command-line return;
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the }
// same base-relative (order-free) delta. // If the tip is already in the base there is no delta to roll, and `git bundle
await exec_exec('git', [ // create` errors on an empty range ("Refusing to create empty bundle"). Detect it
'-C', // first — and before taking the server lock, so an empty delta never blocks the
repoPath, // other jobs racing the same branch.
'bundle', if (await branchDeltaIsEmpty(repoPath)) {
'create', info('Tip already contained in the base; no branch delta to upload');
tmp, return;
UPLOAD_TIP_REF, }
'--not', const grant = await requestBranchUpload(plan.repoKey, plan.refKey, sha);
`--glob=${BASE_REFNS}/*` if (grant.kind !== 'grant') {
]); info(`Branch delta upload skipped (${grant.kind})`);
await httpPut(grant.url, tmp); return;
info(`Uploaded branch delta for '${plan.refKey}'`); }
const tmp = tempBundlePath('branch');
try {
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo
// has hundreds of base refs, and that many args overflows the Windows command-line
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the
// same base-relative (order-free) delta.
await exec_exec('git', [
'-C',
repoPath,
'bundle',
'create',
tmp,
UPLOAD_TIP_REF,
'--not',
`--glob=${BASE_REFNS}/*`
]);
await httpPut(grant.url, tmp);
info(`Uploaded branch delta for '${plan.refKey}'`);
}
finally {
await external_fs_namespaceObject.promises.rm(tmp, { force: true });
}
} }
finally { finally {
await external_fs_namespaceObject.promises.rm(tmp, { force: true });
await exec_exec('git', ['-C', repoPath, 'update-ref', '-d', UPLOAD_TIP_REF], { await exec_exec('git', ['-C', repoPath, 'update-ref', '-d', UPLOAD_TIP_REF], {
ignoreReturnCode: true ignoreReturnCode: true
}); });
} }
} }
// The tip's delta against the base is empty when the tip is already reachable from the
// base — nothing new to bundle.
async function branchDeltaIsEmpty(repoPath) {
let out = '';
await exec_exec('git', [
'-C',
repoPath,
'rev-list',
'--count',
UPLOAD_TIP_REF,
'--not',
`--glob=${BASE_REFNS}/*`
], { silent: true, listeners: { stdout: (d) => (out += d.toString()) } });
return out.trim() === '0';
}
// Whether any base ref was seeded — the guard that keeps the delta base-relative. The // Whether any base ref was seeded — the guard that keeps the delta base-relative. The
// base is excluded by glob (see uploadBranchDelta), so we only need existence here. // base is excluded by glob (see uploadBranchDelta), so we only need existence here.
async function hasBaseRefs(repoPath) { async function hasBaseRefs(repoPath) {

View file

@ -248,38 +248,49 @@ async function uploadBranchDelta(settings: IGitSourceSettings): Promise<void> {
const repoPath = settings.repositoryPath const repoPath = settings.repositoryPath
const sha = settings.commit const sha = settings.commit
const grant = await api.requestBranchUpload(plan.repoKey, plan.refKey, sha) await exec.exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha])
if (grant.kind !== 'grant') {
core.info(`Branch delta upload skipped (${grant.kind})`)
return
}
if (!(await hasBaseRefs(repoPath))) {
core.info('No base refs to diff against; branch delta skipped')
return
}
const tmp = tempBundlePath('branch')
try { try {
await exec.exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha]) if (!(await hasBaseRefs(repoPath))) {
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo core.info('No base refs to diff against; branch delta skipped')
// has hundreds of base refs, and that many args overflows the Windows command-line return
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the }
// same base-relative (order-free) delta. // If the tip is already in the base there is no delta to roll, and `git bundle
await exec.exec('git', [ // create` errors on an empty range ("Refusing to create empty bundle"). Detect it
'-C', // first — and before taking the server lock, so an empty delta never blocks the
repoPath, // other jobs racing the same branch.
'bundle', if (await branchDeltaIsEmpty(repoPath)) {
'create', core.info('Tip already contained in the base; no branch delta to upload')
tmp, return
UPLOAD_TIP_REF, }
'--not',
`--glob=${BASE_REFNS}/*` const grant = await api.requestBranchUpload(plan.repoKey, plan.refKey, sha)
]) if (grant.kind !== 'grant') {
await httpPut(grant.url, tmp) core.info(`Branch delta upload skipped (${grant.kind})`)
core.info(`Uploaded branch delta for '${plan.refKey}'`) return
}
const tmp = tempBundlePath('branch')
try {
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo
// has hundreds of base refs, and that many args overflows the Windows command-line
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the
// same base-relative (order-free) delta.
await exec.exec('git', [
'-C',
repoPath,
'bundle',
'create',
tmp,
UPLOAD_TIP_REF,
'--not',
`--glob=${BASE_REFNS}/*`
])
await httpPut(grant.url, tmp)
core.info(`Uploaded branch delta for '${plan.refKey}'`)
} finally {
await fs.promises.rm(tmp, {force: true})
}
} finally { } finally {
await fs.promises.rm(tmp, {force: true})
await exec.exec( await exec.exec(
'git', 'git',
['-C', repoPath, 'update-ref', '-d', UPLOAD_TIP_REF], ['-C', repoPath, 'update-ref', '-d', UPLOAD_TIP_REF],
@ -290,6 +301,26 @@ async function uploadBranchDelta(settings: IGitSourceSettings): Promise<void> {
} }
} }
// The tip's delta against the base is empty when the tip is already reachable from the
// base — nothing new to bundle.
async function branchDeltaIsEmpty(repoPath: string): Promise<boolean> {
let out = ''
await exec.exec(
'git',
[
'-C',
repoPath,
'rev-list',
'--count',
UPLOAD_TIP_REF,
'--not',
`--glob=${BASE_REFNS}/*`
],
{silent: true, listeners: {stdout: (d: Buffer) => (out += d.toString())}}
)
return out.trim() === '0'
}
// Whether any base ref was seeded — the guard that keeps the delta base-relative. The // Whether any base ref was seeded — the guard that keeps the delta base-relative. The
// base is excluded by glob (see uploadBranchDelta), so we only need existence here. // base is excluded by glob (see uploadBranchDelta), so we only need existence here.
async function hasBaseRefs(repoPath: string): Promise<boolean> { async function hasBaseRefs(repoPath: string): Promise<boolean> {