コード例 #1
0
ファイル: connect.c プロジェクト: LinTeX9527/git
static int process_ref(int len, struct ref ***list, unsigned int flags,
		       struct oid_array *extra_have)
{
	struct object_id old_oid;
	const char *name;

	if (parse_oid_hex(packet_buffer, &old_oid, &name))
		return 0;
	if (*name != ' ')
		return 0;
	name++;

	if (extra_have && !strcmp(name, ".have")) {
		oid_array_append(extra_have, &old_oid);
	} else if (!strcmp(name, "capabilities^{}")) {
		die("protocol error: unexpected capabilities^{}");
	} else if (check_ref(name, flags)) {
		struct ref *ref = alloc_ref(name);
		oidcpy(&ref->old_oid, &old_oid);
		**list = ref;
		*list = &ref->next;
	}
	check_no_capabilities(len);
	return 1;
}
コード例 #2
0
ファイル: fetch-pack.c プロジェクト: hashpling/git
static void receive_wanted_refs(struct packet_reader *reader,
				struct ref **sought, int nr_sought)
{
	process_section_header(reader, "wanted-refs", 0);
	while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
		struct object_id oid;
		const char *end;
		int i;

		if (parse_oid_hex(reader->line, &oid, &end) || *end++ != ' ')
			die(_("expected wanted-ref, got '%s'"), reader->line);

		for (i = 0; i < nr_sought; i++) {
			if (!strcmp(end, sought[i]->name)) {
				oidcpy(&sought[i]->old_oid, &oid);
				break;
			}
		}

