summaryrefslogtreecommitdiff
path: root/grep.c
AgeCommit message (Collapse)Author
2010-04-03Merge branch 'rs/threaded-grep-context'Junio C Hamano
* rs/threaded-grep-context: grep: enable threading for context line printing Conflicts: grep.c
2010-03-20Merge branch 'ml/color-grep'Junio C Hamano
* ml/color-grep: grep: Colorize selected, context, and function lines grep: Colorize filename, line number, and separator Add GIT_COLOR_BOLD_* and GIT_COLOR_BG_*
2010-03-15grep: enable threading for context line printingRené Scharfe
If context lines are to be printed, grep separates them with hunk marks ("--\n"). These marks are printed between matches from different files, too. They are not printed before the first file, though. Threading was disabled when context line printing was enabled because avoiding to print the mark before the first line was an unsolved synchronisation problem. This patch separates the code for printing hunk marks for the threaded and the unthreaded case, allowing threading to be turned on together with the common -ABC options. ->show_hunk_mark, which controls printing of hunk marks between files in show_line(), is now set in grep_buffer_1(), but only if some results have already been printed and threading is disabled. The threaded case is handled in work_done(). Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-08grep: Colorize selected, context, and function linesMark Lodato
Colorize non-matching text of selected lines, context lines, and function name lines. The default for all three is no color, but they can be configured using color.grep.<slot>. The first two are similar to the corresponding options in GNU grep, except that GNU grep applies the color to the entire line, not just non-matching text. Signed-off-by: Mark Lodato <lodatom@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-08grep: Colorize filename, line number, and separatorMark Lodato
Colorize the filename, line number, and separator in git grep output, as GNU grep does. The colors are customizable through color.grep.<slot>. The default is to only color the separator (in cyan), since this gives the biggest legibility increase without overwhelming the user with colors. GNU grep also defaults cyan for the separator, but defaults to magenta for the filename and to green for the line number, as well. There is one difference from GNU grep: When a binary file matches without -a, GNU grep does not color the <file> in "Binary file <file> matches", but we do. Like GNU grep, if --null is given, the null separators are not colored. For config.txt, use a a sub-list to describe the slots, rather than a single paragraph with parentheses, since this is much more readable. Remove the cast to int for `rm_eo - rm_so` since it is not necessary. Signed-off-by: Mark Lodato <lodatom@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-02Merge branch 'jc/grep-author-all-match-implicit'Junio C Hamano
* jc/grep-author-all-match-implicit: "log --author=me --grep=it" should find intersection, not union
2010-02-03grep: simplify assignment of ->fixedRené Scharfe
After 885d211e, the value of the ->fixed pattern option only depends on the grep option of the same name. Regex flags don't matter any more, because fixed mode and regex mode are strictly separated. Thus we can simply copy the value from struct grep_opt to struct grep_pat, as we do already for ->word_regexp and ->ignore_case. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-28Merge branch 'fk/threaded-grep'Junio C Hamano
* fk/threaded-grep: Threaded grep grep: expose "status-only" feature via -q
2010-01-26grep: use REG_STARTEND (if available) to speed up regexecBenjamin Kramer
BSD and glibc have an extension to regexec which takes a buffer + length pair instead of a NUL-terminated string. Since we already have the length computed this can save us a strlen call inside regexec. Signed-off-by: Benjamin Kramer <benny.kra@googlemail.com> Acked-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-26Threaded grepFredrik Kuivinen
Make git grep use threads when it is available. The results below are best of five runs in the Linux repository (on a box with two cores). With the patch: git grep qwerty 1.58user 0.55system 0:01.16elapsed 183%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+800outputs (0major+5774minor)pagefaults 0swaps Without: git grep qwerty 1.59user 0.43system 0:02.02elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+800outputs (0major+3716minor)pagefaults 0swaps And with a pattern with quite a few matches: With the patch: $ /usr/bin/time git grep void 5.61user 0.56system 0:03.44elapsed 179%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+800outputs (0major+5587minor)pagefaults 0swaps Without: $ /usr/bin/time git grep void 5.36user 0.51system 0:05.87elapsed 100%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+800outputs (0major+3693minor)pagefaults 0swaps In either case we gain about 40% by the threading. Signed-off-by: Fredrik Kuivinen <frekui@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-26"log --author=me --grep=it" should find intersection, not unionJunio C Hamano
Historically, any grep filter in "git log" family of commands were taken as restricting to commits with any of the words in the commit log message. However, the user almost always want to find commits "done by this person on that topic". With "--all-match" option, a series of grep patterns can be turned into a requirement that all of them must produce a match, but that makes it impossible to ask for "done by me, on either this or that" with: log --author=me --committer=him --grep=this --grep=that because it will require both "this" and "that" to appear. Change the "header" parser of grep library to treat the headers specially, and parse it as: (all-match-OR (HEADER-AUTHOR me) (HEADER-COMMITTER him) (OR (PATTERN this) (PATTERN that) ) ) Even though the "log" command line parser doesn't give direct access to the extended grep syntax to group terms with parentheses, this change will cover the majority of the case the users would want. This incidentally revealed that one test in t7002 was bogus. It ran: log --author=Thor --grep=Thu --format='%s' and expected (wrongly) "Thu" to match "Thursday" in the author/committer date, but that would never match, as the timestamp in raw commit buffer does not have the name of the day-of-the-week. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-13grep: rip out pessimization to use fixmatch()Junio C Hamano
Even when running without the -F (--fixed-strings) option, we checked the pattern and used fixmatch() codepath when it does not contain any regex magic. Finding fixed strings with strstr() surely must be faster than running the regular expression crud. Not so. It turns out that on some libc implementations, using the regcomp()/regexec() pair is a lot faster than running strstr() and strcasestr() the fixmatch() codepath uses. Drop the optimization and use the fixmatch() codepath only when the user explicitly asked for it with the -F option. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-12Merge branch 'jc/maint-1.6.4-grep-lookahead' into jc/maint-grep-lookaheadJunio C Hamano
* jc/maint-1.6.4-grep-lookahead: grep: optimize built-in grep by skipping lines that do not hit This needs to be an evil merge as fixmatch() changed signature since 5183bf6 (grep: Allow case insensitive search of fixed-strings, 2009-11-06). Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-01-12grep: optimize built-in grep by skipping lines that do not hitJunio C Hamano
The internal "grep" engine we use checks for hits line-by-line, instead of letting the underlying regexec()/fixmatch() routines scan for the first match from the rest of the buffer. This was a major source of overhead compared to the external grep. Introduce a "look-ahead" mechanism to find the next line that would potentially match by using regexec()/fixmatch() in the remainder of the text to skip unmatching lines, and use it when the query criteria is simple enough (i.e. punt for an advanced grep boolean expression like "lines that have both X and Y but not Z" for now) and we are not running under "-v" (aka "--invert-match") option. Note that "-L" (aka "--files-without-match") is not a reason to disable this optimization. Under the option, we are interested if the file has any hit at all, and that is what we determine reliably with or without the optimization. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-11-17grep: Allow case insensitive search of fixed-stringsBrian Collins
"git grep" currently an error when you combine the -F and -i flags. This isn't in line with how GNU grep handles it. This patch allows the simultaneous use of those flags. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Brian Collins <bricollins@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-03grep: simplify -p outputRené Scharfe
It was found a bit too loud to show == separators between the function headers. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-02grep -p: support user defined regular expressionsRené Scharfe
Respect the userdiff attributes and config settings when looking for lines with function definitions in git grep -p. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-02grep: add option -p/--show-functionRené Scharfe
The new option -p instructs git grep to print the previous function definition as a context line, similar to diff -p. Such context lines are marked with an equal sign instead of a dash. This option complements the existing context options -A, -B, -C. Function definitions are detected using the same heuristic that diff uses. User defined regular expressions are not supported, yet. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-02grep: handle pre context lines on demandRené Scharfe
Factor out pre context line handling into the new function show_pre_context() and change the algorithm to rewind by looking for newline characters and roll forward again, instead of maintaining an array of line beginnings and ends. This is slower for hits, but the cost for non-matching lines becomes zero. Normally, there are far more non-matching lines, so the time spent in total decreases. Before this patch (current Linux kernel repo, best of five runs): $ time git grep --no-ext-grep -B1 memset >/dev/null real 0m2.134s user 0m1.932s sys 0m0.196s $ time git grep --no-ext-grep -B1000 memset >/dev/null real 0m12.059s user 0m11.837s sys 0m0.224s The same with this patch: $ time git grep --no-ext-grep -B1 memset >/dev/null real 0m2.117s user 0m1.892s sys 0m0.228s $ time git grep --no-ext-grep -B1000 memset >/dev/null real 0m2.986s user 0m2.696s sys 0m0.288s Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-02grep: print context hunk marks between filesRené Scharfe
Print a hunk mark before matches from a new file are shown, in addition to the current behaviour of printing them if lines have been skipped. The result is easier to read, as (presumably unrelated) matches from different files are separated by a hunk mark. GNU grep does the same. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-07-02grep: move context hunk mark handling into show_line()René Scharfe
Move last_shown into struct grep_opt, to make it available in show_line(), and then make the function handle the printing of hunk marks for context lines in a central place. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-03grep: fix empty word-regexp matchesRené Scharfe
The command "git grep -w ''" dies as soon as it encounters an empty line, reporting (wrongly) that "regexp returned nonsense". The first hunk of this patch relaxes the sanity check that is responsible for that, allowing matches to start at the end. The second hunk complements it by making sure that empty matches are rejected if -w was specified, as they are not really words. GNU grep does the same: $ echo foo | grep -c '' 1 $ echo foo | grep -c -w '' 0 Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-06-02grep: fix colouring of matches with zero lengthRené Scharfe
If a zero-length match is encountered, break out of loop and show the rest of the line uncoloured. Otherwise we'd be looping forever, trying to make progress by advancing the pointer by zero characters. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-23grep: fix word-regexp at the beginning of linesRené Scharfe
After bol is forwarded, it doesn't represent the beginning of the line any more. This means that the beginning-of-line marker (^) mustn't match, i.e. the regex flag REG_NOTBOL needs to be set. This bug was introduced by fb62eb7fab97cea880ea7fe4f341a4dfad14ab48 ("grep -w: forward to next possible position after rejected match"). Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-05-21grep: fix word-regexp colouringRené Scharfe
As noticed by Dmitry Gryazin: When a pattern is found but it doesn't start and end at word boundaries, bol is forwarded to after the match and the pattern is searched again. When a pattern is finally found between word boundaries, the match offsets are off by the number of characters that have been skipped. This patch corrects the offsets to be relative to the value of bol as passed to match_one_pattern() by its caller. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-04-28Merge branch 'maint'Junio C Hamano
* maint: grep: fix segfault when "git grep '('" is given Documentation: fix a grammatical error in api-builtin.txt builtin-merge: fix a typo in an error message
2009-04-28Merge branch 'maint-1.6.1' into maintJunio C Hamano
* maint-1.6.1: grep: fix segfault when "git grep '('" is given Documentation: fix a grammatical error in api-builtin.txt builtin-merge: fix a typo in an error message
2009-04-28Merge branch 'maint-1.6.0' into maint-1.6.1Junio C Hamano
* maint-1.6.0: grep: fix segfault when "git grep '('" is given Documentation: fix a grammatical error in api-builtin.txt builtin-merge: fix a typo in an error message
2009-04-28grep: fix segfault when "git grep '('" is givenLinus Torvalds
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-19git log: avoid segfault with --all-matchMichele Ballabio
Avoid a segfault when the command git log --all-match was issued, by ignoring the option. Signed-off-by: Michele Ballabio <barra_cuda@katamail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-09grep: cast printf %.*s "precision" argument explicitly to intJunio C Hamano
On some systems, regoff_t that is the type of rm_so/rm_eo members are wider than int; %.*s precision specifier expects an int, so use an explicit cast. A breakage reported on Darwin by Brian Gernhardt should be fixed with this patch. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07grep: color patterns in outputRené Scharfe
Coloring matches makes them easier to spot in the output. Add two options and two parameters: color.grep (to turn coloring on or off), color.grep.match (to set the color of matches), --color and --no-color (to turn coloring on or off, respectively). The output of external greps is not changed. This patch is based on earlier ones by Nguyễn Thái Ngọc Duy and Thiago Alves. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07grep: add pmatch and eflags arguments to match_one_pattern()René Scharfe
Push pmatch and eflags to the callers of match_one_pattern(), which allows them to specify regex execution flags and to get the location of a match. Since we only use the first element of the matches array and aren't interested in submatches, no provision is made for callers to provide a larger array. eflags are ignored for fixed patterns, but that's OK, since they only have a meaning in connection with regular expressions containing ^ or $. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07grep: remove grep_opt argument from match_expr_eval()René Scharfe
The only use of the struct grep_opt argument of match_expr_eval() is to pass the option word_regexp to match_one_pattern(). By adding a pattern flag for it we can reduce the number of function arguments of these two functions, as a cleanup and preparation for adding more in the next patch. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-03-07grep: micro-optimize hit collection for AND nodesRené Scharfe
In addition to returning if an expression matches a line, match_expr_eval() updates the expression's hit flag if the parameter collect_hits is set. It never sets collect_hits for children of AND nodes, though, so their hit flag will never be updated. Because of that we can return early if the first child didn't match, no matter if collect_hits is set or not. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18Add is_regex_special()René Scharfe
Add is_regex_special(), a character class macro for chars that have a special meaning in regular expressions. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-18Change NUL char handling of isspecial()René Scharfe
Replace isspecial() by the new macro is_glob_special(), which is more, well, specialized. The former included the NUL char in its character class, while the letter only included characters that are special to file name globbing. The new name contains underscores because they enhance readability considerably now that it's made up of three words. Renaming the function is necessary to document its changed scope. The call sites of isspecial() are updated to check explicitly for NUL. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-10grep: don't call regexec() for fixed stringsRené Scharfe
Add the new flag "fixed" to struct grep_pat and set it if the pattern is doesn't contain any regex control characters in addition to if the flag -F/--fixed-strings was specified. This gives a nice speed up on msysgit, where regexec() seems to be extra slow. Before (best of five runs): $ time git grep grep v1.6.1 >/dev/null real 0m0.552s user 0m0.000s sys 0m0.000s $ time git grep -F grep v1.6.1 >/dev/null real 0m0.170s user 0m0.000s sys 0m0.015s With the patch: $ time git grep grep v1.6.1 >/dev/null real 0m0.173s user 0m0.000s sys 0m0.000s The difference is much smaller on Linux, but still measurable. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-10grep -w: forward to next possible position after rejected matchRené Scharfe
grep -w accepts matches between non-word characters, only. If a match from regexec() doesn't meet this criteria, grep continues its search after the first character of that match. We can be a bit smarter here and skip all positions that follow a word character first, as they can't match our criteria. This way we can consume characters quite cheaply and don't need to special-case the handling of the beginning of a line. Here's a contrived example command on msysgit (best of five runs): $ time git grep -w ...... v1.6.1 >/dev/null real 0m1.611s user 0m0.000s sys 0m0.015s With the patch it's quite a bit faster: $ time git grep -w ...... v1.6.1 >/dev/null real 0m1.179s user 0m0.000s sys 0m0.015s More common search patterns will gain a lot less, but it's a nice clean up anyway. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2009-01-05remove trailing LF in die() messagesAlexander Potashev
LF at the end of format strings given to die() is redundant because die already adds one on its own. Signed-off-by: Alexander Potashev <aspotashev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-11-11Merge branch 'maint'Junio C Hamano
* maint: Fix non-literal format in printf-style calls git-submodule: Avoid printing a spurious message. git ls-remote: make usage string match manpage Makefile: help people who run 'make check' by mistake
2008-11-11Fix non-literal format in printf-style callsDaniel Lowe
These were found using gcc 4.3.2-1ubuntu11 with the warning: warning: format not a string literal and no format arguments Incorporated suggestions from Brandon Casey <casey@nrlssc.navy.mil>. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2008-10-01git grep: Add "-z/--null" option as in GNU's grep.Raphael Zimmerer
Here's a trivial patch that adds "-z" and "--null" options to "git grep". It was discussed on the mailing-list that git's "-z" convention should be used instead of GNU grep's "-Z". So things like 'git grep -l -z "$FOO" | xargs -0 sed -i "s/$FOO/$BOO/"' do work now. Signed-off-by: Raphael Zimmerer <killekulla@rdrz.de> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2008-09-05log --author/--committer: really match only with name partJunio C Hamano
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>
2007-06-05Move buffer_is_binary() to xdiff-interface.hJohannes Schindelin
We already have two instances where we want to determine if a buffer contains binary data as opposed to text. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2006-12-20simplify inclusion of system header files.Junio C Hamano
This is a mechanical clean-up of the way *.c files include system header files. (1) sources under compat/, platform sha-1 implementations, and xdelta code are exempt from the following rules; (2) the first #include must be "git-compat-util.h" or one of our own header file that includes it first (e.g. config.h, builtin.h, pkt-line.h); (3) system headers that are included in "git-compat-util.h" need not be included in individual C source files. (4) "git-compat-util.h" does not have to include subsystem specific header files (e.g. expat.h). Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-28grep --all-matchJunio C Hamano
This lets you say: git grep --all-match -e A -e B -e C to find lines that match A or B or C but limit the matches from the files that have all of A, B and C. This is different from git grep -e A --and -e B --and -e C in that the latter looks for a single line that has all of these at the same time. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-27grep: fix --fixed-strings combined with expression.Junio C Hamano
"git grep --fixed-strings -e GIT --and -e VERSION .gitignore" misbehaved because we did not notice this needs to grab lines that have the given two fixed strings at the same time. Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-27grep: free expressions and patterns when done.Junio C Hamano
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-20Update grep internal for grepping only in head/bodyJunio C Hamano
This further updates the built-in grep engine so that we can say something like "this pattern should match only in head". This can be used to simplify grepping in the log messages. Signed-off-by: Junio C Hamano <junkio@cox.net>