Exemplo n.º 1
0
static int show_reference(const char *refname, const struct object_id *oid,
			  int flag, void *cb_data)
{
	struct show_data *data = cb_data;

	if (!wildmatch(data->pattern, refname, 0)) {
		if (data->format == REPLACE_FORMAT_SHORT)
			printf("%s\n", refname);
		else if (data->format == REPLACE_FORMAT_MEDIUM)
			printf("%s -> %s\n", refname, oid_to_hex(oid));
		else { /* data->format == REPLACE_FORMAT_LONG */
			struct object_id object;
			enum object_type obj_type, repl_type;

			if (get_oid(refname, &object))
				return error("Failed to resolve '%s' as a valid ref.", refname);

			obj_type = oid_object_info(the_repository, &object,
						   NULL);
			repl_type = oid_object_info(the_repository, oid, NULL);

			printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type),
			       oid_to_hex(oid), type_name(repl_type));
		}
	}

	return 0;
}
Exemplo n.º 2
0
Arquivo: tag.c Projeto: PEPE-coin/git
int gpg_verify_tag(const struct object_id *oid, const char *name_to_report,
		unsigned flags)
{
	enum object_type type;
	char *buf;
	unsigned long size;
	int ret;

	type = oid_object_info(the_repository, oid, NULL);
	if (type != OBJ_TAG)
		return error("%s: cannot verify a non-tag object of type %s.",
				name_to_report ?
				name_to_report :
				find_unique_abbrev(oid, DEFAULT_ABBREV),
				type_name(type));

	buf = read_object_file(oid, &type, &size);
	if (!buf)
		return error("%s: unable to read file.",
				name_to_report ?
				name_to_report :
				find_unique_abbrev(oid, DEFAULT_ABBREV));

	ret = run_gpg_verify(buf, size, flags);

	free(buf);
	return ret;
}
Exemplo n.º 3
0
static int prune_object(const struct object_id *oid, const char *fullpath,
			void *data)
{
	struct stat st;

	/*
	 * Do we know about this object?
	 * It must have been reachable
	 */
	if (lookup_object(oid->hash))
		return 0;

	if (lstat(fullpath, &st)) {
		/* report errors, but do not stop pruning */
		error("Could not stat '%s'", fullpath);
		return 0;
	}
	if (st.st_mtime > expire)
		return 0;
	if (show_only || verbose) {
		enum object_type type = oid_object_info(the_repository, oid,
							NULL);
		printf("%s %s\n", oid_to_hex(oid),
		       (type > 0) ? type_name(type) : "unknown");
	}
	if (!show_only)
		unlink_or_warn(fullpath);
	return 0;
}
Exemplo n.º 4
0
static int show_tree(const struct object_id *oid, struct strbuf *base,
		const char *pathname, unsigned mode, int stage, void *context)
{
	int retval = 0;
	int baselen;
	const char *type = blob_type;

	if (S_ISGITLINK(mode)) {
		/*
		 * Maybe we want to have some recursive version here?
		 *
		 * Something similar to this incomplete example:
		 *
		if (show_subprojects(base, baselen, pathname))
			retval = READ_TREE_RECURSIVE;
		 *
		 */
		type = commit_type;
	} else if (S_ISDIR(mode)) {
		if (show_recursive(base->buf, base->len, pathname)) {
			retval = READ_TREE_RECURSIVE;
			if (!(ls_options & LS_SHOW_TREES))
				return retval;
		}
		type = tree_type;
	}
	else if (ls_options & LS_TREE_ONLY)
		return 0;

	if (!(ls_options & LS_NAME_ONLY)) {
		if (ls_options & LS_SHOW_SIZE) {
			char size_text[24];
			if (!strcmp(type, blob_type)) {
				unsigned long size;
				if (oid_object_info(oid, &size) == OBJ_BAD)
					xsnprintf(size_text, sizeof(size_text),
						  "BAD");
				else
					xsnprintf(size_text, sizeof(size_text),
						  "%lu", size);
			} else
				xsnprintf(size_text, sizeof(size_text), "-");
			printf("%06o %s %s %7s\t", mode, type,
			       find_unique_abbrev(oid, abbrev),
			       size_text);
		} else
			printf("%06o %s %s\t", mode, type,
			       find_unique_abbrev(oid, abbrev));
	}
	baselen = base->len;
	strbuf_addstr(base, pathname);
	write_name_quoted_relative(base->buf,
				   chomp_prefix ? ls_tree_prefix : NULL,
				   stdout, line_termination);
	strbuf_setlen(base, baselen);
	return retval;
}
Exemplo n.º 5
0
/**
 * Build the initial type index for the packfile
 */
