aboutsummaryrefslogtreecommitdiffstats
path: root/worktree.go
diff options
context:
space:
mode:
authorSunny <me@darkowlzz.space>2017-12-18 01:50:42 +0530
committerSunny <me@darkowlzz.space>2017-12-20 00:32:59 +0530
commit4ead334dbdf371b75d26dc682e930d1338b8ce35 (patch)
tree2b3750f66ad65575baa879e408b650aea671edd2 /worktree.go
parent757a26038e5404f94523ba07d017d1b38bcbf6dd (diff)
downloadgo-git-4ead334dbdf371b75d26dc682e930d1338b8ce35.tar.gz
git: Worktree.Grep() support multiple patterns and pathspecs
Signed-off-by: Sunny <me@darkowlzz.space>
Diffstat (limited to 'worktree.go')
-rw-r--r--worktree.go84
1 files changed, 61 insertions, 23 deletions
diff --git a/worktree.go b/worktree.go
index 2c35ffb..a23397e 100644
--- a/worktree.go
+++ b/worktree.go
@@ -765,50 +765,88 @@ func (w *Worktree) Grep(opts *GrepOptions) ([]GrepResult, error) {
// findMatchInFiles takes a FileIter, worktree name and GrepOptions, and
// returns a slice of GrepResult containing the result of regex pattern matching
-// in the file content.
+// in content of all the files.
func findMatchInFiles(fileiter *object.FileIter, treeName string, opts *GrepOptions) ([]GrepResult, error) {
var results []GrepResult
- // Iterate through the files and look for any matches.
err := fileiter.ForEach(func(file *object.File) error {
- // Check if the file name matches with the pathspec.
- if opts.PathSpec != nil && !opts.PathSpec.MatchString(file.Name) {
+ var fileInPathSpec bool
+
+ // When no pathspecs are provided, search all the files.
+ if len(opts.PathSpecs) == 0 {
+ fileInPathSpec = true
+ }
+
+ // Check if the file name matches with the pathspec. Break out of the
+ // loop once a match is found.
+ for _, pathSpec := range opts.PathSpecs {
+ if pathSpec != nil && pathSpec.MatchString(file.Name) {
+ fileInPathSpec = true
+ break
+ }
+ }
+
+ // If the file does not match with any of the pathspec, skip it.
+ if !fileInPathSpec {
return nil
}
- content, err := file.Contents()
+ grepResults, err := findMatchInFile(file, treeName, opts)
if err != nil {
return err
}
+ results = append(results, grepResults...)
+
+ return nil
+ })
+
+ return results, err
+}
- // Split the content and make parseable line-by-line.
- contentByLine := strings.Split(content, "\n")
- for lineNum, cnt := range contentByLine {
- addToResult := false
- // Match the pattern and content.
- if opts.Pattern != nil && opts.Pattern.MatchString(cnt) {
+// findMatchInFile takes a single File, worktree name and GrepOptions,
+// and returns a slice of GrepResult containing the result of regex pattern
+// matching in the given file.
+func findMatchInFile(file *object.File, treeName string, opts *GrepOptions) ([]GrepResult, error) {
+ var grepResults []GrepResult
+
+ content, err := file.Contents()
+ if err != nil {
+ return grepResults, err
+ }
+
+ // Split the file content and parse line-by-line.
+ contentByLine := strings.Split(content, "\n")
+ for lineNum, cnt := range contentByLine {
+ addToResult := false
+
+ // Match the patterns and content. Break out of the loop once a
+ // match is found.
+ for _, pattern := range opts.Patterns {
+ if pattern != nil && pattern.MatchString(cnt) {
// Add to result only if invert match is not enabled.
if !opts.InvertMatch {
addToResult = true
+ break
}
} else if opts.InvertMatch {
- // If matching fails, and invert match is enabled, add to results.
+ // If matching fails, and invert match is enabled, add to
+ // results.
addToResult = true
+ break
}
+ }
- if addToResult {
- results = append(results, GrepResult{
- FileName: file.Name,
- LineNumber: lineNum + 1,
- Content: cnt,
- TreeName: treeName,
- })
- }
+ if addToResult {
+ grepResults = append(grepResults, GrepResult{
+ FileName: file.Name,
+ LineNumber: lineNum + 1,
+ Content: cnt,
+ TreeName: treeName,
+ })
}
- return nil
- })
+ }
- return results, err
+ return grepResults, nil
}
func rmFileAndDirIfEmpty(fs billy.Filesystem, name string) error {