grep: support searching non default branches/tags

This commit is contained in:
Shiny Nematoda 2024-05-06 10:09:28 +00:00
parent 8c3511a8b3
commit 46a5b13292
6 changed files with 60 additions and 22 deletions

View file

@ -29,6 +29,7 @@ type GrepOptions struct {
MaxResultLimit int
ContextLineNumber int
IsFuzzy bool
PathSpec []setting.Glob
}
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
@ -61,15 +62,20 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
} else {
cmd.AddOptionValues("-e", strings.TrimLeft(search, "-"))
}
// pathspec
files := make([]string, 0, len(setting.Indexer.IncludePatterns)+len(setting.Indexer.ExcludePatterns))
for _, expr := range setting.Indexer.IncludePatterns {
files = append(files, expr.Pattern())
files := make([]string, 0,
len(setting.Indexer.IncludePatterns)+
len(setting.Indexer.ExcludePatterns)+
len(opts.PathSpec))
for _, expr := range append(setting.Indexer.IncludePatterns, opts.PathSpec...) {
files = append(files, ":(glob)"+expr.Pattern())
}
for _, expr := range setting.Indexer.ExcludePatterns {
files = append(files, ":^"+expr.Pattern())
files = append(files, ":(glob,exclude)"+expr.Pattern())
}
cmd.AddDynamicArguments(cmp.Or(opts.RefName, "HEAD")).AddDashesAndList(files...)
opts.MaxResultLimit = cmp.Or(opts.MaxResultLimit, 50)
stderr := bytes.Buffer{}
err = cmd.Run(&RunOpts{

View file

@ -76,3 +76,33 @@ func TestGrepLongFiles(t *testing.T) {
assert.Len(t, res, 1)
assert.Len(t, res[0].LineCodes[0], 65*1024)
}
func TestGrepRefs(t *testing.T) {
tmpDir := t.TempDir()
err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
assert.NoError(t, err)
gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
assert.NoError(t, err)
defer gitRepo.Close()
assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A'}, 0o666))
assert.NoError(t, AddChanges(tmpDir, true))
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add A"})
assert.NoError(t, err)
assert.NoError(t, gitRepo.CreateTag("v1", "HEAD"))
assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A', 'B', 'C', 'D'}, 0o666))
assert.NoError(t, AddChanges(tmpDir, true))
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add BCD"})
assert.NoError(t, err)
res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{RefName: "v1"})
assert.NoError(t, err)
assert.Len(t, res, 1)
assert.Equal(t, res[0].LineCodes[0], "A")
}

View file

@ -64,7 +64,11 @@ func Search(ctx *context.Context) {
ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
}
} else {
res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{ContextLineNumber: 3, IsFuzzy: isFuzzy})
res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{
ContextLineNumber: 1,
IsFuzzy: isFuzzy,
RefName: ctx.Repo.RefName,
})
if err != nil {
ctx.ServerError("GrepSearch", err)
return

View file

@ -1140,6 +1140,7 @@ PostRecentBranchCheck:
ctx.Data["TreeLink"] = treeLink
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled
ctx.HTML(http.StatusOK, tplRepoHome)
}

View file

@ -1567,11 +1567,17 @@ func registerRoutes(m *web.Route) {
m.Group("/{username}/{reponame}", func() {
if !setting.Repository.DisableStars {
m.Get("/stars", repo.Stars)
m.Get("/stars", context.RepoRef(), repo.Stars)
}
m.Get("/watchers", repo.Watchers)
m.Get("/search", reqRepoCodeReader, repo.Search)
}, ignSignIn, context.RepoAssignment, context.RepoRef(), context.UnitTypes())
m.Get("/watchers", context.RepoRef(), repo.Watchers)
m.Group("/search", func() {
m.Get("", context.RepoRef(), repo.Search)
if !setting.Indexer.RepoIndexerEnabled {
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Search)
m.Get("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.Search)
}
}, reqRepoCodeReader)
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
m.Group("/{username}", func() {
m.Group("/{reponame}", func() {

View file

@ -8,10 +8,10 @@
<div class="repo-description">
<div id="repo-desc" class="gt-word-break tw-text-16">
{{$description := .Repository.DescriptionHTML $.Context}}
{{if $description}}<span class="description">{{$description | RenderCodeBlock}}</span>{{else if .IsRepositoryAdmin}}<span class="no-description text-italic">{{ctx.Locale.Tr "repo.no_desc"}}</span>{{end}}
<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>
{{if $description}}<span class="description">{{$description | RenderCodeBlock}}</span>{{else}}<span class="no-description text-italic">{{ctx.Locale.Tr "repo.no_desc"}}</span>{{end}}
{{if .Repository.Website}}<a class="link" href="{{.Repository.Website}}">{{.Repository.Website}}</a>{{end}}
</div>
<form class="ignore-dirty" action="{{.RepoLink}}/search" method="get">
<form class="ignore-dirty" action="{{.RepoLink}}/search/{{if .CodeIndexerDisabled}}{{.BranchNameSubURL}}{{end}}" method="get">
<div class="ui small action input">
<input name="q" value="{{.Keyword}}" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
{{template "shared/search/button"}}
@ -106,16 +106,7 @@
{{ctx.Locale.Tr "repo.use_template"}}
</a>
{{end}}
{{if $isHomepage}}
{{/* only show the "code search" on the repo home page, it only does global search,
so do not show it when viewing file or directory to avoid misleading users (it doesn't search in a directory) */}}
<form class="ignore-dirty" action="{{.RepoLink}}/search" method="get">
<div class="ui small action input">
<input name="q" placeholder="{{ctx.Locale.Tr "search.code_kind"}}">
{{template "shared/search/button"}}
</div>
</form>
{{else}}
{{if (not $isHomepage)}}
<span class="breadcrumb repo-path tw-ml-1">
<a class="section" href="{{.RepoLink}}/src/{{.BranchNameSubURL}}" title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>
{{- range $i, $v := .TreeNames -}}