Exemple #1
0
static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
		       struct object *obj, const char *name)
{
	if (obj->type == OBJ_BLOB)
		return grep_sha1(opt, obj->sha1, name, 0, NULL);
	if (obj->type == OBJ_COMMIT || obj->type == OBJ_TREE) {
		struct tree_desc tree;
		void *data;
		unsigned long size;
		struct strbuf base;
		int hit, len;

		grep_read_lock();
		data = read_object_with_reference(obj->sha1, tree_type,
						  &size, NULL);
		grep_read_unlock();

		if (!data)
			die(_("unable to read tree (%s)"), sha1_to_hex(obj->sha1));

		len = name ? strlen(name) : 0;
		strbuf_init(&base, PATH_MAX + len + 1);
		if (len) {
			strbuf_add(&base, name, len);
			strbuf_addch(&base, ':');
		}
		init_tree_desc(&tree, data, size);
		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
				obj->type == OBJ_COMMIT);
		strbuf_release(&base);
		free(data);
		return hit;
	}
	die(_("unable to grep from object of type %s"), typename(obj->type));
}
Exemple #2
0
static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
{
	void *data;

	grep_read_lock();
	data = read_sha1_file(sha1, type, size);
	grep_read_unlock();
	return data;
}
Exemple #3
0
static void *lock_and_read_oid_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
{
	void *data;

	grep_read_lock();
	data = read_sha1_file(oid->hash, type, size);
	grep_read_unlock();
	return data;
}
Exemple #4
0
static int fill_textconv_grep(struct userdiff_driver *driver,
			      struct grep_source *gs)
{
	struct diff_filespec *df;
	char *buf;
	size_t size;

	if (!driver || !driver->textconv)
		return grep_source_load(gs);

	/*
	 * The textconv interface is intimately tied to diff_filespecs, so we
	 * have to pretend to be one. If we could unify the grep_source
	 * and diff_filespec structs, this mess could just go away.
	 */
	df = alloc_filespec(gs->path);
	switch (gs->type) {
	case GREP_SOURCE_SHA1:
		fill_filespec(df, gs->identifier, 1, 0100644);
		break;
	case GREP_SOURCE_FILE:
		fill_filespec(df, null_sha1, 0, 0100644);
		break;
	default:
		die("BUG: attempt to textconv something without a path?");
	}

	/*
	 * fill_textconv is not remotely thread-safe; it may load objects
	 * behind the scenes, and it modifies the global diff tempfile
	 * structure.
	 */
	grep_read_lock();
	size = fill_textconv(driver, df, &buf);
	grep_read_unlock();
	free_filespec(df);

	/*
	 * The normal fill_textconv usage by the diff machinery would just keep
	 * the textconv'd buf separate from the diff_filespec. But much of the
	 * grep code passes around a grep_source and assumes that its "buf"
	 * pointer is the beginning of the thing we are searching. So let's
	 * install our textconv'd version into the grep_source, taking care not
	 * to leak any existing buffer.
	 */
	grep_source_clear_data(gs);
	gs->buf = buf;
	gs->size = size;

	return 0;
}
Exemple #5
0
static int grep_source_load_sha1(struct grep_source *gs)
{
	enum object_type type;

	grep_read_lock();
	gs->buf = read_sha1_file(gs->identifier, &type, &gs->size);
	grep_read_unlock();

	if (!gs->buf)
		return error(_("'%s': unable to read %s"),
			     gs->name,
			     sha1_to_hex(gs->identifier));
	return 0;
}
Exemple #6
0
static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
			  const struct pathspec *pathspec,
			  const struct object_id *oid,
			  const char *filename, const char *path)
{
	struct repository submodule;
	int hit;

	if (!is_submodule_active(superproject, path))
		return 0;

	if (repo_submodule_init(&submodule, superproject, path))
		return 0;

	repo_read_gitmodules(&submodule);

	/*
	 * NEEDSWORK: This adds the submodule's object directory to the list of
	 * alternates for the single in-memory object store.  This has some bad
	 * consequences for memory (processed objects will never be freed) and
	 * performance (this increases the number of pack files git has to pay
	 * attention to, to the sum of the number of pack files in all the
	 * repositories processed so far).  This can be removed once the object
	 * store is no longer global and instead is a member of the repository
	 * object.
	 */
	grep_read_lock();
	add_to_alternates_memory(submodule.objectdir);
	grep_read_unlock();

	if (oid) {
		struct object *object;
		struct tree_desc tree;
		void *data;
		unsigned long size;
		struct strbuf base = STRBUF_INIT;

		object = parse_object_or_die(oid, oid_to_hex(oid));

		grep_read_lock();
		data = read_object_with_reference(object->oid.hash, tree_type,
						  &size, NULL);
		grep_read_unlock();

		if (!data)
			die(_("unable to read tree (%s)"), oid_to_hex(&object->oid));

		strbuf_addstr(&base, filename);
		strbuf_addch(&base, '/');

		init_tree_desc(&tree, data, size);
		hit = grep_tree(opt, pathspec, &tree, &base, base.len,
				object->type == OBJ_COMMIT, &submodule);
		strbuf_release(&base);
		free(data);
	} else {
		hit = grep_cache(opt, &submodule, pathspec, 1);
	}

	repo_clear(&submodule);
	return hit;
}