1
0
Fork 0
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: use external grep when we can take advantage of it
This commit is contained in:
Junio C Hamano 2006-05-15 00:52:20 -07:00
commit a5954eccdd

View file

@ -12,6 +12,7 @@
#include "builtin.h"
#include <regex.h>
#include <fnmatch.h>
#include <sys/wait.h>
/*
* git grep pathspecs are somewhat different from diff-tree pathspecs;
@ -409,12 +410,90 @@ static int grep_file(struct grep_opt *opt, const char *filename)
return i;
}
static int exec_grep(int argc, const char **argv)
{
pid_t pid;
int status;
argv[argc] = NULL;
pid = fork();
if (pid < 0)
return pid;
if (!pid) {
execvp("grep", (char **) argv);
exit(255);
}
while (waitpid(pid, &status, 0) < 0) {
if (errno == EINTR)
continue;
return -1;
}
if (WIFEXITED(status)) {
if (!WEXITSTATUS(status))
return 1;
return 0;
}
return -1;
}
#define MAXARGS 1000
static int external_grep(struct grep_opt *opt, const char **paths, int cached)
{
int i, nr, argc, hit;
const char *argv[MAXARGS+1];
struct grep_pat *p;
nr = 0;
argv[nr++] = "grep";
if (opt->word_regexp)
argv[nr++] = "-w";
if (opt->name_only)
argv[nr++] = "-l";
for (p = opt->pattern_list; p; p = p->next) {
argv[nr++] = "-e";
argv[nr++] = p->pattern;
}
argv[nr++] = "--";
hit = 0;
argc = nr;
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))
continue;
if (!pathspec_matches(paths, ce->name))
continue;
argv[argc++] = ce->name;
if (argc < MAXARGS)
continue;
hit += exec_grep(argc, argv);
argc = nr;
}
if (argc > nr)
hit += exec_grep(argc, argv);
return 0;
}
static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
{
int hit = 0;
int nr;
read_cache();
#ifdef __unix__
/*
* Use the external "grep" command for the case where
* we grep through the checked-out files. It tends to
* be a lot more optimized
*/
if (!cached) {
hit = external_grep(opt, paths, cached);
if (hit >= 0)
return hit;
}
#endif
for (nr = 0; nr < active_nr; nr++) {
struct cache_entry *ce = active_cache[nr];
if (ce_stage(ce) || !S_ISREG(ntohl(ce->ce_mode)))