		if (i == nr_sought)
			die(_("unexpected wanted-ref: '%s'"), reader->line);
	}

	if (reader->status != PACKET_READ_DELIM)
		die(_("error processing wanted refs: %d"), reader->status);
}
コード例 #3
0
ファイル: fetch-pack.c プロジェクト: Noffica/git
static void add_sought_entry(struct ref ***sought, int *nr, int *alloc,
			     const char *name)
{
	struct ref *ref;
	struct object_id oid;
	const char *p;

	if (!parse_oid_hex(name, &oid, &p)) {
		if (*p == ' ') {
			/* <oid> <ref>, find refname */
			name = p + 1;
		} else if (*p == '\0') {
			; /* <oid>, leave oid as name */
		} else {
			/* <ref>, clear cruft from oid */
			oidclr(&oid);
		}
	} else {
		/* <ref>, clear cruft from get_oid_hex */
		oidclr(&oid);
	}

	ref = alloc_ref(name);
	oidcpy(&ref->old_oid, &oid);
	(*nr)++;
	ALLOC_GROW(*sought, *nr, *alloc);
	(*sought)[*nr - 1] = ref;
}
コード例 #4
0
ファイル: transport.c プロジェクト: MichaelBlume/git
static void read_alternate_refs(const char *path,
				alternate_ref_fn *cb,
				void *data)
{
	struct child_process cmd = CHILD_PROCESS_INIT;
	struct strbuf line = STRBUF_INIT;
	FILE *fh;

	fill_alternate_refs_command(&cmd, path);

	if (start_command(&cmd))
		return;

	fh = xfdopen(cmd.out, "r");
	while (strbuf_getline_lf(&line, fh) != EOF) {
		struct object_id oid;
		const char *p;

		if (parse_oid_hex(line.buf, &oid, &p) || *p) {
			warning(_("invalid line while parsing alternate refs: %s"),
				line.buf);
			break;
		}

		cb(&oid, data);
	}

	fclose(fh);
	finish_command(&cmd);
}
コード例 #5
0
ファイル: tag.c プロジェクト: PEPE-coin/git
int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
{
	struct object_id oid;
	char type[20];
	const char *bufptr = data;
	const char *tail = bufptr + size;
	const char *nl;

	if (item->object.parsed)
		return 0;
	item->object.parsed = 1;

	if (size < GIT_SHA1_HEXSZ + 24)
		return -1;
	if (memcmp("object ", bufptr, 7) || parse_oid_hex(bufptr + 7, &oid, &bufptr) || *bufptr++ != '\n')
		return -1;

	if (!starts_with(bufptr, "type "))
		return -1;
	bufptr += 5;
	nl = memchr(bufptr, '\n', tail - bufptr);
	if (!nl || sizeof(type) <= (nl - bufptr))
		return -1;
	memcpy(type, bufptr, nl - bufptr);
	type[nl - bufptr] = '\0';
	bufptr = nl + 1;

	if (!strcmp(type, blob_type)) {
		item->tagged = (struct object *)lookup_blob(&oid);
	} else if (!strcmp(type, tree_type)) {
		item->tagged = (struct object *)lookup_tree(&oid);
	} else if (!strcmp(type, commit_type)) {
		item->tagged = (struct object *)lookup_commit(&oid);
	} else if (!strcmp(type, tag_type)) {
		item->tagged = (struct object *)lookup_tag(&oid);
	} else {
		error("Unknown type %s", type);
		item->tagged = NULL;
	}

	if (bufptr + 4 < tail && starts_with(bufptr, "tag "))
		; 		/* good */
	else
		return -1;
	bufptr += 4;
	nl = memchr(bufptr, '\n', tail - bufptr);
	if (!nl)
		return -1;
	item->tag = xmemdupz(bufptr, nl - bufptr);
	bufptr = nl + 1;

	if (bufptr + 7 < tail && starts_with(bufptr, "tagger "))
		item->date = parse_tag_date(bufptr, tail);
	else
		item->date = 0;

	return 0;
}
コード例 #6
0
ファイル: fetch-pack.c プロジェクト: hashpling/git
static int is_unmatched_ref(const struct ref *ref)
{
	struct object_id oid;
	const char *p;
	return	ref->match_status == REF_NOT_MATCHED &&
		!parse_oid_hex(ref->name, &oid, &p) &&
		*p == '\0' &&
		oideq(&oid, &ref->old_oid);
}
コード例 #7
0
ファイル: connect.c プロジェクト: LinTeX9527/git
static int process_dummy_ref(void)
{
	struct object_id oid;
	const char *name;

	if (parse_oid_hex(packet_buffer, &oid, &name))
		return 0;
	if (*name != ' ')
		return 0;
	name++;

	return !oidcmp(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
}
コード例 #8
0
ファイル: connect.c プロジェクト: alexhenrie/git-po
static int process_dummy_ref(const char *line)
{
	struct object_id oid;
	const char *name;

	if (parse_oid_hex(line, &oid, &name))
		return 0;
	if (*name != ' ')
		return 0;
	name++;

	return oideq(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
}
コード例 #9
0
ファイル: test-repository.c プロジェクト: MichaelBlume/git
int cmd__repository(int argc, const char **argv)
{
	if (argc < 2)
		die("must have at least 2 arguments");
	if (!strcmp(argv[1], "parse_commit_in_graph")) {
		struct object_id oid;
		if (argc < 5)
			die("not enough arguments");
		if (parse_oid_hex(argv[4], &oid, &argv[4]))
			die("cannot parse oid '%s'", argv[4]);
		test_parse_commit_in_graph(argv[2], argv[3], &oid);
	} else if (!strcmp(argv[1], "get_commit_tree_in_graph")) {
		struct object_id oid;
		if (argc < 5)
			die("not enough arguments");
		if (parse_oid_hex(argv[4], &oid, &argv[4]))
			die("cannot parse oid '%s'", argv[4]);
		test_get_commit_tree_in_graph(argv[2], argv[3], &oid);
	} else {
		die("unrecognized '%s'", argv[1]);
	}
	return 0;
}
コード例 #10
0
ファイル: diff-tree.c プロジェクト: Litttle-butterfly/git
/* Diff two trees. */
static int stdin_diff_trees(struct tree *tree1, const char *p)
{
	struct object_id oid;
	struct tree *tree2;
	if (!isspace(*p++) || parse_oid_hex(p, &oid, &p) || *p)
		return error("Need exactly two trees, separated by a space");
	tree2 = lookup_tree(&oid);
	if (!tree2 || parse_tree(tree2))
		return -1;
	printf("%s %s\n", oid_to_hex(&tree1->object.oid),
			  oid_to_hex(&tree2->object.oid));
	diff_tree_oid(&tree1->object.oid, &tree2->object.oid,
		      "", &log_tree_opt.diffopt);
	log_tree_diff_flush(&log_tree_opt);
	return 0;
}
コード例 #11
0
ファイル: diff-tree.c プロジェクト: Litttle-butterfly/git
/* Diff one or more commits. */
static int stdin_diff_commit(struct commit *commit, const char *p)
{
	struct object_id oid;
	struct commit_list **pptr = NULL;

	/* Graft the fake parents locally to the commit */
	while (isspace(*p++) && !parse_oid_hex(p, &oid, &p)) {
		struct commit *parent = lookup_commit(&oid);
		if (!pptr) {
			/* Free the real parent list */
			free_commit_list(commit->parents);
			commit->parents = NULL;
			pptr = &(commit->parents);
		}
		if (parent) {
			pptr = &commit_list_insert(parent, pptr)->next;
		}
	}
	return log_tree_commit(&log_tree_opt, commit);
}
コード例 #12
0
ファイル: upload-pack.c プロジェクト: cEngineGit/git
static int get_reachable_list(struct object_array *src,
			      struct object_array *reachable)
{
	struct child_process cmd = CHILD_PROCESS_INIT;
	int i;
	struct object *o;
	char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
	const unsigned hexsz = the_hash_algo->hexsz;

	if (do_reachable_revlist(&cmd, src, reachable) < 0)
		return -1;

	while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) {
		struct object_id sha1;
		const char *p;

		if (parse_oid_hex(namebuf, &sha1, &p) || *p != '\n')
			break;

		o = lookup_object(sha1.hash);
		if (o && o->type == OBJ_COMMIT) {
			o->flags &= ~TMP_MARK;
		}
	}
	for (i = get_max_object_index(); 0 < i; i--) {
		o = get_indexed_object(i - 1);
		if (o && o->type == OBJ_COMMIT &&
		    (o->flags & TMP_MARK)) {
			add_object_array(o, NULL, reachable);
				o->flags &= ~TMP_MARK;
		}
	}
	close(cmd.out);

	if (finish_command(&cmd))
		return -1;

	return 0;
}
コード例 #13
0
ファイル: diff-tree.c プロジェクト: Litttle-butterfly/git
static int diff_tree_stdin(char *line)
{
	int len = strlen(line);
	struct object_id oid;
	struct object *obj;
	const char *p;

	if (!len || line[len-1] != '\n')
		return -1;
	line[len-1] = 0;
	if (parse_oid_hex(line, &oid, &p))
		return -1;
	obj = parse_object(&oid);
	if (!obj)
		return -1;
	if (obj->type == OBJ_COMMIT)
		return stdin_diff_commit((struct commit *)obj, p);
	if (obj->type == OBJ_TREE)
		return stdin_diff_trees((struct tree *)obj, p);
	error("Object %s is a %s, not a commit or tree",
	      oid_to_hex(&oid), typename(obj->type));
	return -1;
}
コード例 #14
0
ファイル: update-index.c プロジェクト: Nowher2/git
static int parse_new_style_cacheinfo(const char *arg,
				     unsigned int *mode,
				     struct object_id *oid,
				     const char **path)
{
	unsigned long ul;
	char *endp;
	const char *p;

	if (!arg)
		return -1;

	errno = 0;
	ul = strtoul(arg, &endp, 8);
	if (errno || endp == arg || *endp != ',' || (unsigned int) ul != ul)
		return -1; /* not a new-style cacheinfo */
	*mode = ul;
	endp++;
	if (parse_oid_hex(endp, oid, &p) || *p != ',')
		return -1;
	*path = p + 1;
	return 0;
}
コード例 #15
0
ファイル: fsck.c プロジェクト: PEPE-coin/git
static void init_skiplist(struct fsck_options *options, const char *path)
{
	static struct oid_array skiplist = OID_ARRAY_INIT;
	int sorted, fd;
	char buffer[GIT_MAX_HEXSZ + 1];
	struct object_id oid;

	if (options->skiplist)
		sorted = options->skiplist->sorted;
	else {
		sorted = 1;
		options->skiplist = &skiplist;
	}

	fd = open(path, O_RDONLY);
	if (fd < 0)
		die("Could not open skip list: %s", path);
	for (;;) {
		const char *p;
		int result = read_in_full(fd, buffer, sizeof(buffer));
		if (result < 0)
			die_errno("Could not read '%s'", path);
		if (!result)
			break;
		if (parse_oid_hex(buffer, &oid, &p) || *p != '\n')
			die("Invalid SHA-1: %s", buffer);
		oid_array_append(&skiplist, &oid);
		if (sorted && skiplist.nr > 1 &&
				oidcmp(&skiplist.oid[skiplist.nr - 2],
				       &oid) > 0)
			sorted = 0;
	}
	close(fd);

	if (sorted)
		skiplist.sorted = 1;
}
コード例 #16
0
ファイル: fetch-pack.c プロジェクト: DoWonJin/git
static void filter_refs(struct fetch_pack_args *args,
			struct ref **refs,
			struct ref **sought, int nr_sought)
{
	struct ref *newlist = NULL;
	struct ref **newtail = &newlist;
	struct ref *unmatched = NULL;
	struct ref *ref, *next;
	struct oidset tip_oids = OIDSET_INIT;
	int i;

	i = 0;
	for (ref = *refs; ref; ref = next) {
		int keep = 0;
		next = ref->next;

		if (starts_with(ref->name, "refs/") &&
		    check_refname_format(ref->name, 0))
			; /* trash */
		else {
			while (i < nr_sought) {
				int cmp = strcmp(ref->name, sought[i]->name);
				if (cmp < 0)
					break; /* definitely do not have it */
				else if (cmp == 0) {
					keep = 1; /* definitely have it */
					sought[i]->match_status = REF_MATCHED;
				}
				i++;
			}
		}

		if (!keep && args->fetch_all &&
		    (!args->deepen || !starts_with(ref->name, "refs/tags/")))
			keep = 1;

		if (keep) {
			*newtail = ref;
			ref->next = NULL;
			newtail = &ref->next;
		} else {
			ref->next = unmatched;
			unmatched = ref;
		}
	}

	/* Append unmatched requests to the list */
	for (i = 0; i < nr_sought; i++) {
		struct object_id oid;
		const char *p;

		ref = sought[i];
		if (ref->match_status != REF_NOT_MATCHED)
			continue;
		if (parse_oid_hex(ref->name, &oid, &p) ||
		    *p != '\0' ||
		    oidcmp(&oid, &ref->old_oid))
			continue;

		if ((allow_unadvertised_object_request &
		     (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1)) ||
		    tip_oids_contain(&tip_oids, unmatched, newlist,
				     &ref->old_oid)) {
			ref->match_status = REF_MATCHED;
			*newtail = copy_ref(ref);
			newtail = &(*newtail)->next;
		} else {
			ref->match_status = REF_UNADVERTISED_NOT_ALLOWED;
		}
	}

	oidset_clear(&tip_oids);
	for (ref = unmatched; ref; ref = next) {
		next = ref->next;
		free(ref);
	}

	*refs = newlist;
}
コード例 #17
0
ファイル: packed-backend.c プロジェクト: guban/git
/*
 * Move the iterator to the next record in the snapshot, without
 * respect for whether the record is actually required by the current
 * iteration. Adjust the fields in `iter` and return `ITER_OK` or
 * `ITER_DONE`. This function does not free the iterator in the case
 * of `ITER_DONE`.
 */
static int next_record(struct packed_ref_iterator *iter)
{
	const char *p = iter->pos, *eol;

	strbuf_reset(&iter->refname_buf);

	if (iter->pos == iter->eof)
		return ITER_DONE;

	iter->base.flags = REF_ISPACKED;

	if (iter->eof - p < GIT_SHA1_HEXSZ + 2 ||
	    parse_oid_hex(p, &iter->oid, &p) ||
	    !isspace(*p++))
		die_invalid_line(iter->snapshot->refs->path,
				 iter->pos, iter->eof - iter->pos);

	eol = memchr(p, '\n', iter->eof - p);
	if (!eol)
		die_unterminated_line(iter->snapshot->refs->path,
				      iter->pos, iter->eof - iter->pos);

	strbuf_add(&iter->refname_buf, p, eol - p);
	iter->base.refname = iter->refname_buf.buf;

	if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) {
		if (!refname_is_safe(iter->base.refname))
			die("packed refname is dangerous: %s",
			    iter->base.refname);
		oidclr(&iter->oid);
		iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
	}
	if (iter->snapshot->peeled == PEELED_FULLY ||
	    (iter->snapshot->peeled == PEELED_TAGS &&
	     starts_with(iter->base.refname, "refs/tags/")))
		iter->base.flags |= REF_KNOWS_PEELED;

	iter->pos = eol + 1;

	if (iter->pos < iter->eof && *iter->pos == '^') {
		p = iter->pos + 1;
		if (iter->eof - p < GIT_SHA1_HEXSZ + 1 ||
		    parse_oid_hex(p, &iter->peeled, &p) ||
		    *p++ != '\n')
			die_invalid_line(iter->snapshot->refs->path,
					 iter->pos, iter->eof - iter->pos);
		iter->pos = p;

		/*
		 * Regardless of what the file header said, we
		 * definitely know the value of *this* reference. But
		 * we suppress it if the reference is broken:
		 */
		if ((iter->base.flags & REF_ISBROKEN)) {
			oidclr(&iter->peeled);
			iter->base.flags &= ~REF_KNOWS_PEELED;
		} else {
			iter->base.flags |= REF_KNOWS_PEELED;
		}
	} else {
		oidclr(&iter->peeled);
	}

	return ITER_OK;
}
コード例 #18
0
ファイル: connect.c プロジェクト: alexhenrie/git-po
/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
static int process_ref_v2(const char *line, struct ref ***list)
{
	int ret = 1;
	int i = 0;
	struct object_id old_oid;
	struct ref *ref;
	struct string_list line_sections = STRING_LIST_INIT_DUP;
	const char *end;

	/*
	 * Ref lines have a number of fields which are space deliminated.  The
	 * first field is the OID of the ref.  The second field is the ref
	 * name.  Subsequent fields (symref-target and peeled) are optional and
	 * don't have a particular order.
	 */
	if (string_list_split(&line_sections, line, ' ', -1) < 2) {
		ret = 0;
		goto out;
	}

	if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) ||
	    *end) {
		ret = 0;
		goto out;
	}

	ref = alloc_ref(line_sections.items[i++].string);

	oidcpy(&ref->old_oid, &old_oid);
	**list = ref;
	*list = &ref->next;

	for (; i < line_sections.nr; i++) {
		const char *arg = line_sections.items[i].string;
		if (skip_prefix(arg, "symref-target:", &arg))
			ref->symref = xstrdup(arg);

		if (skip_prefix(arg, "peeled:", &arg)) {
			struct object_id peeled_oid;
			char *peeled_name;
			struct ref *peeled;
			if (parse_oid_hex(arg, &peeled_oid, &end) || *end) {
				ret = 0;
				goto out;
			}

			peeled_name = xstrfmt("%s^{}", ref->name);
			peeled = alloc_ref(peeled_name);

			oidcpy(&peeled->old_oid, &peeled_oid);
			**list = peeled;
			*list = &peeled->next;

			free(peeled_name);
		}
	}

