Merge branch 'nd/grep-true-path' into maint

"git grep -e pattern <tree>" asked the attribute system to read
"<tree>:.gitattributes" file in the working tree, which was
nonsense.

* nd/grep-true-path:
  grep: stop looking at random places for .gitattributes
maint
Junio C Hamano 2012-11-18 19:32:30 -08:00
commit dca5ed5f5b
4 changed files with 51 additions and 17 deletions

View File

@ -86,7 +86,7 @@ static pthread_cond_t cond_result;
static int skip_first_line; static int skip_first_line;


static void add_work(struct grep_opt *opt, enum grep_source_type type, static void add_work(struct grep_opt *opt, enum grep_source_type type,
const char *name, const void *id) const char *name, const char *path, const void *id)
{ {
grep_lock(); grep_lock();


@ -94,7 +94,7 @@ static void add_work(struct grep_opt *opt, enum grep_source_type type,
pthread_cond_wait(&cond_write, &grep_mutex); pthread_cond_wait(&cond_write, &grep_mutex);
} }


grep_source_init(&todo[todo_end].source, type, name, id); grep_source_init(&todo[todo_end].source, type, name, path, id);
if (opt->binary != GREP_BINARY_TEXT) if (opt->binary != GREP_BINARY_TEXT)
grep_source_load_driver(&todo[todo_end].source); grep_source_load_driver(&todo[todo_end].source);
todo[todo_end].done = 0; todo[todo_end].done = 0;
@ -280,7 +280,8 @@ static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type
} }


static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
const char *filename, int tree_name_len) const char *filename, int tree_name_len,
const char *path)
{ {
struct strbuf pathbuf = STRBUF_INIT; struct strbuf pathbuf = STRBUF_INIT;


@ -294,7 +295,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,


#ifndef NO_PTHREADS #ifndef NO_PTHREADS
if (use_threads) { if (use_threads) {
add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, sha1); add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
strbuf_release(&pathbuf); strbuf_release(&pathbuf);
return 0; return 0;
} else } else
@ -303,7 +304,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
struct grep_source gs; struct grep_source gs;
int hit; int hit;


grep_source_init(&gs, GREP_SOURCE_SHA1, pathbuf.buf, sha1); grep_source_init(&gs, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
strbuf_release(&pathbuf); strbuf_release(&pathbuf);
hit = grep_source(opt, &gs); hit = grep_source(opt, &gs);


@ -323,7 +324,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)


#ifndef NO_PTHREADS #ifndef NO_PTHREADS
if (use_threads) { if (use_threads) {
add_work(opt, GREP_SOURCE_FILE, buf.buf, filename); add_work(opt, GREP_SOURCE_FILE, buf.buf, filename, filename);
strbuf_release(&buf); strbuf_release(&buf);
return 0; return 0;
} else } else
@ -332,7 +333,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
struct grep_source gs; struct grep_source gs;
int hit; int hit;


grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename); grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
strbuf_release(&buf); strbuf_release(&buf);
hit = grep_source(opt, &gs); hit = grep_source(opt, &gs);


@ -388,7 +389,7 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) { if (cached || (ce->ce_flags & CE_VALID) || ce_skip_worktree(ce)) {
if (ce_stage(ce)) if (ce_stage(ce))
continue; continue;
hit |= grep_sha1(opt, ce->sha1, ce->name, 0); hit |= grep_sha1(opt, ce->sha1, ce->name, 0, ce->name);
} }
else else
hit |= grep_file(opt, ce->name); hit |= grep_file(opt, ce->name);
@ -406,7 +407,8 @@ static int grep_cache(struct grep_opt *opt, const struct pathspec *pathspec, int
} }


static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
struct tree_desc *tree, struct strbuf *base, int tn_len) struct tree_desc *tree, struct strbuf *base, int tn_len,
int check_attr)
{ {
int hit = 0; int hit = 0;
enum interesting match = entry_not_interesting; enum interesting match = entry_not_interesting;
@ -427,7 +429,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
strbuf_add(base, entry.path, te_len); strbuf_add(base, entry.path, te_len);


if (S_ISREG(entry.mode)) { if (S_ISREG(entry.mode)) {
hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len); hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len,
check_attr ? base->buf + tn_len : NULL);
} }
else if (S_ISDIR(entry.mode)) { else if (S_ISDIR(entry.mode)) {
enum object_type type; enum object_type type;
@ -442,7 +445,8 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,


strbuf_addch(base, '/'); strbuf_addch(base, '/');
init_tree_desc(&sub, data, size); init_tree_desc(&sub, data, size);
hit |= grep_tree(opt, pathspec, &sub, base, tn_len); hit |= grep_tree(opt, pathspec, &sub, base, tn_len,
check_attr);
free(data); free(data);
} }
strbuf_setlen(base, old_baselen); strbuf_setlen(base, old_baselen);
@ -457,7 +461,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
struct object *obj, const char *name) struct object *obj, const char *name)
{ {
if (obj->type == OBJ_BLOB) if (obj->type == OBJ_BLOB)
return grep_sha1(opt, obj->sha1, name, 0); return grep_sha1(opt, obj->sha1, name, 0, NULL);
if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) { if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
struct tree_desc tree; struct tree_desc tree;
void *data; void *data;
@ -480,7 +484,8 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
strbuf_addch(&base, ':'); strbuf_addch(&base, ':');
} }
init_tree_desc(&tree, data, size); init_tree_desc(&tree, data, size);
hit = grep_tree(opt, pathspec, &tree, &base, base.len); hit = grep_tree(opt, pathspec, &tree, &base, base.len,
obj->type == OBJ_COMMIT);
strbuf_release(&base); strbuf_release(&base);
free(data); free(data);
return hit; return hit;

