···289289 }
290290291291 fileMatch := zoekt.FileMatch{
292292- Repository: md.Name,
292292+ Repository: md.URL,
293293 RepositoryID: md.ID,
294294 RepositoryPriority: md.GetPriority(),
295295 FileName: string(d.fileName(nextDoc)),
···357357358358 for _, md := range d.repoMetaData {
359359 r := md
360360- addRepo(&res, &r)
360360+ // Key by URL: it is the unique repo identity and matches
361361+ // FileMatch.Repository (also set to the URL). Subrepos are keyed by
362362+ // their Name, matching FileMatch.SubRepositoryName.
363363+ addRepo(&res, r.URL, &r)
361364 for _, v := range r.SubRepoMap {
362362- addRepo(&res, v)
365365+ addRepo(&res, v.Name, v)
363366 }
364367 }
365368···371374 return &res, nil
372375}
373376374374-func addRepo(res *zoekt.SearchResult, repo *zoekt.Repository) {
377377+func addRepo(res *zoekt.SearchResult, key string, repo *zoekt.Repository) {
375378 if res.RepoURLs == nil {
376379 res.RepoURLs = map[string]string{}
377380 }
378378- res.RepoURLs[repo.Name] = repo.FileURLTemplate
381381+ res.RepoURLs[key] = repo.FileURLTemplate
379382380383 if res.LineFragments == nil {
381384 res.LineFragments = map[string]string{}
382385 }
383383- res.LineFragments[repo.Name] = repo.LineFragmentTemplate
386386+ res.LineFragments[key] = repo.LineFragmentTemplate
384387}
385388386389// Gather matches from this document. The matches are returned in document
···547550 }
548551549552 include = func(rle *zoekt.RepoListEntry) bool {
550550- _, ok := foundRepos[rle.Repository.Name]
553553+ _, ok := foundRepos[rle.Repository.URL]
551554 return ok
552555 }
553556 }
+18-4
index/index_test.go
···1640164016411641 sres := searchForTest(t, b, &query.Substring{Pattern: "bla"})
1642164216431643- if sres.RepoURLs["name"] != "file-url" {
16441644- t.Errorf("got RepoURLs %v, want {name: URL}", sres.RepoURLs)
16431643+ // RepoURLs/LineFragments are keyed by the repo's URL (its unique identity).
16441644+ if sres.RepoURLs["URL"] != "file-url" {
16451645+ t.Errorf("got RepoURLs %v, want {URL: file-url}", sres.RepoURLs)
16451646 }
16461646- if sres.LineFragments["name"] != "fragment" {
16471647- t.Errorf("got URLs %v, want {name: URL}", sres.LineFragments)
16471647+ if sres.LineFragments["URL"] != "fragment" {
16481648+ t.Errorf("got URLs %v, want {URL: fragment}", sres.LineFragments)
16481649 }
16491650}
16501651···36393640 chunkOpts,
36403641 )
36413642 wantSingleMatch(res, "f2")
36433643+ })
36443644+36453645+ // type:filematch is the default result granularity. The wrapper must be
36463646+ // treated as a passthrough to the child instead of crashing the shard.
36473647+ t.Run("TypeFileMatch", func(t *testing.T) {
36483648+ res := searchForTest(t, b,
36493649+ &query.Type{
36503650+ Type: query.TypeFileMatch,
36513651+ Child: &query.Substring{Pattern: "needle"},
36523652+ })
36533653+ if len(res.Files) != 2 {
36543654+ t.Fatalf("got %d file matches, want 2", len(res.Files))
36553655+ }
36423656 })
36433657}
36443658
+5-1
index/matchtree.go
···1057105710581058 case *query.Type:
10591059 if s.Type != query.TypeFileName {
10601060- break
10601060+ // TypeFileMatch is the default result granularity, so the
10611061+ // wrapper carries no extra match semantics: match the child
10621062+ // directly. TypeRepo is normally stripped before reaching a
10631063+ // shard, but handle it the same way to avoid a panic.
10641064+ return d.newMatchTree(s.Child, opt)
10611065 }
1062106610631067 ct, err := d.newMatchTree(s.Child, opt)
+8-4
internal/e2e/e2e_index_test.go
···5050 ShardMax: 1024,
5151 RepositoryDescription: zoekt.Repository{
5252 Name: "repo",
5353+ URL: "repo",
5354 },
5455 Parallelism: 2,
5556 SizeMax: 1 << 20,
···123124 // use retryTest to allow for the directory watcher to notice the meta
124125 // file
125126 retryTest(t, func(fatalf func(format string, args ...any)) {
126126- // Add a .meta file for each shard with repo.Name set to
127127- // "repo-mutated". We do this inside retry helper since we have noticed
128128- // some flakiness on github CI.
127127+ // Add a .meta file for each shard with repo.URL set to
128128+ // "repo-mutated" (URL is the repo identity surfaced as
129129+ // FileMatch.Repository). We do this inside retry helper since we have
130130+ // noticed some flakiness on github CI.
129131 for _, p := range fs {
130132 repos, _, err := index.ReadMetadataPath(p)
131133 if err != nil {
132134 t.Fatal(err)
133135 }
134134- repos[0].Name = "repo-mutated"
136136+ repos[0].URL = "repo-mutated"
135137 b, err := json.Marshal(repos[0])
136138 if err != nil {
137139 t.Fatal(err)
···391393 ShardMax: 1024,
392394 RepositoryDescription: zoekt.Repository{
393395 Name: "repo",
396396+ URL: "repo",
394397 FileURLTemplate: "url",
395398 },
396399 Parallelism: 2,
···429432430433 opts.RepositoryDescription = zoekt.Repository{
431434 Name: "repo2",
435435+ URL: "repo2",
432436 FileURLTemplate: "url2",
433437 }
434438
+11-9
search/shards.go
···835835 return
836836 }
837837838838- send := func(repoName string, a, b int, stats zoekt.Stats) {
838838+ send := func(repoURL string, a, b int, stats zoekt.Stats) {
839839 index.SortFiles(result.Files[a:b])
840840841841- filteredRepoURLs := map[string]string{repoName: result.RepoURLs[repoName]}
842842- filteredLineFragments := map[string]string{repoName: result.LineFragments[repoName]}
841841+ // FileMatch.Repository holds the repo's unique key (its URL), which is
842842+ // also the key used for RepoURLs/LineFragments.
843843+ filteredRepoURLs := map[string]string{repoURL: result.RepoURLs[repoURL]}
844844+ filteredLineFragments := map[string]string{repoURL: result.LineFragments[repoURL]}
843845844846 // Filter RepoURLs and LineFragments to only those of repoName and its
845847 // subRepositories if there are subRepositories
···874876875877 var startIndex, endIndex int
876878 curRepoID := result.Files[0].RepositoryID
877877- curRepoName := result.Files[0].Repository
879879+ curRepoURL := result.Files[0].Repository
878880879881 fm := zoekt.FileMatch{}
880882 for endIndex, fm = range result.Files {
881883 if curRepoID != fm.RepositoryID {
882884 // Stats must stay aggregate-able, hence we sent the aggregate stats with the
883885 // last event.
884884- send(curRepoName, startIndex, endIndex, zoekt.Stats{})
886886+ send(curRepoURL, startIndex, endIndex, zoekt.Stats{})
885887886888 startIndex = endIndex
887889 curRepoID = fm.RepositoryID
888888- curRepoName = fm.Repository
890890+ curRepoURL = fm.Repository
889891 }
890892 }
891893892892- send(curRepoName, startIndex, endIndex+1, result.Stats)
894894+ send(curRepoURL, startIndex, endIndex+1, result.Stats)
893895}
894896895897func observeMetrics(sr *zoekt.SearchResult) {
···10731075 agg.Stats.Add(&r.rl.Stats)
1074107610751077 for _, r := range r.rl.Repos {
10761076- prev, ok := uniq[r.Repository.Name]
10781078+ prev, ok := uniq[r.Repository.URL]
10771079 if !ok {
10781080 cp := *r // We need to copy because we mutate r.Stats when merging duplicates
10791079- uniq[r.Repository.Name] = &cp
10811081+ uniq[r.Repository.URL] = &cp
10801082 } else {
10811083 prev.Stats.Add(&r.Stats)
10821084 }