|
|
|
#ifndef GREP_H
|
|
|
|
#define GREP_H
|
|
|
|
#include "color.h"
|
|
|
|
|
|
|
|
enum grep_pat_token {
|
|
|
|
GREP_PATTERN,
|
|
|
|
GREP_PATTERN_HEAD,
|
|
|
|
GREP_PATTERN_BODY,
|
|
|
|
GREP_AND,
|
|
|
|
GREP_OPEN_PAREN,
|
|
|
|
GREP_CLOSE_PAREN,
|
|
|
|
GREP_NOT,
|
|
|
|
GREP_OR,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum grep_context {
|
|
|
|
GREP_CONTEXT_HEAD,
|
|
|
|
GREP_CONTEXT_BODY,
|
|
|
|
};
|
|
|
|
|
log --author/--committer: really match only with name part
When we tried to find commits done by AUTHOR, the first implementation
tried to pattern match a line with "^author .*AUTHOR", which later was
enhanced to strip leading caret and look for "^author AUTHOR" when the
search pattern was anchored at the left end (i.e. --author="^AUTHOR").
This had a few problems:
* When looking for fixed strings (e.g. "git log -F --author=x --grep=y"),
the regexp internally used "^author .*x" would never match anything;
* To match at the end (e.g. "git log --author='google.com>$'"), the
generated regexp has to also match the trailing timestamp part the
commit header lines have. Also, in order to determine if the '$' at
the end means "match at the end of the line" or just a literal dollar
sign (probably backslash-quoted), we would need to parse the regexp
ourselves.
An earlier alternative tried to make sure that a line matches "^author "
(to limit by field name) and the user supplied pattern at the same time.
While it solved the -F problem by introducing a special override for
matching the "^author ", it did not solve the trailing timestamp nor tail
match problem. It also would have matched every commit if --author=author
was asked for, not because the author's email part had this string, but
because every commit header line that talks about the author begins with
that field name, regardleses of who wrote it.
Instead of piling more hacks on top of hacks, this rethinks the grep
machinery that is used to look for strings in the commit header, and makes
sure that (1) field name matches literally at the beginning of the line,
followed by a SP, and (2) the user supplied pattern is matched against the
remainder of the line, excluding the trailing timestamp data.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
17 years ago
|
|
|
enum grep_header_field {
|
|
|
|
GREP_HEADER_AUTHOR = 0,
|
|
|
|
GREP_HEADER_COMMITTER,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct grep_pat {
|
|
|
|
struct grep_pat *next;
|
|
|
|
const char *origin;
|
|
|
|
int no;
|
|
|
|
enum grep_pat_token token;
|
|
|
|
const char *pattern;
|
log --author/--committer: really match only with name part
When we tried to find commits done by AUTHOR, the first implementation
tried to pattern match a line with "^author .*AUTHOR", which later was
enhanced to strip leading caret and look for "^author AUTHOR" when the
search pattern was anchored at the left end (i.e. --author="^AUTHOR").
This had a few problems:
* When looking for fixed strings (e.g. "git log -F --author=x --grep=y"),
the regexp internally used "^author .*x" would never match anything;
* To match at the end (e.g. "git log --author='google.com>$'"), the
generated regexp has to also match the trailing timestamp part the
commit header lines have. Also, in order to determine if the '$' at
the end means "match at the end of the line" or just a literal dollar
sign (probably backslash-quoted), we would need to parse the regexp
ourselves.
An earlier alternative tried to make sure that a line matches "^author "
(to limit by field name) and the user supplied pattern at the same time.
While it solved the -F problem by introducing a special override for
matching the "^author ", it did not solve the trailing timestamp nor tail
match problem. It also would have matched every commit if --author=author
was asked for, not because the author's email part had this string, but
because every commit header line that talks about the author begins with
that field name, regardleses of who wrote it.
Instead of piling more hacks on top of hacks, this rethinks the grep
machinery that is used to look for strings in the commit header, and makes
sure that (1) field name matches literally at the beginning of the line,
followed by a SP, and (2) the user supplied pattern is matched against the
remainder of the line, excluding the trailing timestamp data.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
17 years ago
|
|
|
enum grep_header_field field;
|
|
|
|
regex_t regexp;
|
|
|
|
unsigned fixed:1;
|
|
|
|
unsigned word_regexp:1;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum grep_expr_node {
|
|
|
|
GREP_NODE_ATOM,
|
|
|
|
GREP_NODE_NOT,
|
|
|
|
GREP_NODE_AND,
|
|
|
|
GREP_NODE_OR,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct grep_expr {
|
|
|
|
enum grep_expr_node node;
|
|
|
|
unsigned hit;
|
|
|
|
union {
|
|
|
|
struct grep_pat *atom;
|
|
|
|
struct grep_expr *unary;
|
|
|
|
struct {
|
|
|
|
struct grep_expr *left;
|
|
|
|
struct grep_expr *right;
|
|
|
|
} binary;
|
|
|
|
} u;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct grep_opt {
|
|
|
|
struct grep_pat *pattern_list;
|
|
|
|
struct grep_pat **pattern_tail;
|
|
|
|
struct grep_expr *pattern_expression;
|
|
|
|
const char *prefix;
|
|
|
|
int prefix_length;
|
|
|
|
regex_t regexp;
|
|
|
|
int linenum;
|
|
|
|
int invert;
|
|
|
|
int status_only;
|
|
|
|
int name_only;
|
|
|
|
int unmatch_name_only;
|
|
|
|
int count;
|
|
|
|
int word_regexp;
|
|
|
|
int fixed;
|
|
|
|
int all_match;
|
|
|
|
#define GREP_BINARY_DEFAULT 0
|
|
|
|
#define GREP_BINARY_NOMATCH 1
|
|
|
|
#define GREP_BINARY_TEXT 2
|
|
|
|
int binary;
|
|
|
|
int extended;
|
|
|
|
int relative;
|
|
|
|
int pathname;
|
|
|
|
int null_following_name;
|
|
|
|
int color;
|
grep: Add --max-depth option.
It is useful to grep directories non-recursively, e.g. when one wants to
look for all files in the toplevel directory, but not in any subdirectory,
or in Documentation/, but not in Documentation/technical/.
This patch adds support for --max-depth <depth> option to git-grep. If it is
given, git-grep descends at most <depth> levels of directories below paths
specified on the command line.
Note that if path specified on command line contains wildcards, this option
makes no sense, e.g.
$ git grep -l --max-depth 0 GNU -- 'contrib/*'
(note the quotes) will search all files in contrib/, even in
subdirectories, because '*' matches all files.
Documentation updates, bash-completion and simple test cases are also
provided.
Signed-off-by: Michał Kiedrowicz <michal.kiedrowicz@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
16 years ago
|
|
|
int max_depth;
|
|
|
|
int funcname;
|
|
|
|
char color_match[COLOR_MAXLEN];
|
|
|
|
const char *color_external;
|
|
|
|
int regflags;
|
|
|
|
unsigned pre_context;
|
|
|
|
unsigned post_context;
|
|
|
|
unsigned last_shown;
|
|
|
|
int show_hunk_mark;
|
|
|
|
void *priv;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
|
log --author/--committer: really match only with name part
When we tried to find commits done by AUTHOR, the first implementation
tried to pattern match a line with "^author .*AUTHOR", which later was
enhanced to strip leading caret and look for "^author AUTHOR" when the
search pattern was anchored at the left end (i.e. --author="^AUTHOR").
This had a few problems:
* When looking for fixed strings (e.g. "git log -F --author=x --grep=y"),
the regexp internally used "^author .*x" would never match anything;
* To match at the end (e.g. "git log --author='google.com>$'"), the
generated regexp has to also match the trailing timestamp part the
commit header lines have. Also, in order to determine if the '$' at
the end means "match at the end of the line" or just a literal dollar
sign (probably backslash-quoted), we would need to parse the regexp
ourselves.
An earlier alternative tried to make sure that a line matches "^author "
(to limit by field name) and the user supplied pattern at the same time.
While it solved the -F problem by introducing a special override for
matching the "^author ", it did not solve the trailing timestamp nor tail
match problem. It also would have matched every commit if --author=author
was asked for, not because the author's email part had this string, but
because every commit header line that talks about the author begins with
that field name, regardleses of who wrote it.
Instead of piling more hacks on top of hacks, this rethinks the grep
machinery that is used to look for strings in the commit header, and makes
sure that (1) field name matches literally at the beginning of the line,
followed by a SP, and (2) the user supplied pattern is matched against the
remainder of the line, excluding the trailing timestamp data.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
17 years ago
|
|
|
extern void append_header_grep_pattern(struct grep_opt *, enum grep_header_field, const char *);
|
|
|
|
extern void compile_grep_patterns(struct grep_opt *opt);
|
|
|
|
extern void free_grep_patterns(struct grep_opt *opt);
|
|
|
|
extern int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size);
|
|
|
|
|
|
|
|
#endif
|