fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

gitindex: handle bare repos in plainOpenRepo (#1030)

If you set ZOEKT_DISABLE_GOGIT_OPTIMIZATION=true then zoekt-git-index
would fail on bare repositories. This was a regression from

a0f5789 Handle git indexing path correctly for Git worktrees

As such we also increase our test coverage to handle bare vs normal vs
worktrees. Additionally we add a test for when we disable the
optimization for bare repos, specifically targetting the regression we
saw.

+122
+10
gitindex/index.go
··· 183 183 } 184 184 185 185 func plainOpenRepo(repoDir string) (*git.Repository, error) { 186 + // Try repoDir as the repository root first so bare repositories open 187 + // correctly. If repoDir itself is not a repository, fall back to searching 188 + // for a .git entry to preserve compatibility with worktree paths. 189 + repo, err := git.PlainOpenWithOptions(repoDir, &git.PlainOpenOptions{ 190 + EnableDotGitCommonDir: true, 191 + }) 192 + if err == nil || !errors.Is(err, git.ErrRepositoryNotExists) { 193 + return repo, err 194 + } 195 + 186 196 return git.PlainOpenWithOptions(repoDir, &git.PlainOpenOptions{ 187 197 DetectDotGit: true, 188 198 EnableDotGitCommonDir: true,
+112
gitindex/index_test.go
··· 165 165 } 166 166 } 167 167 168 + func TestOpenRepoVariants(t *testing.T) { 169 + repoDir, worktreeDir := initGitWorktree(t, "file1.go", "package main\n\nfunc main() {}\n") 170 + bareDir := cloneBareRepo(t, repoDir) 171 + 172 + paths := []struct { 173 + name string 174 + path string 175 + }{ 176 + {name: "repo root", path: repoDir}, 177 + {name: "dot git dir", path: filepath.Join(repoDir, ".git")}, 178 + {name: "worktree root", path: worktreeDir}, 179 + {name: "bare repo root", path: bareDir}, 180 + } 181 + 182 + openers := []struct { 183 + name string 184 + open func(t *testing.T, repoDir string) *git.Repository 185 + }{ 186 + { 187 + name: "plain", 188 + open: func(t *testing.T, repoDir string) *git.Repository { 189 + t.Helper() 190 + 191 + repo, err := plainOpenRepo(repoDir) 192 + if err != nil { 193 + t.Fatalf("plainOpenRepo(%q): %v", repoDir, err) 194 + } 195 + 196 + return repo 197 + }, 198 + }, 199 + { 200 + name: "optimized", 201 + open: func(t *testing.T, repoDir string) *git.Repository { 202 + t.Helper() 203 + 204 + repo, closer, err := openRepo(repoDir) 205 + if err != nil { 206 + t.Fatalf("openRepo(%q): %v", repoDir, err) 207 + } 208 + t.Cleanup(func() { 209 + _ = closer.Close() 210 + }) 211 + 212 + return repo 213 + }, 214 + }, 215 + } 216 + 217 + for _, opener := range openers { 218 + for _, tc := range paths { 219 + t.Run(opener.name+"/"+tc.name, func(t *testing.T) { 220 + repo := opener.open(t, tc.path) 221 + 222 + head, err := repo.Head() 223 + if err != nil { 224 + t.Fatalf("repo.Head(): %v", err) 225 + } 226 + 227 + if _, err := repo.CommitObject(head.Hash()); err != nil { 228 + t.Fatalf("repo.CommitObject(%s): %v", head.Hash(), err) 229 + } 230 + }) 231 + } 232 + } 233 + } 234 + 235 + func TestIndexGitRepo_BareRepo_LegacyRepoOpen(t *testing.T) { 236 + repoDir, _ := initGitWorktree(t, "file1.go", "package main\n\nfunc main() {}\n") 237 + bareDir := cloneBareRepo(t, repoDir) 238 + indexDir := t.TempDir() 239 + 240 + t.Setenv("ZOEKT_DISABLE_GOGIT_OPTIMIZATION", "true") 241 + 242 + opts := Options{ 243 + RepoDir: bareDir, 244 + Branches: []string{"main"}, 245 + BuildOptions: index.Options{ 246 + RepositoryDescription: zoekt.Repository{Name: "repo"}, 247 + IndexDir: indexDir, 248 + }, 249 + } 250 + 251 + if _, err := IndexGitRepo(opts); err != nil { 252 + t.Fatalf("IndexGitRepo(bare, legacy open): %v", err) 253 + } 254 + 255 + searcher, err := search.NewDirectorySearcher(indexDir) 256 + if err != nil { 257 + t.Fatal("NewDirectorySearcher", err) 258 + } 259 + defer searcher.Close() 260 + 261 + results, err := searcher.Search(context.Background(), &query.Const{Value: true}, &zoekt.SearchOptions{}) 262 + if err != nil { 263 + t.Fatal("search failed", err) 264 + } 265 + 266 + if len(results.Files) != 1 || results.Files[0].FileName != "file1.go" { 267 + t.Fatalf("got search result %v, want file1.go", results.Files) 268 + } 269 + } 270 + 168 271 func TestCatfileFilterSpec(t *testing.T) { 169 272 for _, tc := range []struct { 170 273 name string ··· 229 332 executeCommand(t, repoDir, exec.Command("git", "worktree", "add", "-b", "worktree-branch", worktreeDir)) 230 333 231 334 return repoDir, worktreeDir 335 + } 336 + 337 + func cloneBareRepo(t *testing.T, repoDir string) string { 338 + t.Helper() 339 + 340 + bareDir := filepath.Join(t.TempDir(), "repo.git") 341 + executeCommand(t, filepath.Dir(repoDir), exec.Command("git", "clone", "--bare", repoDir, bareDir)) 342 + 343 + return bareDir 232 344 } 233 345 234 346 func TestIndexDeltaBasic(t *testing.T) {