void bitmap_writer_build_type_index(struct packing_data *to_pack,
				    struct pack_idx_entry **index,
				    uint32_t index_nr)
{
	uint32_t i;

	writer.commits = ewah_new();
	writer.trees = ewah_new();
	writer.blobs = ewah_new();
	writer.tags = ewah_new();
	ALLOC_ARRAY(to_pack->in_pack_pos, to_pack->nr_objects);

	for (i = 0; i < index_nr; ++i) {
		struct object_entry *entry = (struct object_entry *)index[i];
		enum object_type real_type;

		oe_set_in_pack_pos(to_pack, entry, i);

		switch (oe_type(entry)) {
		case OBJ_COMMIT:
		case OBJ_TREE:
		case OBJ_BLOB:
		case OBJ_TAG:
			real_type = oe_type(entry);
			break;

		default:
			real_type = oid_object_info(to_pack->repo,
						    &entry->idx.oid, NULL);
			break;
		}

		switch (real_type) {
		case OBJ_COMMIT:
			ewah_set(writer.commits, i);
			break;

		case OBJ_TREE:
			ewah_set(writer.trees, i);
			break;

		case OBJ_BLOB:
			ewah_set(writer.blobs, i);
			break;

		case OBJ_TAG:
			ewah_set(writer.tags, i);
			break;

		default:
			die("Missing type information for %s (%d/%d)",
			    oid_to_hex(&entry->idx.oid), real_type,
			    oe_type(entry));
		}
	}
}
Exemplo n.º 6
0
static enum list_objects_filter_result filter_blobs_limit(
	struct repository *r,
	enum list_objects_filter_situation filter_situation,
	struct object *obj,
	const char *pathname,
	const char *filename,
	void *filter_data_)
{
	struct filter_blobs_limit_data *filter_data = filter_data_;
	unsigned long object_length;
	enum object_type t;

	switch (filter_situation) {
	default:
		BUG("unknown filter_situation: %d", filter_situation);

	case LOFS_BEGIN_TREE:
		assert(obj->type == OBJ_TREE);
		/* always include all tree objects */
		return LOFR_MARK_SEEN | LOFR_DO_SHOW;

	case LOFS_END_TREE:
		assert(obj->type == OBJ_TREE);
		return LOFR_ZERO;

	case LOFS_BLOB:
		assert(obj->type == OBJ_BLOB);
		assert((obj->flags & SEEN) == 0);

		t = oid_object_info(r, &obj->oid, &object_length);
		if (t != OBJ_BLOB) { /* probably OBJ_NONE */
			/*
			 * We DO NOT have the blob locally, so we cannot
			 * apply the size filter criteria.  Be conservative
			 * and force show it (and let the caller deal with
			 * the ambiguity).
			 */
			goto include_it;
		}

		if (object_length < filter_data->max_bytes)
			goto include_it;

		if (filter_data->omits)
			oidset_insert(filter_data->omits, &obj->oid);
		return LOFR_MARK_SEEN; /* but not LOFR_DO_SHOW (hard omit) */
	}

include_it:
	if (filter_data->omits)
		oidset_remove(filter_data->omits, &obj->oid);
	return LOFR_MARK_SEEN | LOFR_DO_SHOW;
}
Exemplo n.º 7
0
static int replace_object_oid(const char *object_ref,
			       struct object_id *object,
			       const char *replace_ref,
			       struct object_id *repl,
			       int force)
{
	struct object_id prev;
	enum object_type obj_type, repl_type;
	struct strbuf ref = STRBUF_INIT;
	struct ref_transaction *transaction;
	struct strbuf err = STRBUF_INIT;
	int res = 0;

	obj_type = oid_object_info(the_repository, object, NULL);
	repl_type = oid_object_info(the_repository, repl, NULL);
	if (!force && obj_type != repl_type)
		return error("Objects must be of the same type.\n"
			     "'%s' points to a replaced object of type '%s'\n"
			     "while '%s' points to a replacement object of "
			     "type '%s'.",
			     object_ref, type_name(obj_type),
			     replace_ref, type_name(repl_type));

	if (check_ref_valid(object, &prev, &ref, force)) {
		strbuf_release(&ref);
		return -1;
	}

	transaction = ref_transaction_begin(&err);
	if (!transaction ||
	    ref_transaction_update(transaction, ref.buf, repl, &prev,
				   0, NULL, &err) ||
	    ref_transaction_commit(transaction, &err))
		res = error("%s", err.buf);

	ref_transaction_free(transaction);
	strbuf_release(&ref);
	return res;
}
Exemplo n.º 8
0
Arquivo: blame.c Projeto: ovmine/git
/*
 * Fill the blob_sha1 field of an origin if it hasn't, so that later
 * call to fill_origin_blob() can use it to locate the data.  blob_sha1
 * for an origin is also used to pass the blame for the entire file to
 * the parent to detect the case where a child's blob is identical to
 * that of its parent's.
 *
 * This also fills origin->mode for corresponding tree path.
 */
