Skip to content

Commit dfed55c

Browse files
authored
Merge pull request #2638 from github/cklin/diff-informed-graph-fetching-tweak
Improve Git subgraph fetching for diff-informed queries
2 parents 417bb84 + f9b0c1f commit dfed55c

9 files changed

+104
-22
lines changed

lib/actions-util.js

+25-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/actions-util.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/analyze.js

+8-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/analyze.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/logging.js

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/logging.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions-util.ts

+27-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export const determineBaseBranchHeadCommitOid = async function (
163163
};
164164

165165
/**
166-
* Deepen the git history of the given ref by one level. Errors are logged.
166+
* Deepen the git history of HEAD by one level. Errors are logged.
167167
*
168168
* This function uses the `checkout_path` to determine the repository path and
169169
* works only when called from `analyze` or `upload-sarif`.
@@ -172,7 +172,14 @@ export const deepenGitHistory = async function () {
172172
try {
173173
await runGitCommand(
174174
getOptionalInput("checkout_path"),
175-
["fetch", "--no-tags", "--deepen=1"],
175+
[
176+
"fetch",
177+
"origin",
178+
"HEAD",
179+
"--no-tags",
180+
"--no-recurse-submodules",
181+
"--deepen=1",
182+
],
176183
"Cannot deepen the shallow repository.",
177184
);
178185
} catch {
@@ -198,6 +205,24 @@ export const gitFetch = async function (branch: string, extraFlags: string[]) {
198205
}
199206
};
200207

208+
/**
209+
* Repack the git repository, using with the given flags. Errors are logged.
210+
*
211+
* This function uses the `checkout_path` to determine the repository path and
212+
* works only when called from `analyze` or `upload-sarif`.
213+
*/
214+
export const gitRepack = async function (flags: string[]) {
215+
try {
216+
await runGitCommand(
217+
getOptionalInput("checkout_path"),
218+
["repack", ...flags],
219+
"Cannot repack the repository.",
220+
);
221+
} catch {
222+
// Errors are already logged by runGitCommand()
223+
}
224+
};
225+
201226
/**
202227
* Compute the all merge bases between the given refs. Returns an empty array
203228
* if no merge base is found, or if there is an error.

src/analyze.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { addDiagnostic, makeDiagnostic } from "./diagnostics";
1818
import { EnvVar } from "./environment";
1919
import { FeatureEnablement, Feature } from "./feature-flags";
2020
import { isScannedLanguage, Language } from "./languages";
21-
import { Logger, withGroup } from "./logging";
21+
import { Logger, withGroupAsync } from "./logging";
2222
import { DatabaseCreationTimings, EventReport } from "./status-report";
2323
import { ToolsFeature } from "./tools-features";
2424
import { endTracingForCluster } from "./tracer-config";
@@ -256,14 +256,17 @@ export async function setupDiffInformedQueryRun(
256256
if (!(await features.getValue(Feature.DiffInformedQueries, codeql))) {
257257
return undefined;
258258
}
259-
return await withGroup("Generating diff range extension pack", async () => {
260-
const diffRanges = await getPullRequestEditedDiffRanges(
261-
baseRef,
262-
headRef,
263-
logger,
264-
);
265-
return writeDiffRangeDataExtensionPack(logger, diffRanges);
266-
});
259+
return await withGroupAsync(
260+
"Generating diff range extension pack",
261+
async () => {
262+
const diffRanges = await getPullRequestEditedDiffRanges(
263+
baseRef,
264+
headRef,
265+
logger,
266+
);
267+
return writeDiffRangeDataExtensionPack(logger, diffRanges);
268+
},
269+
);
267270
}
268271

269272
interface DiffThunkRange {
@@ -295,7 +298,7 @@ async function getPullRequestEditedDiffRanges(
295298

296299
// To compute the merge bases between the base branch and the PR topic branch,
297300
// we need to fetch the commit graph from the branch heads to those merge
298-
// babes. The following 4-step procedure does so while limiting the amount of
301+
// babes. The following 6-step procedure does so while limiting the amount of
299302
// history fetched.
300303

301304
// Step 1: Deepen from the PR merge commit to the base branch head and the PR
@@ -314,7 +317,12 @@ async function getPullRequestEditedDiffRanges(
314317
// Step 4: Fetch the base branch history, stopping when we reach commits that
315318
// are reachable from the PR topic branch head.
316319
await actionsUtil.gitFetch(baseRef, [`--shallow-exclude=${headRef}`]);
317-
// Step 5: Deepen the history so that we have the merge bases between the base
320+
// Step 5: Repack the history to remove the shallow grafts that were added by
321+
// the previous fetches. This step works around a bug that causes subsequent
322+
// deepening fetches to fail with "fatal: error in object: unshallow <SHA>".
323+
// See https://stackoverflow.com/q/63878612
324+
await actionsUtil.gitRepack(["-d"]);
325+
// Step 6: Deepen the history so that we have the merge bases between the base
318326
// branch and the PR topic branch.
319327
await actionsUtil.deepenGitHistory();
320328

src/logging.ts

+12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ export function withGroup<T>(groupName: string, f: () => T): T {
4141
}
4242
}
4343

44+
export async function withGroupAsync<T>(
45+
groupName: string,
46+
f: () => Promise<T>,
47+
): Promise<T> {
48+
core.startGroup(groupName);
49+
try {
50+
return await f();
51+
} finally {
52+
core.endGroup();
53+
}
54+
}
55+
4456
/** Format a duration for use in logs. */
4557
export function formatDuration(durationMs: number) {
4658
if (durationMs < 1000) {

0 commit comments

Comments
 (0)