Example #1
0
static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_buf *buf)
{
	git_buf str = GIT_BUF_INIT;
	char oid[GIT_OID_HEXSZ +1] = {0};
	size_t len;

	/* Prefer multi_ack_detailed */
	if (caps->multi_ack_detailed)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK_DETAILED " ");
	else if (caps->multi_ack)
		git_buf_puts(&str, GIT_CAP_MULTI_ACK " ");

	/* Prefer side-band-64k if the server supports both */
	if (caps->side_band_64k)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND_64K);
	else if (caps->side_band)
		git_buf_printf(&str, "%s ", GIT_CAP_SIDE_BAND);

	if (caps->include_tag)
		git_buf_puts(&str, GIT_CAP_INCLUDE_TAG " ");

	if (caps->thin_pack)
		git_buf_puts(&str, GIT_CAP_THIN_PACK " ");

	if (caps->ofs_delta)
		git_buf_puts(&str, GIT_CAP_OFS_DELTA " ");

	if (git_buf_oom(&str))
		return -1;

	len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
		 git_buf_len(&str) + 1 /* LF */;

	if (len > 0xffff) {
		giterr_set(GITERR_NET,
			"tried to produce packet with invalid length %" PRIuZ, len);
		return -1;
	}

	git_buf_grow_by(buf, len);
	git_oid_fmt(oid, &head->oid);
	git_buf_printf(buf,
		"%04xwant %s %s\n", (unsigned int)len, oid, git_buf_cstr(&str));
	git_buf_dispose(&str);

	GITERR_CHECK_ALLOC_BUF(buf);

	return 0;
}
Example #2
0
static int push_glob(git_revwalk *walk, const char *glob, int hide)
{
	int error = 0;
	git_buf buf = GIT_BUF_INIT;
	git_reference *ref;
	git_reference_iterator *iter;
	size_t wildcard;

	assert(walk && glob);

	/* refs/ is implied if not given in the glob */
	if (git__prefixcmp(glob, GIT_REFS_DIR) != 0)
		git_buf_joinpath(&buf, GIT_REFS_DIR, glob);
	else
		git_buf_puts(&buf, glob);
	GITERR_CHECK_ALLOC_BUF(&buf);

	/* If no '?', '*' or '[' exist, we append '/ *' to the glob */
	wildcard = strcspn(glob, "?*[");
	if (!glob[wildcard])
		git_buf_put(&buf, "/*", 2);

	if ((error = git_reference_iterator_glob_new(&iter, walk->repo, buf.ptr)) < 0)
		goto out;

	while ((error = git_reference_next(&ref, iter)) == 0) {
		error = push_ref(walk, git_reference_name(ref), hide, true);
		git_reference_free(ref);
		if (error < 0)
			break;
	}
	git_reference_iterator_free(iter);

	if (error == GIT_ITEROVER)
		error = 0;
out:
	git_buf_free(&buf);
	return error;
}
Example #3
0
int git_refspec__dwim_one(git_vector *out, git_refspec *spec, git_vector *refs)
{
	git_buf buf = GIT_BUF_INIT;
	size_t j, pos;
	git_remote_head key;
	git_refspec *cur;

	const char* formatters[] = {
		GIT_REFS_DIR "%s",
		GIT_REFS_TAGS_DIR "%s",
		GIT_REFS_HEADS_DIR "%s",
		NULL
	};

	assert(out && spec && refs);

	cur = git__calloc(1, sizeof(git_refspec));
	GITERR_CHECK_ALLOC(cur);

	cur->force = spec->force;
	cur->push = spec->push;
	cur->pattern = spec->pattern;
	cur->matching = spec->matching;
	cur->string = git__strdup(spec->string);

	/* shorthand on the lhs */
	if (git__prefixcmp(spec->src, GIT_REFS_DIR)) {
		for (j = 0; formatters[j]; j++) {
			git_buf_clear(&buf);
			git_buf_printf(&buf, formatters[j], spec->src);
			GITERR_CHECK_ALLOC_BUF(&buf);

			key.name = (char *) git_buf_cstr(&buf);
			if (!git_vector_search(&pos, refs, &key)) {
				/* we found something to match the shorthand, set src to that */
				cur->src = git_buf_detach(&buf);
			}
		}
	}

	/* No shorthands found, copy over the name */
	if (cur->src == NULL && spec->src != NULL) {
		cur->src = git__strdup(spec->src);
		GITERR_CHECK_ALLOC(cur->src);
	}

	if (spec->dst && git__prefixcmp(spec->dst, GIT_REFS_DIR)) {
		/* if it starts with "remotes" then we just prepend "refs/" */
		if (!git__prefixcmp(spec->dst, "remotes/")) {
			git_buf_puts(&buf, GIT_REFS_DIR);
		} else {
			git_buf_puts(&buf, GIT_REFS_HEADS_DIR);
		}

		git_buf_puts(&buf, spec->dst);
		GITERR_CHECK_ALLOC_BUF(&buf);

		cur->dst = git_buf_detach(&buf);
	}

	git_buf_dispose(&buf);

	if (cur->dst == NULL && spec->dst != NULL) {
		cur->dst = git__strdup(spec->dst);
		GITERR_CHECK_ALLOC(cur->dst);
	}

	return git_vector_insert(out, cur);
}
Example #4
0
int git_path_resolve_relative(git_buf *path, size_t ceiling)
{
	char *base, *to, *from, *next;
	size_t len;

	GITERR_CHECK_ALLOC_BUF(path);

	if (ceiling > path->size)
		ceiling = path->size;

	/* recognize drive prefixes, etc. that should not be backed over */
	if (ceiling == 0)
		ceiling = git_path_root(path->ptr) + 1;

	/* recognize URL prefixes that should not be backed over */
	if (ceiling == 0) {
		for (next = path->ptr; *next && git__isalpha(*next); ++next);
		if (next[0] == ':' && next[1] == '/' && next[2] == '/')
			ceiling = (next + 3) - path->ptr;
	}

	base = to = from = path->ptr + ceiling;

	while (*from) {
		for (next = from; *next && *next != '/'; ++next);

		len = next - from;

		if (len == 1 && from[0] == '.')
			/* do nothing with singleton dot */;

		else if (len == 2 && from[0] == '.' && from[1] == '.') {
			/* error out if trying to up one from a hard base */
			if (to == base && ceiling != 0) {
				giterr_set(GITERR_INVALID,
					"Cannot strip root component off url");
				return -1;
			}

			/* no more path segments to strip,
			 * use '../' as a new base path */
			if (to == base) {
				if (*next == '/')
					len++;

				if (to != from)
					memmove(to, from, len);

				to += len;
				/* this is now the base, can't back up from a
				 * relative prefix */
				base = to;
			} else {
				/* back up a path segment */
				while (to > base && to[-1] == '/') to--;
				while (to > base && to[-1] != '/') to--;
			}
		} else {
			if (*next == '/' && *from != '/')
				len++;

			if (to != from)
				memmove(to, from, len);

			to += len;
		}

		from += len;

		while (*from == '/') from++;
	}

	*to = '\0';

	path->size = to - path->ptr;

	return 0;
}