mirror of
https://github.com/git/git.git
synced 2024-11-17 22:44:49 +01:00
Merge branch 'jc/grep' into next
* jc/grep: builtin-grep: documentation Teach -f <file> option to builtin-grep.
This commit is contained in:
commit
4ca72f20c3
2 changed files with 104 additions and 42 deletions
|
@ -8,43 +8,82 @@ git-grep - Print lines matching a pattern
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
--------
|
--------
|
||||||
'git-grep' [<option>...] [-e] <pattern> [--] [<path>...]
|
[verse]
|
||||||
|
'git-grep' [--cached]
|
||||||
|
[-a | --text] [-I] [-i | --ignore-case] [-w | --word-regexp]
|
||||||
|
[-v | --invert-match]
|
||||||
|
[-E | --extended-regexp] [-G | --basic-regexp]
|
||||||
|
[-n] [-l | --files-with-matches] [-L | --files-without-match]
|
||||||
|
[-c | --count]
|
||||||
|
[-A <post-context>] [-B <pre-context>] [-C <context>]
|
||||||
|
[-f <file>] [-e <pattern>]
|
||||||
|
[<tree>...]
|
||||||
|
[--] [<path>...]
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
Searches list of files `git-ls-files` produces for lines
|
Look for specified patterns in the working tree files, blobs
|
||||||
containing a match to the given pattern.
|
registered in the index file, or given tree objects.
|
||||||
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
--cached::
|
||||||
|
Instead of searching in the working tree files, check
|
||||||
|
the blobs registerd in the index file.
|
||||||
|
|
||||||
|
-a | --text::
|
||||||
|
Process binary files as if they were text.
|
||||||
|
|
||||||
|
-i | --ignore-case::
|
||||||
|
Ignore case differences between the patterns and the
|
||||||
|
files.
|
||||||
|
|
||||||
|
-w | --word-regexp::
|
||||||
|
Match the pattern only at word boundary (either begin at the
|
||||||
|
beginning of a line, or preceded by a non-word character; end at
|
||||||
|
the end of a line or followed by a non-word character).
|
||||||
|
|
||||||
|
-v | --invert-match::
|
||||||
|
Select non-matching lines.
|
||||||
|
|
||||||
|
-E | --extended-regexp | -G | --basic-regexp::
|
||||||
|
Use POSIX extended/basic regexp for patterns. Default
|
||||||
|
is to use basic regexp.
|
||||||
|
|
||||||
|
-n::
|
||||||
|
Prefix the line number to matching lines.
|
||||||
|
|
||||||
|
-l | --files-with-matches | -L | --files-without-match::
|
||||||
|
Instead of showing every matched line, show only the
|
||||||
|
names of files that contain (or do not contain) matches.
|
||||||
|
|
||||||
|
-c | --count::
|
||||||
|
Instead of showing every matched line, show the number of
|
||||||
|
lines that match.
|
||||||
|
|
||||||
|
-[ABC] <context>::
|
||||||
|
Show `context` trailing (`A` -- after), or leading (`B`
|
||||||
|
-- before), or both (`C` -- context) lines, and place a
|
||||||
|
line containing `--` between continguous groups of
|
||||||
|
matches.
|
||||||
|
|
||||||
|
-f <file>::
|
||||||
|
Read patterns from <file>, one per line.
|
||||||
|
|
||||||
|
`<tree>...`::
|
||||||
|
Search blobs in the trees for specified patterns.
|
||||||
|
|
||||||
`--`::
|
`--`::
|
||||||
Signals the end of options; the rest of the parameters
|
Signals the end of options; the rest of the parameters
|
||||||
are <path> limiters.
|
are <path> limiters.
|
||||||
|
|
||||||
<option>...::
|
|
||||||
Either an option to pass to `grep` or `git-ls-files`.
|
|
||||||
+
|
|
||||||
The following are the specific `git-ls-files` options
|
|
||||||
that may be given: `-o`, `--cached`, `--deleted`, `--others`,
|
|
||||||
`--killed`, `--ignored`, `--modified`, `--exclude=\*`,
|
|
||||||
`--exclude-from=\*`, and `--exclude-per-directory=\*`.
|
|
||||||
+
|
|
||||||
All other options will be passed to `grep`.
|
|
||||||
|
|
||||||
<pattern>::
|
|
||||||
The pattern to look for. The first non option is taken
|
|
||||||
as the pattern; if your pattern begins with a dash, use
|
|
||||||
`-e <pattern>`.
|
|
||||||
|
|
||||||
<path>...::
|
|
||||||
Optional paths to limit the set of files to be searched;
|
|
||||||
passed to `git-ls-files`.
|
|
||||||
|
|
||||||
|
|
||||||
Author
|
Author
|
||||||
------
|
------
|
||||||
Written by Linus Torvalds <torvalds@osdl.org>
|
Originally written by Linus Torvalds <torvalds@osdl.org>, later
|
||||||
|
revamped by Junio C Hamano.
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
--------------
|
--------------
|
||||||
|
|
|
@ -82,6 +82,8 @@ static int pathspec_matches(const char **paths, const char *name)
|
||||||
|
|
||||||
struct grep_pat {
|
struct grep_pat {
|
||||||
struct grep_pat *next;
|
struct grep_pat *next;
|
||||||
|
const char *origin;
|
||||||
|
int no;
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
regex_t regexp;
|
regex_t regexp;
|
||||||
};
|
};
|
||||||
|
@ -105,10 +107,13 @@ struct grep_opt {
|
||||||
unsigned post_context;
|
unsigned post_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void add_pattern(struct grep_opt *opt, const char *pat)
|
static void add_pattern(struct grep_opt *opt, const char *pat,
|
||||||
|
const char *origin, int no)
|
||||||
{
|
{
|
||||||
struct grep_pat *p = xcalloc(1, sizeof(*p));
|
struct grep_pat *p = xcalloc(1, sizeof(*p));
|
||||||
p->pattern = pat;
|
p->pattern = pat;
|
||||||
|
p->origin = origin;
|
||||||
|
p->no = no;
|
||||||
*opt->pattern_tail = p;
|
*opt->pattern_tail = p;
|
||||||
opt->pattern_tail = &p->next;
|
opt->pattern_tail = &p->next;
|
||||||
p->next = NULL;
|
p->next = NULL;
|
||||||
|
@ -121,9 +126,17 @@ static void compile_patterns(struct grep_opt *opt)
|
||||||
int err = regcomp(&p->regexp, p->pattern, opt->regflags);
|
int err = regcomp(&p->regexp, p->pattern, opt->regflags);
|
||||||
if (err) {
|
if (err) {
|
||||||
char errbuf[1024];
|
char errbuf[1024];
|
||||||
|
char where[1024];
|
||||||
|
if (p->no)
|
||||||
|
sprintf(where, "In '%s' at %d, ",
|
||||||
|
p->origin, p->no);
|
||||||
|
else if (p->origin)
|
||||||
|
sprintf(where, "%s, ", p->origin);
|
||||||
|
else
|
||||||
|
where[0] = 0;
|
||||||
regerror(err, &p->regexp, errbuf, 1024);
|
regerror(err, &p->regexp, errbuf, 1024);
|
||||||
regfree(&p->regexp);
|
regfree(&p->regexp);
|
||||||
die("'%s': %s", p->pattern, errbuf);
|
die("%s'%s': %s", where, p->pattern, errbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -482,7 +495,6 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
{
|
{
|
||||||
int hit = 0;
|
int hit = 0;
|
||||||
int no_more_flags = 0;
|
int no_more_flags = 0;
|
||||||
int seen_noncommit = 0;
|
|
||||||
int cached = 0;
|
int cached = 0;
|
||||||
struct grep_opt opt;
|
struct grep_opt opt;
|
||||||
struct object_list *list, **tail, *object_list = NULL;
|
struct object_list *list, **tail, *object_list = NULL;
|
||||||
|
@ -598,9 +610,32 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp("-f", arg)) {
|
||||||
|
FILE *patterns;
|
||||||
|
int lno = 0;
|
||||||
|
char buf[1024];
|
||||||
|
if (argc <= 1)
|
||||||
|
usage(builtin_grep_usage);
|
||||||
|
patterns = fopen(argv[1], "r");
|
||||||
|
if (!patterns)
|
||||||
|
die("'%s': %s", strerror(errno));
|
||||||
|
while (fgets(buf, sizeof(buf), patterns)) {
|
||||||
|
int len = strlen(buf);
|
||||||
|
if (buf[len-1] == '\n')
|
||||||
|
buf[len-1] = 0;
|
||||||
|
/* ignore empty line like grep does */
|
||||||
|
if (!buf[0])
|
||||||
|
continue;
|
||||||
|
add_pattern(&opt, strdup(buf), argv[1], ++lno);
|
||||||
|
}
|
||||||
|
fclose(patterns);
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strcmp("-e", arg)) {
|
if (!strcmp("-e", arg)) {
|
||||||
if (1 < argc) {
|
if (1 < argc) {
|
||||||
add_pattern(&opt, argv[1]);
|
add_pattern(&opt, argv[1], "-e option", 0);
|
||||||
argv++;
|
argv++;
|
||||||
argc--;
|
argc--;
|
||||||
continue;
|
continue;
|
||||||
|
@ -615,7 +650,7 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
if (!no_more_flags && *arg == '-')
|
if (!no_more_flags && *arg == '-')
|
||||||
usage(builtin_grep_usage);
|
usage(builtin_grep_usage);
|
||||||
if (!opt.pattern_list) {
|
if (!opt.pattern_list) {
|
||||||
add_pattern(&opt, arg);
|
add_pattern(&opt, arg, "command line", 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -656,21 +691,9 @@ int cmd_grep(int argc, const char **argv, char **envp)
|
||||||
|
|
||||||
if (!object_list)
|
if (!object_list)
|
||||||
return !grep_cache(&opt, paths, cached);
|
return !grep_cache(&opt, paths, cached);
|
||||||
/*
|
|
||||||
* Do not walk "grep -e foo master next pu -- Documentation/"
|
|
||||||
* but do walk "grep -e foo master..next -- Documentation/".
|
|
||||||
* Ranged request mixed with a blob or tree object, like
|
|
||||||
* "grep -e foo v1.0.0:Documentation/ master..next"
|
|
||||||
* so detect that and complain.
|
|
||||||
*/
|
|
||||||
for (list = object_list; list; list = list->next) {
|
|
||||||
struct object *real_obj;
|
|
||||||
real_obj = deref_tag(list->item, NULL, 0);
|
|
||||||
if (strcmp(real_obj->type, commit_type))
|
|
||||||
seen_noncommit = 1;
|
|
||||||
}
|
|
||||||
if (cached)
|
if (cached)
|
||||||
die("both --cached and revisions given.");
|
die("both --cached and trees are given.");
|
||||||
|
|
||||||
for (list = object_list; list; list = list->next) {
|
for (list = object_list; list; list = list->next) {
|
||||||
struct object *real_obj;
|
struct object *real_obj;
|
||||||
|
|
Loading…
Reference in a new issue