mirror of
https://github.com/actions/checkout.git
synced 2026-07-19 04:30:04 +08:00
dont push empty bundles
This commit is contained in:
parent
3f843303fa
commit
7a2ed3a023
2 changed files with 116 additions and 58 deletions
37
dist/index.js
vendored
37
dist/index.js
vendored
|
|
@ -41983,18 +41983,27 @@ async function uploadBranchDelta(settings) {
|
||||||
}
|
}
|
||||||
const repoPath = settings.repositoryPath;
|
const repoPath = settings.repositoryPath;
|
||||||
const sha = settings.commit;
|
const sha = settings.commit;
|
||||||
|
await exec_exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha]);
|
||||||
|
try {
|
||||||
|
if (!(await hasBaseRefs(repoPath))) {
|
||||||
|
info('No base refs to diff against; branch delta skipped');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// If the tip is already in the base there is no delta to roll, and `git bundle
|
||||||
|
// create` errors on an empty range ("Refusing to create empty bundle"). Detect it
|
||||||
|
// first — and before taking the server lock, so an empty delta never blocks the
|
||||||
|
// other jobs racing the same branch.
|
||||||
|
if (await branchDeltaIsEmpty(repoPath)) {
|
||||||
|
info('Tip already contained in the base; no branch delta to upload');
|
||||||
|
return;
|
||||||
|
}
|
||||||
const grant = await requestBranchUpload(plan.repoKey, plan.refKey, sha);
|
const grant = await requestBranchUpload(plan.repoKey, plan.refKey, sha);
|
||||||
if (grant.kind !== 'grant') {
|
if (grant.kind !== 'grant') {
|
||||||
info(`Branch delta upload skipped (${grant.kind})`);
|
info(`Branch delta upload skipped (${grant.kind})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(await hasBaseRefs(repoPath))) {
|
|
||||||
info('No base refs to diff against; branch delta skipped');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tmp = tempBundlePath('branch');
|
const tmp = tempBundlePath('branch');
|
||||||
try {
|
try {
|
||||||
await exec_exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha]);
|
|
||||||
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo
|
// 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
|
// 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
|
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the
|
||||||
|
|
@ -42014,11 +42023,29 @@ async function uploadBranchDelta(settings) {
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
await external_fs_namespaceObject.promises.rm(tmp, { force: true });
|
await external_fs_namespaceObject.promises.rm(tmp, { force: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
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) {
|
||||||
|
|
|
||||||
|
|
@ -248,20 +248,29 @@ async function uploadBranchDelta(settings: IGitSourceSettings): Promise<void> {
|
||||||
const repoPath = settings.repositoryPath
|
const repoPath = settings.repositoryPath
|
||||||
const sha = settings.commit
|
const sha = settings.commit
|
||||||
|
|
||||||
|
await exec.exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha])
|
||||||
|
try {
|
||||||
|
if (!(await hasBaseRefs(repoPath))) {
|
||||||
|
core.info('No base refs to diff against; branch delta skipped')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// If the tip is already in the base there is no delta to roll, and `git bundle
|
||||||
|
// create` errors on an empty range ("Refusing to create empty bundle"). Detect it
|
||||||
|
// first — and before taking the server lock, so an empty delta never blocks the
|
||||||
|
// other jobs racing the same branch.
|
||||||
|
if (await branchDeltaIsEmpty(repoPath)) {
|
||||||
|
core.info('Tip already contained in the base; no branch delta to upload')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const grant = await api.requestBranchUpload(plan.repoKey, plan.refKey, sha)
|
const grant = await api.requestBranchUpload(plan.repoKey, plan.refKey, sha)
|
||||||
if (grant.kind !== 'grant') {
|
if (grant.kind !== 'grant') {
|
||||||
core.info(`Branch delta upload skipped (${grant.kind})`)
|
core.info(`Branch delta upload skipped (${grant.kind})`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(await hasBaseRefs(repoPath))) {
|
|
||||||
core.info('No base refs to diff against; branch delta skipped')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tmp = tempBundlePath('branch')
|
const tmp = tempBundlePath('branch')
|
||||||
try {
|
try {
|
||||||
await exec.exec('git', ['-C', repoPath, 'update-ref', UPLOAD_TIP_REF, sha])
|
|
||||||
// Exclude the base with a single --glob, not one `^ref` arg per ref: a large repo
|
// 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
|
// 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
|
// limit (ENAMETOOLONG). The glob matches the multi-level seeded refs and yields the
|
||||||
|
|
@ -280,6 +289,8 @@ async function uploadBranchDelta(settings: IGitSourceSettings): Promise<void> {
|
||||||
core.info(`Uploaded branch delta for '${plan.refKey}'`)
|
core.info(`Uploaded branch delta for '${plan.refKey}'`)
|
||||||
} finally {
|
} finally {
|
||||||
await fs.promises.rm(tmp, {force: true})
|
await fs.promises.rm(tmp, {force: true})
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
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> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue