From: Junio C Hamano Date: Sun, 13 Sep 2009 08:24:20 +0000 (-0700) Subject: Merge branch 'cb/maint-1.6.3-grep-relative-up' into maint X-Git-Tag: v1.6.4.3~2 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/45c58ba00a9c4e31e94997b59fd8112f962fa222?ds=inline;hp=-c Merge branch 'cb/maint-1.6.3-grep-relative-up' into maint * cb/maint-1.6.3-grep-relative-up: grep: accept relative paths outside current working directory grep: fix exit status if external_grep() punts Conflicts: t/t7002-grep.sh --- 45c58ba00a9c4e31e94997b59fd8112f962fa222 diff --combined builtin-grep.c index f477659100,eda2c88487..fd450bc16e --- a/builtin-grep.c +++ b/builtin-grep.c @@@ -10,9 -10,8 +10,10 @@@ #include "tag.h" #include "tree-walk.h" #include "builtin.h" +#include "parse-options.h" +#include "userdiff.h" #include "grep.h" + #include "quote.h" #ifndef NO_EXTERNAL_GREP #ifdef __unix__ @@@ -22,21 -21,12 +23,21 @@@ #endif #endif -static int builtin_grep; +static char const * const grep_usage[] = { + "git grep [options] [-e] [...] [[--] path...]", + NULL +}; static int grep_config(const char *var, const char *value, void *cb) { struct grep_opt *opt = cb; + switch (userdiff_config(var, value)) { + case 0: break; + case -1: return -1; + default: return 0; + } + if (!strcmp(var, "color.grep")) { opt->color = git_config_colorbool(var, value, -1); return 0; @@@ -125,8 -115,8 +126,8 @@@ static int grep_sha1(struct grep_opt *o unsigned long size; char *data; enum object_type type; - char *to_free = NULL; int hit; + struct strbuf pathbuf = STRBUF_INIT; data = read_sha1_file(sha1, &type, &size); if (!data) { @@@ -134,26 -124,13 +135,13 @@@ return 0; } if (opt->relative && opt->prefix_length) { - static char name_buf[PATH_MAX]; - char *cp; - int name_len = strlen(name) - opt->prefix_length + 1; - - if (!tree_name_len) - name += opt->prefix_length; - else { - if (ARRAY_SIZE(name_buf) <= name_len) - cp = to_free = xmalloc(name_len); - else - cp = name_buf; - memcpy(cp, name, tree_name_len); - strcpy(cp + tree_name_len, - name + tree_name_len + opt->prefix_length); - name = cp; - } + quote_path_relative(name + tree_name_len, -1, &pathbuf, opt->prefix); + strbuf_insert(&pathbuf, 0, name, tree_name_len); + name = pathbuf.buf; } hit = grep_buffer(opt, name, data, size); + strbuf_release(&pathbuf); free(data); - free(to_free); return hit; } @@@ -163,6 -140,7 +151,7 @@@ static int grep_file(struct grep_opt *o int i; char *data; size_t sz; + struct strbuf buf = STRBUF_INIT; if (lstat(filename, &st) < 0) { err_ret: @@@ -187,8 -165,9 +176,9 @@@ } close(i); if (opt->relative && opt->prefix_length) - filename += opt->prefix_length; + filename = quote_path_relative(filename, -1, &buf, opt->prefix); i = grep_buffer(opt, filename, data, sz); + strbuf_release(&buf); free(data); return i; } @@@ -285,17 -264,6 +275,17 @@@ static int flush_grep(struct grep_opt * argc -= 2; } + if (opt->pre_context || opt->post_context) { + /* + * grep handles hunk marks between files, but we need to + * do that ourselves between multiple calls. + */ + if (opt->show_hunk_mark) + write_or_die(1, "--\n", 3); + else + opt->show_hunk_mark = 1; + } + status = exec_grep(argc, argv); if (kept_0) { @@@ -454,8 -422,7 +444,8 @@@ static int external_grep(struct grep_op } #endif -static int grep_cache(struct grep_opt *opt, const char **paths, int cached) +static int grep_cache(struct grep_opt *opt, const char **paths, int cached, + int external_grep_allowed) { int hit = 0; int nr; @@@ -467,10 -434,11 +457,11 @@@ * we grep through the checked-out files. It tends to * be a lot more optimized */ - if (!cached && !builtin_grep) { + if (!cached && external_grep_allowed) { hit = external_grep(opt, paths, cached); if (hit >= 0) return hit; + hit = 0; } #endif @@@ -583,186 -551,28 +574,187 @@@ static int grep_object(struct grep_opt die("unable to grep from object of type %s", typename(obj->type)); } -static const char builtin_grep_usage[] = -"git grep