diff options
| -rw-r--r-- | Documentation/git-grep.txt | 4 | ||||
| -rw-r--r-- | grep.c | 33 | ||||
| -rw-r--r-- | grep.h | 2 | ||||
| -rwxr-xr-x | t/t7810-grep.sh | 5 | 
4 files changed, 41 insertions, 3 deletions
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index e150c77cff..c3306f3a3b 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -29,7 +29,9 @@ SYNOPSIS  DESCRIPTION  -----------  Look for specified patterns in the tracked files in the work tree, blobs -registered in the index file, or blobs in given tree objects. +registered in the index file, or blobs in given tree objects.  Patterns +are lists of one or more search expressions separated by newline +characters.  An empty string as search expression matches all lines.  CONFIGURATION @@ -9,7 +9,7 @@ static struct grep_pat *create_grep_pat(const char *pat, size_t patlen,  					enum grep_header_field field)  {  	struct grep_pat *p = xcalloc(1, sizeof(*p)); -	p->pattern = pat; +	p->pattern = xmemdupz(pat, patlen);  	p->patternlen = patlen;  	p->origin = origin;  	p->no = no; @@ -23,6 +23,36 @@ static void do_append_grep_pat(struct grep_pat ***tail, struct grep_pat *p)  	**tail = p;  	*tail = &p->next;  	p->next = NULL; + +	switch (p->token) { +	case GREP_PATTERN: /* atom */ +	case GREP_PATTERN_HEAD: +	case GREP_PATTERN_BODY: +		for (;;) { +			struct grep_pat *new_pat; +			size_t len = 0; +			char *cp = p->pattern + p->patternlen, *nl = NULL; +			while (++len <= p->patternlen) { +				if (*(--cp) == '\n') { +					nl = cp; +					break; +				} +			} +			if (!nl) +				break; +			new_pat = create_grep_pat(nl + 1, len - 1, p->origin, +						  p->no, p->token, p->field); +			new_pat->next = p->next; +			if (!p->next) +				*tail = &new_pat->next; +			p->next = new_pat; +			*nl = '\0'; +			p->patternlen -= len; +		} +		break; +	default: +		break; +	}  }  void append_header_grep_pattern(struct grep_opt *opt, @@ -408,6 +438,7 @@ void free_grep_patterns(struct grep_opt *opt)  				free_pcre_regexp(p);  			else  				regfree(&p->regexp); +			free(p->pattern);  			break;  		default:  			break; @@ -35,7 +35,7 @@ struct grep_pat {  	const char *origin;  	int no;  	enum grep_pat_token token; -	const char *pattern; +	char *pattern;  	size_t patternlen;  	enum grep_header_field field;  	regex_t regexp; diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 6379ad60bc..bc9a522085 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -322,6 +322,11 @@ test_expect_success 'grep -f, multiple patterns' '  	test_cmp expected actual  ' +test_expect_success 'grep, multiple patterns' ' +	git grep "$(cat patterns)" >actual && +	test_cmp expected actual +' +  cat >expected <<EOF  file:foo mmap bar  file:foo_mmap bar  | 