11
grep.c
View File

@ -1550,7 +1550,7 @@ int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size)
struct grep_source gs; struct grep_source gs;
int r; int r;


grep_source_init(&gs, GREP_SOURCE_BUF, NULL, NULL); grep_source_init(&gs, GREP_SOURCE_BUF, NULL, NULL, NULL);
gs.buf = buf; gs.buf = buf;
gs.size = size; gs.size = size;


@ -1561,10 +1561,12 @@ int grep_buffer(struct grep_opt *opt, char *buf, unsigned long size)
} }


void grep_source_init(struct grep_source *gs, enum grep_source_type type, void grep_source_init(struct grep_source *gs, enum grep_source_type type,
const char *name, const void *identifier) const char *name, const char *path,
const void *identifier)
{ {
gs->type = type; gs->type = type;
gs->name = name ? xstrdup(name) : NULL; gs->name = name ? xstrdup(name) : NULL;
gs->path = path ? xstrdup(path) : NULL;
gs->buf = NULL; gs->buf = NULL;
gs->size = 0; gs->size = 0;
gs->driver = NULL; gs->driver = NULL;
@ -1586,6 +1588,8 @@ void grep_source_clear(struct grep_source *gs)
{ {
free(gs->name); free(gs->name);
gs->name = NULL; gs->name = NULL;
free(gs->path);
gs->path = NULL;
free(gs->identifier); free(gs->identifier);
gs->identifier = NULL; gs->identifier = NULL;
grep_source_clear_data(gs); grep_source_clear_data(gs);
@ -1678,7 +1682,8 @@ void grep_source_load_driver(struct grep_source *gs)
return; return;


grep_attr_lock(); grep_attr_lock();
gs->driver = userdiff_find_by_path(gs->name); if (gs->path)
gs->driver = userdiff_find_by_path(gs->path);
if (!gs->driver) if (!gs->driver)
gs->driver = userdiff_find_by_name("default"); gs->driver = userdiff_find_by_name("default");
grep_attr_unlock(); grep_attr_unlock();

4
grep.h
View File

@ -164,11 +164,13 @@ struct grep_source {
char *buf; char *buf;
unsigned long size; unsigned long size;


char *path; /* for attribute lookups */
struct userdiff_driver *driver; struct userdiff_driver *driver;
}; };


void grep_source_init(struct grep_source *gs, enum grep_source_type type, void grep_source_init(struct grep_source *gs, enum grep_source_type type,
const char *name, const void *identifier); const char *name, const char *path,
const void *identifier);
void grep_source_clear_data(struct grep_source *gs); void grep_source_clear_data(struct grep_source *gs);
void grep_source_clear(struct grep_source *gs); void grep_source_clear(struct grep_source *gs);
void grep_source_load_driver(struct grep_source *gs); void grep_source_load_driver(struct grep_source *gs);

View File

@ -111,6 +111,28 @@ test_expect_success 'grep respects binary diff attribute' '
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'grep --cached respects binary diff attribute' '
git grep --cached text t >actual &&
test_cmp expect actual
'

test_expect_success 'grep --cached respects binary diff attribute (2)' '
git add .gitattributes &&
rm .gitattributes &&
git grep --cached text t >actual &&
test_when_finished "git rm --cached .gitattributes" &&
test_when_finished "git checkout .gitattributes" &&
test_cmp expect actual
'

test_expect_success 'grep revision respects binary diff attribute' '
git commit -m new &&
echo "Binary file HEAD:t matches" >expect &&
git grep text HEAD -- t >actual &&
test_when_finished "git reset HEAD^" &&
test_cmp expect actual
'

test_expect_success 'grep respects not-binary diff attribute' ' test_expect_success 'grep respects not-binary diff attribute' '
echo binQary | q_to_nul >b && echo binQary | q_to_nul >b &&
git add b && git add b &&