static int fill_blob_sha1_and_mode(struct blame_origin *origin)
{
	if (!is_null_oid(&origin->blob_oid))
		return 0;
	if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
		goto error_out;
	if (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB)
		goto error_out;
	return 0;
 error_out:
	oidclr(&origin->blob_oid);
	origin->mode = S_IFINVALID;
	return -1;
}
Exemplo n.º 9
0
Arquivo: fsck.c Projeto: DoWonJin/git
static const char *printable_type(struct object *obj)
{
	const char *ret;

	if (obj->type == OBJ_NONE) {
		enum object_type type = oid_object_info(&obj->oid, NULL);
		if (type > 0)
			object_as_type(obj, type, 0);
	}

	ret = type_name(obj->type);
	if (!ret)
		ret = "unknown";

	return ret;
}
Exemplo n.º 10
0
static int edit_and_replace(const char *object_ref, int force, int raw)
{
	char *tmpfile;
	enum object_type type;
	struct object_id old_oid, new_oid, prev;
	struct strbuf ref = STRBUF_INIT;

	if (get_oid(object_ref, &old_oid) < 0)
		return error("Not a valid object name: '%s'", object_ref);

	type = oid_object_info(the_repository, &old_oid, NULL);
	if (type < 0)
		return error("unable to get object type for %s",
			     oid_to_hex(&old_oid));

	if (check_ref_valid(&old_oid, &prev, &ref, force)) {
		strbuf_release(&ref);
		return -1;
	}
	strbuf_release(&ref);

	tmpfile = git_pathdup("REPLACE_EDITOBJ");
	if (export_object(&old_oid, type, raw, tmpfile)) {
		free(tmpfile);
		return -1;
	}
	if (launch_editor(tmpfile, NULL, NULL) < 0) {
		free(tmpfile);
		return error("editing object file failed");
	}
	if (import_object(&new_oid, type, raw, tmpfile)) {
		free(tmpfile);
		return -1;
	}
	free(tmpfile);

	if (!oidcmp(&old_oid, &new_oid))
		return error("new object is the same as the old one: '%s'", oid_to_hex(&old_oid));

	return replace_object_oid(object_ref, &old_oid, "replacement", &new_oid, force);
}
Exemplo n.º 11
0
struct object *parse_object(const struct object_id *oid)
{
	unsigned long size;
	enum object_type type;
	int eaten;
	const struct object_id *repl = lookup_replace_object(the_repository, oid);
	void *buffer;
	struct object *obj;

	obj = lookup_object(oid->hash);
	if (obj && obj->parsed)
		return obj;

