Exemple #1
0
int ref_transaction_update(struct ref_transaction *transaction,
			   const char *refname,
			   const unsigned char *new_sha1,
			   const unsigned char *old_sha1,
			   unsigned int flags, const char *msg,
			   struct strbuf *err)
{
	assert(err);

	if ((new_sha1 && !is_null_sha1(new_sha1)) ?
	    check_refname_format(refname, REFNAME_ALLOW_ONELEVEL) :
	    !refname_is_safe(refname)) {
		strbuf_addf(err, "refusing to update ref with bad name '%s'",
			    refname);
		return -1;
	}

	flags |= (new_sha1 ? REF_HAVE_NEW : 0) | (old_sha1 ? REF_HAVE_OLD : 0);

	ref_transaction_add_update(transaction, refname, flags,
				   new_sha1, old_sha1, msg);
	return 0;
}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
/* This function needs to return a meaningful errno on failure */
static const char *resolve_ref_recursively(struct ref_store *refs,
					   const char *refname,
					   int resolve_flags,
					   unsigned char *sha1, int *flags)
{
	static struct strbuf sb_refname = STRBUF_INIT;
	int unused_flags;
	int symref_count;

	if (!flags)
		flags = &unused_flags;

	*flags = 0;

	if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
		if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
		    !refname_is_safe(refname)) {
			errno = EINVAL;
			return NULL;
		}

		/*
		 * dwim_ref() uses REF_ISBROKEN to distinguish between
		 * missing refs and refs that were present but invalid,
		 * to complain about the latter to stderr.
		 *
		 * We don't know whether the ref exists, so don't set
		 * REF_ISBROKEN yet.
		 */
		*flags |= REF_BAD_NAME;
	}

	for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) {
		unsigned int read_flags = 0;

		if (refs->be->read_raw_ref(refs, refname,
					   sha1, &sb_refname, &read_flags)) {
			*flags |= read_flags;
			if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING))
				return NULL;
			hashclr(sha1);
			if (*flags & REF_BAD_NAME)
				*flags |= REF_ISBROKEN;
			return refname;
		}

		*flags |= read_flags;

		if (!(read_flags & REF_ISSYMREF)) {
			if (*flags & REF_BAD_NAME) {
				hashclr(sha1);
				*flags |= REF_ISBROKEN;
			}
			return refname;
		}

		refname = sb_refname.buf;
		if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
			hashclr(sha1);
			return refname;
		}
		if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
			if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
			    !refname_is_safe(refname)) {
				errno = EINVAL;
				return NULL;
			}

			*flags |= REF_ISBROKEN | REF_BAD_NAME;
		}
	}

	errno = ELOOP;
	return NULL;
}