MCPcopy Create free account
hub / github.com/alibaba/open-code-review / gitGrep

Method gitGrep

internal/tool/code_search.go:136–238  ·  view source on GitHub ↗
(ctx context.Context, searchText string, caseSensitive bool, usePerlRegexp bool, pathspec []string)

Source from the content-addressed store, hash-verified

134}
135
136func (p *CodeSearchProvider) gitGrep(ctx context.Context, searchText string, caseSensitive bool, usePerlRegexp bool, pathspec []string) (string, error) {
137 cmdArgs := p.buildGrepArgs(searchText, caseSensitive, usePerlRegexp, false, pathspec)
138 if cmdArgs == nil {
139 return "Error: ref must not start with '-'", nil
140 }
141
142 outStr, errStr, err := p.runGitGrep(ctx, cmdArgs)
143
144 // Non-git directory: `git grep` exits 128 with "not a git repository".
145 // `ocr scan` supports plain directories, so retry in --no-index mode, which
146 // searches the working tree directly while still honoring .gitignore.
147 // Ref-based search needs a real repo, so it is not retried.
148 if err != nil && p.FileReader.Ref == "" && isNotGitRepoError(err, errStr) {
149 cmdArgs = p.buildGrepArgs(searchText, caseSensitive, usePerlRegexp, true, pathspec)
150 outStr, errStr, err = p.runGitGrep(ctx, cmdArgs)
151 }
152
153 if err != nil {
154 if errors.Is(err, context.DeadlineExceeded) {
155 return "", fmt.Errorf("git grep timed out; try narrowing file_patterns to a more specific path: %w", err)
156 }
157 if errors.Is(err, context.Canceled) {
158 return "", err
159 }
160 if outStr == "" {
161 var exitErr *exec.ExitError
162 exitCode := -1
163 if errors.As(err, &exitErr) {
164 exitCode = exitErr.ExitCode()
165 }
166 if errStr == "" && exitCode == 1 {
167 return "No matches found", nil
168 }
169 trimmedErr := trimGitUsage(errStr, exitCode)
170 if trimmedErr == "" {
171 return "", fmt.Errorf("git grep failed: %w", err)
172 }
173 return "", fmt.Errorf("git grep failed: %w: %s", err, trimmedErr)
174 }
175 }
176
177 lines := strings.Split(strings.TrimRight(outStr, "\n"), "\n")
178 truncated := len(lines) >= gitGrepMaxCount
179
180 type match struct {
181 lineNum int
182 content string
183 }
184 fileMatches := make(map[string][]match)
185 var fileOrder []string
186 seen := make(map[string]bool)
187
188 hasRef := p.FileReader.Ref != ""
189 splitN := 3
190 offset := 0
191 if hasRef {
192 splitN = 4
193 offset = 1

Calls 5

buildGrepArgsMethod · 0.95
runGitGrepMethod · 0.95
isNotGitRepoErrorFunction · 0.85
trimGitUsageFunction · 0.85
StringMethod · 0.45