	if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||
	    (!obj && has_object_file(oid) &&
	     oid_object_info(the_repository, oid, NULL) == OBJ_BLOB)) {
		if (check_object_signature(repl, NULL, 0, NULL) < 0) {
			error("sha1 mismatch %s", oid_to_hex(oid));
			return NULL;
		}
		parse_blob_buffer(lookup_blob(oid), NULL, 0);
		return lookup_object(oid->hash);
	}

	buffer = read_object_file(oid, &type, &size);
	if (buffer) {
		if (check_object_signature(repl, buffer, size, type_name(type)) < 0) {
			free(buffer);
			error("sha1 mismatch %s", oid_to_hex(repl));
			return NULL;
		}

		obj = parse_object_buffer(oid, type, size, buffer, &eaten);
		if (!eaten)
			free(buffer);
		return obj;
	}
	return NULL;
}
Exemplo n.º 12
0
Arquivo: blame.c Projeto: ovmine/git
static void verify_working_tree_path(struct commit *work_tree, const char *path)
{
	struct commit_list *parents;
	int pos;

	for (parents = work_tree->parents; parents; parents = parents->next) {
		const struct object_id *commit_oid = &parents->item->object.oid;
		struct object_id blob_oid;
		unsigned mode;

		if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&
		    oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB)
			return;
	}

	pos = cache_name_pos(path, strlen(path));
	if (pos >= 0)
		; /* path is in the index */
	else if (-1 - pos < active_nr &&
		 !strcmp(active_cache[-1 - pos]->name, path))
		; /* path is in the index, unmerged */
	else
		die("no such path '%s' in HEAD", path);
}
Exemplo n.º 13
0
static int write_tar_entry(struct archiver_args *args,
			   const struct object_id *oid,
			   const char *path, size_t pathlen,
			   unsigned int mode)
{
	struct ustar_header header;
	struct strbuf ext_header = STRBUF_INIT;
	unsigned int old_mode = mode;
	unsigned long size, size_in_header;
	void *buffer;
	int err = 0;

	memset(&header, 0, sizeof(header));

	if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
		*header.typeflag = TYPEFLAG_DIR;
		mode = (mode | 0777) & ~tar_umask;
	} else if (S_ISLNK(mode)) {
		*header.typeflag = TYPEFLAG_LNK;
		mode |= 0777;
	} else if (S_ISREG(mode)) {
		*header.typeflag = TYPEFLAG_REG;
		mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
	} else {
		return error(_("unsupported file mode: 0%o (SHA1: %s)"),
			     mode, oid_to_hex(oid));
	}
	if (pathlen > sizeof(header.name)) {
		size_t plen = get_path_prefix(path, pathlen,
					      sizeof(header.prefix));
		size_t rest = pathlen - plen - 1;
		if (plen > 0 && rest <= sizeof(header.name)) {
			memcpy(header.prefix, path, plen);
			memcpy(header.name, path + plen + 1, rest);
		} else {
			xsnprintf(header.name, sizeof(header.name), "%s.data",
				  oid_to_hex(oid));
			strbuf_append_ext_header(&ext_header, "path",
						 path, pathlen);
		}
	} else
		memcpy(header.name, path, pathlen);

	if (S_ISREG(mode) && !args->convert &&
	    oid_object_info(args->repo, oid, &size) == OBJ_BLOB &&
	    size > big_file_threshold)
		buffer = NULL;
	else if (S_ISLNK(mode) || S_ISREG(mode)) {
		enum object_type type;
		buffer = object_file_to_archive(args, path, oid, old_mode, &type, &size);
		if (!buffer)
			return error(_("cannot read %s"), oid_to_hex(oid));
	} else {
		buffer = NULL;
		size = 0;
	}

	if (S_ISLNK(mode)) {
		if (size > sizeof(header.linkname)) {
			xsnprintf(header.linkname, sizeof(header.linkname),
				  "see %s.paxheader", oid_to_hex(oid));
			strbuf_append_ext_header(&ext_header, "linkpath",
			                         buffer, size);
		} else
			memcpy(header.linkname, buffer, size);
	}

	size_in_header = size;
	if (S_ISREG(mode) && size > USTAR_MAX_SIZE) {
		size_in_header = 0;
		strbuf_append_ext_header_uint(&ext_header, "size", size);
	}

	prepare_header(args, &header, mode, size_in_header);

	if (ext_header.len > 0) {
		write_extended_header(args, oid, ext_header.buf,
				      ext_header.len);
	}
	strbuf_release(&ext_header);
	write_blocked(&header, sizeof(header));
	if (S_ISREG(mode) && size > 0) {
		if (buffer)
			write_blocked(buffer, size);
		else
			err = stream_blocked(oid);
	}
	free(buffer);
	return err;
}
Exemplo n.º 14
0
int cgit_ref_path_exists(const char *path, const char *ref, int file_only)
{
	struct object_id oid;
	unsigned long size;
	struct pathspec_item path_items = {
		.match = xstrdup(path),
		.len = strlen(path)
	};
	struct pathspec paths = {
		.nr = 1,
		.items = &path_items
	};
	struct walk_tree_context walk_tree_ctx = {
		.match_path = path,
		.matched_oid = &oid,
		.found_path = 0,
		.file_only = file_only
	};

	if (get_oid(ref, &oid))
		goto done;
	if (oid_object_info(the_repository, &oid, &size) != OBJ_COMMIT)
		goto done;
	read_tree_recursive(lookup_commit_reference(the_repository, &oid)->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);

done:
	free(path_items.match);
	return walk_tree_ctx.found_path;
}

