Respect num_context_lines in exact code search
What does this MR do and why?
The Zoekt client hardcoded num_context_lines to 1 and discarded the API
parameter, so a documented parameter was accepted and silently ignored
(issue 599116). The REST declaration already admits 0..MAX_NUM_CONTEXT_LINES and
advanced search already honours it; only the Zoekt path did not.
The value is now read from the search filters and clamped to the same 0-20 range advanced search admits, so an unbounded value cannot reach the webserver, which expands every match by this much. The default stays 1 rather than advanced search's 2: exact code search renders a caller-controlled number of chunks per file, so the larger default would multiply the payload by the chunk count.
Two consequences the plumbing change carries with it:
- The rendered start line was the match line less one, which was correct only while the context was fixed at 1. It is now derived from the context the webserver actually returned, which is fewer than requested near the start of a file.
- The language aggregation cache key excludes the value. The indexer forces it to 0 on an aggregation-only request, so keying on it would fragment one tally into one entry per context setting.
References
- Closes #599116
- Spec:
specs/exact-code-search-result-limits/SPEC.mdingitlab-org/search-team/artifacts, at merged commit44921f0e(artifacts!118). That amendment also settled a contradiction between two specs about what the parameter means for exact code search.
Screenshots or screen recordings
| Before | After |
|---|---|
How to set up and validate locally
With a GDK running Zoekt and a project indexed:
curl -s --header "PRIVATE-TOKEN: <token>" \
"http://gdk.test:3000/api/v4/projects/<id>/search?scope=blobs&search=<term>&search_type=zoekt&num_context_lines=7"Each result's data carries 7 lines either side of the match, and startline
names the first of them. num_context_lines=50 is rejected with 400 by the
REST parameter declaration; 0 yields the matching line alone.
MR acceptance checklist
Verification
With the five production files reverted to the parent commit and both spec
files kept, the two spec files report 50 examples, 10 failures — the ten
being exactly the new examples, with no infrastructure failures. With the
change in place the same command reports 50 examples, 0 failures.
That the webserver honours a caller-supplied value above 1 was measured rather
than assumed, because a Rails-side fix against a backend that ignored the
field would be a no-op. A gitlab-zoekt webserver was run over a purpose-built
one-file index and sent the v2 payload this code sends, varying only
num_context_lines. Returned context lines either side of a match at line 15
of a 30-line file:
| requested | before | after |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 5 | 5 | 5 |
| 20 | 14 | 15 |
The last row is the file boundary, which is what the start_line derivation
exists to handle.
What I did not verify
The GraphQL blobSearch resolver does not build a num_context_lines
argument, so that surface is unchanged by this MR and was not exercised. The
web search page passes the parameter through the same filter path but was not
driven end to end. The probe used a locally built single-shard index, not a
multi-node production corpus, so fan-out and dedup behaviour under a non-zero
context setting is untested here.