out:
	string_list_clear(&line_sections, 0);
	return ret;
}
コード例 #19
0
ファイル: mktag.c プロジェクト: PhilipOakley/git
static int verify_tag(char *buffer, unsigned long size)
{
	int typelen;
	char type[20];
	struct object_id oid;
	const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
	size_t len;

	if (size < 84)
		return error("wanna fool me ? you obviously got the size wrong !");

	buffer[size] = 0;

	/* Verify object line */
	object = buffer;
	if (memcmp(object, "object ", 7))
		return error("char%d: does not start with \"object \"", 0);

	if (parse_oid_hex(object + 7, &oid, &p))
		return error("char%d: could not get SHA1 hash", 7);

	/* Verify type line */
	type_line = p + 1;
	if (memcmp(type_line - 1, "\ntype ", 6))
		return error("char%d: could not find \"\\ntype \"", 47);

	/* Verify tag-line */
	tag_line = strchr(type_line, '\n');
	if (!tag_line)
		return error("char%"PRIuMAX": could not find next \"\\n\"",
				(uintmax_t) (type_line - buffer));
	tag_line++;
	if (memcmp(tag_line, "tag ", 4) || tag_line[4] == '\n')
		return error("char%"PRIuMAX": no \"tag \" found",
				(uintmax_t) (tag_line - buffer));

	/* Get the actual type */
	typelen = tag_line - type_line - strlen("type \n");
	if (typelen >= sizeof(type))
		return error("char%"PRIuMAX": type too long",
				(uintmax_t) (type_line+5 - buffer));

	memcpy(type, type_line+5, typelen);
	type[typelen] = 0;

	/* Verify that the object matches */
	if (verify_object(&oid, type))
		return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));

	/* Verify the tag-name: we don't allow control characters or spaces in it */
	tag_line += 4;
	for (;;) {
		unsigned char c = *tag_line++;
		if (c == '\n')
			break;
		if (c > ' ')
			continue;
		return error("char%"PRIuMAX": could not verify tag name",
				(uintmax_t) (tag_line - buffer));
	}

	/* Verify the tagger line */
	tagger_line = tag_line;

	if (memcmp(tagger_line, "tagger ", 7))
		return error("char%"PRIuMAX": could not find \"tagger \"",
			(uintmax_t) (tagger_line - buffer));

	/*
	 * Check for correct form for name and email
	 * i.e. " <" followed by "> " on _this_ line
	 * No angle brackets within the name or email address fields.
	 * No spaces within the email address field.
	 */
	tagger_line += 7;
	if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
		strpbrk(tagger_line, "<>\n") != lb+1 ||
		strpbrk(lb+2, "><\n ") != rb)
		return error("char%"PRIuMAX": malformed tagger field",
			(uintmax_t) (tagger_line - buffer));

	/* Check for author name, at least one character, space is acceptable */
	if (lb == tagger_line)
		return error("char%"PRIuMAX": missing tagger name",
			(uintmax_t) (tagger_line - buffer));

	/* timestamp, 1 or more digits followed by space */
	tagger_line = rb + 2;
	if (!(len = strspn(tagger_line, "0123456789")))
		return error("char%"PRIuMAX": missing tag timestamp",
			(uintmax_t) (tagger_line - buffer));
	tagger_line += len;
	if (*tagger_line != ' ')
		return error("char%"PRIuMAX": malformed tag timestamp",
			(uintmax_t) (tagger_line - buffer));
	tagger_line++;

	/* timezone, 5 digits [+-]hhmm, max. 1400 */
	if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
	      strspn(tagger_line+1, "0123456789") == 4 &&
	      tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
		return error("char%"PRIuMAX": malformed tag timezone",
			(uintmax_t) (tagger_line - buffer));
	tagger_line += 6;

	/* Verify the blank line separating the header from the body */
	if (*tagger_line != '\n')
		return error("char%"PRIuMAX": trailing garbage in tag header",
			(uintmax_t) (tagger_line - buffer));

	/* The actual stuff afterwards we don't care about.. */
	return 0;
}
コード例 #20
0
ファイル: upload-pack.c プロジェクト: cEngineGit/git
static void receive_needs(void)
{
	struct object_array shallows = OBJECT_ARRAY_INIT;
	struct string_list deepen_not = STRING_LIST_INIT_DUP;
	int depth = 0;
	int has_non_tip = 0;
	timestamp_t deepen_since = 0;
	int deepen_rev_list = 0;

	shallow_nr = 0;
	for (;;) {
		struct object *o;
		const char *features;
		struct object_id oid_buf;
		char *line = packet_read_line(0, NULL);
		const char *arg;

		reset_timeout();
		if (!line)
			break;

		if (process_shallow(line, &shallows))
			continue;
		if (process_deepen(line, &depth))
			continue;
		if (process_deepen_since(line, &deepen_since, &deepen_rev_list))
			continue;
		if (process_deepen_not(line, &deepen_not, &deepen_rev_list))
			continue;

		if (skip_prefix(line, "filter ", &arg)) {
			if (!filter_capability_requested)
				die("git upload-pack: filtering capability not negotiated");
			parse_list_objects_filter(&filter_options, arg);
			continue;
		}

		if (!skip_prefix(line, "want ", &arg) ||
		    parse_oid_hex(arg, &oid_buf, &features))
			die("git upload-pack: protocol error, "
			    "expected to get object ID, not '%s'", line);

		if (parse_feature_request(features, "deepen-relative"))
			deepen_relative = 1;
		if (parse_feature_request(features, "multi_ack_detailed"))
			multi_ack = 2;
		else if (parse_feature_request(features, "multi_ack"))
			multi_ack = 1;
		if (parse_feature_request(features, "no-done"))
			no_done = 1;
		if (parse_feature_request(features, "thin-pack"))
			use_thin_pack = 1;
		if (parse_feature_request(features, "ofs-delta"))
			use_ofs_delta = 1;
		if (parse_feature_request(features, "side-band-64k"))
			use_sideband = LARGE_PACKET_MAX;
		else if (parse_feature_request(features, "side-band"))
			use_sideband = DEFAULT_PACKET_MAX;
		if (parse_feature_request(features, "no-progress"))
			no_progress = 1;
		if (parse_feature_request(features, "include-tag"))
			use_include_tag = 1;
		if (allow_filter && parse_feature_request(features, "filter"))
			filter_capability_requested = 1;

		o = parse_object(&oid_buf);
		if (!o) {
			packet_write_fmt(1,
					 "ERR upload-pack: not our ref %s",
					 oid_to_hex(&oid_buf));
			die("git upload-pack: not our ref %s",
			    oid_to_hex(&oid_buf));
		}
		if (!(o->flags & WANTED)) {
			o->flags |= WANTED;
			if (!((allow_unadvertised_object_request & ALLOW_ANY_SHA1) == ALLOW_ANY_SHA1
			      || is_our_ref(o)))
				has_non_tip = 1;
			add_object_array(o, NULL, &want_obj);
		}
	}

	/*
	 * We have sent all our refs already, and the other end
	 * should have chosen out of them. When we are operating
	 * in the stateless RPC mode, however, their choice may
	 * have been based on the set of older refs advertised
	 * by another process that handled the initial request.
	 */
	if (has_non_tip)
		check_non_tip();

	if (!use_sideband && daemon_mode)
		no_progress = 1;

	if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
		return;

	if (send_shallow_list(depth, deepen_rev_list, deepen_since,
			      &deepen_not, &shallows))
		packet_flush(1);
	object_array_clear(&shallows);
}
コード例 #21
0
ファイル: fsck.c プロジェクト: PEPE-coin/git
static int fsck_tag_buffer(struct tag *tag, const char *data,
	unsigned long size, struct fsck_options *options)
{
	struct object_id oid;
	int ret = 0;
	const char *buffer;
	char *to_free = NULL, *eol;
	struct strbuf sb = STRBUF_INIT;
	const char *p;

	if (data)
		buffer = data;
	else {
		enum object_type type;

		buffer = to_free =
			read_object_file(&tag->object.oid, &type, &size);
		if (!buffer)
			return report(options, &tag->object,
				FSCK_MSG_MISSING_TAG_OBJECT,
				"cannot read tag object");

		if (type != OBJ_TAG) {
			ret = report(options, &tag->object,
				FSCK_MSG_TAG_OBJECT_NOT_TAG,
				"expected tag got %s",
			    type_name(type));
			goto done;
		}
	}

	ret = verify_headers(buffer, size, &tag->object, options);
	if (ret)
		goto done;

	if (!skip_prefix(buffer, "object ", &buffer)) {
		ret = report(options, &tag->object, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
		goto done;
	}
	if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
		ret = report(options, &tag->object, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
		if (ret)
			goto done;
	}
	buffer = p + 1;

	if (!skip_prefix(buffer, "type ", &buffer)) {
		ret = report(options, &tag->object, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line");
		goto done;
	}
	eol = strchr(buffer, '\n');
	if (!eol) {
		ret = report(options, &tag->object, FSCK_MSG_MISSING_TYPE, "invalid format - unexpected end after 'type' line");
		goto done;
	}
	if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
		ret = report(options, &tag->object, FSCK_MSG_BAD_TYPE, "invalid 'type' value");
	if (ret)
		goto done;
	buffer = eol + 1;

	if (!skip_prefix(buffer, "tag ", &buffer)) {
		ret = report(options, &tag->object, FSCK_MSG_MISSING_TAG_ENTRY, "invalid format - expected 'tag' line");
		goto done;
	}
	eol = strchr(buffer, '\n');
	if (!eol) {
		ret = report(options, &tag->object, FSCK_MSG_MISSING_TAG, "invalid format - unexpected end after 'type' line");
		goto done;
	}
	strbuf_addf(&sb, "refs/tags/%.*s", (int)(eol - buffer), buffer);
	if (check_refname_format(sb.buf, 0)) {
		ret = report(options, &tag->object, FSCK_MSG_BAD_TAG_NAME,
			   "invalid 'tag' name: %.*s",
			   (int)(eol - buffer), buffer);
		if (ret)
			goto done;
	}
	buffer = eol + 1;

	if (!skip_prefix(buffer, "tagger ", &buffer)) {
		/* early tags do not contain 'tagger' lines; warn only */
		ret = report(options, &tag->object, FSCK_MSG_MISSING_TAGGER_ENTRY, "invalid format - expected 'tagger' line");
		if (ret)
			goto done;
	}
	else
		ret = fsck_ident(&buffer, &tag->object, options);

done:
	strbuf_release(&sb);
	free(to_free);
	return ret;
}
コード例 #22
0
ファイル: fsck.c プロジェクト: PEPE-coin/git
static int fsck_commit_buffer(struct commit *commit, const char *buffer,
	unsigned long size, struct fsck_options *options)
{
	struct object_id tree_oid, oid;
	struct commit_graft *graft;
	unsigned parent_count, parent_line_count = 0, author_count;
	int err;
	const char *buffer_begin = buffer;
	const char *p;

	if (verify_headers(buffer, size, &commit->object, options))
		return -1;

	if (!skip_prefix(buffer, "tree ", &buffer))
		return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
	if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') {
		err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
		if (err)
			return err;
	}
	buffer = p + 1;
	while (skip_prefix(buffer, "parent ", &buffer)) {
		if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
			err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
			if (err)
				return err;
		}
		buffer = p + 1;
		parent_line_count++;
	}
	graft = lookup_commit_graft(&commit->object.oid);
	parent_count = commit_list_count(commit->parents);
	if (graft) {
		if (graft->nr_parent == -1 && !parent_count)
			; /* shallow commit */
		else if (graft->nr_parent != parent_count) {
			err = report(options, &commit->object, FSCK_MSG_MISSING_GRAFT, "graft objects missing");
			if (err)
				return err;
		}
	} else {
		if (parent_count != parent_line_count) {
			err = report(options, &commit->object, FSCK_MSG_MISSING_PARENT, "parent objects missing");
			if (err)
				return err;
		}
	}
	author_count = 0;
	while (skip_prefix(buffer, "author ", &buffer)) {
		author_count++;
		err = fsck_ident(&buffer, &commit->object, options);
		if (err)
			return err;
	}
	if (author_count < 1)
		err = report(options, &commit->object, FSCK_MSG_MISSING_AUTHOR, "invalid format - expected 'author' line");
	else if (author_count > 1)
		err = report(options, &commit->object, FSCK_MSG_MULTIPLE_AUTHORS, "invalid format - multiple 'author' lines");
	if (err)
		return err;
	if (!skip_prefix(buffer, "committer ", &buffer))
		return report(options, &commit->object, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line");
	err = fsck_ident(&buffer, &commit->object, options);
	if (err)
		return err;
	if (!get_commit_tree(commit)) {
		err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", oid_to_hex(&tree_oid));
		if (err)
			return err;
	}
	if (memchr(buffer_begin, '\0', size)) {
		err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT,
			     "NUL byte in the commit object body");
		if (err)
			return err;
	}
	return 0;
}