int cgit_print_file(char *path, const char *head, int file_only)
{
	struct object_id oid;
	enum object_type type;
	char *buf;
	unsigned long size;
	struct commit *commit;
	struct pathspec_item path_items = {
		.match = path,
		.len = strlen(path)
	};
	struct pathspec paths = {
		.nr = 1,
		.items = &path_items
	};
	struct walk_tree_context walk_tree_ctx = {
		.match_path = path,
		.matched_oid = &oid,
		.found_path = 0,
		.file_only = file_only
	};

	if (get_oid(head, &oid))
		return -1;
	type = oid_object_info(the_repository, &oid, &size);
	if (type == OBJ_COMMIT) {
		commit = lookup_commit_reference(the_repository, &oid);
		read_tree_recursive(commit->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
		if (!walk_tree_ctx.found_path)
			return -1;
		type = oid_object_info(the_repository, &oid, &size);
	}
	if (type == OBJ_BAD)
		return -1;
	buf = read_object_file(&oid, &type, &size);
	if (!buf)
		return -1;
	buf[size] = '\0';
	html_raw(buf, size);
	free(buf);
	return 0;
}

void cgit_print_blob(const char *hex, char *path, const char *head, int file_only)
{
	struct object_id oid;
	enum object_type type;
	char *buf;
	unsigned long size;
	struct commit *commit;
	struct pathspec_item path_items = {
		.match = path,
		.len = path ? strlen(path) : 0
	};
	struct pathspec paths = {
		.nr = 1,
		.items = &path_items
	};
	struct walk_tree_context walk_tree_ctx = {
		.match_path = path,
		.matched_oid = &oid,
		.found_path = 0,
		.file_only = file_only
	};

	if (hex) {
		if (get_oid_hex(hex, &oid)) {
			cgit_print_error_page(400, "Bad request",
					"Bad hex value: %s", hex);
			return;
		}
	} else {
		if (get_oid(head, &oid)) {
			cgit_print_error_page(404, "Not found",
					"Bad ref: %s", head);
			return;
		}
	}

	type = oid_object_info(the_repository, &oid, &size);

	if ((!hex) && type == OBJ_COMMIT && path) {
		commit = lookup_commit_reference(the_repository, &oid);
		read_tree_recursive(commit->maybe_tree, "", 0, 0, &paths, walk_tree, &walk_tree_ctx);
		type = oid_object_info(the_repository, &oid, &size);
	}

	if (type == OBJ_BAD) {
		cgit_print_error_page(404, "Not found",
				"Bad object name: %s", hex);
		return;
	}

	buf = read_object_file(&oid, &type, &size);
	if (!buf) {
		cgit_print_error_page(500, "Internal server error",
				"Error reading object %s", hex);
		return;
	}

	buf[size] = '\0';
	if (buffer_is_binary(buf, size))
		ctx.page.mimetype = "application/octet-stream";
	else
		ctx.page.mimetype = "text/plain";
	ctx.page.filename = path;

	html("X-Content-Type-Options: nosniff\n");
	html("Content-Security-Policy: default-src 'none'\n");
	cgit_print_http_headers();
	html_raw(buf, size);
	free(buf);
}