Exemplo n.º 1
0
Arquivo: push.c Projeto: dscho/git
static const char *map_refspec(const char *ref,
			       struct remote *remote, struct ref *local_refs)
{
	struct ref *matched = NULL;

	/* Does "ref" uniquely name our ref? */
	if (count_refspec_match(ref, local_refs, &matched) != 1)
		return ref;

	if (remote->push.nr) {
		struct refspec_item query;
		memset(&query, 0, sizeof(struct refspec_item));
		query.src = matched->name;
		if (!query_refspecs(&remote->push, &query) && query.dst) {
			struct strbuf buf = STRBUF_INIT;
			strbuf_addf(&buf, "%s%s:%s",
				    query.force ? "+" : "",
				    query.src, query.dst);
			return strbuf_detach(&buf, NULL);
		}
	}

	if (push_default == PUSH_DEFAULT_UPSTREAM &&
	    starts_with(matched->name, "refs/heads/")) {
		struct branch *branch = branch_get(matched->name + 11);
		if (branch->merge_nr == 1 && branch->merge[0]->src) {
			struct strbuf buf = STRBUF_INIT;
			strbuf_addf(&buf, "%s:%s",
				    ref, branch->merge[0]->src);
			return strbuf_detach(&buf, NULL);
		}
	}

	return ref;
}
Exemplo n.º 2
0
static int push_check(int argc, const char **argv, const char *prefix)
{
	struct remote *remote;

	if (argc < 2)
		die("submodule--helper push-check requires at least 1 argument");

	/*
	 * The remote must be configured.
	 * This is to avoid pushing to the exact same URL as the parent.
	 */
	remote = pushremote_get(argv[1]);
	if (!remote || remote->origin == REMOTE_UNCONFIGURED)
		die("remote '%s' not configured", argv[1]);

	/* Check the refspec */
	if (argc > 2) {
		int i, refspec_nr = argc - 2;
		struct ref *local_refs = get_local_heads();
		struct refspec *refspec = parse_push_refspec(refspec_nr,
							     argv + 2);

		for (i = 0; i < refspec_nr; i++) {
			struct refspec *rs = refspec + i;

			if (rs->pattern || rs->matching)
				continue;

			/*
			 * LHS must match a single ref
			 * NEEDSWORK: add logic to special case 'HEAD' once
			 * working with submodules in a detached head state
			 * ceases to be the norm.
			 */
			if (count_refspec_match(rs->src, local_refs, NULL) != 1)
				die("src refspec '%s' must name a ref",
				    rs->src);
		}
		free_refspec(refspec_nr, refspec);
	}

	return 0;
}
Exemplo n.º 3
0
Arquivo: remote.c Projeto: certik/git
static int match_explicit(struct ref *src, struct ref *dst,
			  struct ref ***dst_tail,
			  struct refspec *rs)
{
	struct ref *matched_src, *matched_dst;

	const char *dst_value = rs->dst;
	char *dst_guess;

	if (rs->pattern || rs->matching)
		return 0;

	matched_src = matched_dst = NULL;
	switch (count_refspec_match(rs->src, src, &matched_src)) {
	case 1:
		break;
	case 0:
		/* The source could be in the get_sha1() format
		 * not a reference name.  :refs/other is a
		 * way to delete 'other' ref at the remote end.
		 */
		matched_src = try_explicit_object_name(rs->src);
		if (!matched_src)
			return error("src refspec %s does not match any.", rs->src);
		break;
	default:
		return error("src refspec %s matches more than one.", rs->src);
	}

	if (!dst_value) {
		unsigned char sha1[20];
		int flag;

		dst_value = resolve_ref(matched_src->name, sha1, 1, &flag);
		if (!dst_value ||
		    ((flag & REF_ISSYMREF) &&
		     prefixcmp(dst_value, "refs/heads/")))
			die("%s cannot be resolved to branch.",
			    matched_src->name);
	}

	switch (count_refspec_match(dst_value, dst, &matched_dst)) {
	case 1:
		break;
	case 0:
		if (!memcmp(dst_value, "refs/", 5))
			matched_dst = make_linked_ref(dst_value, dst_tail);
		else if((dst_guess = guess_ref(dst_value, matched_src)))
			matched_dst = make_linked_ref(dst_guess, dst_tail);
		else
			error("unable to push to unqualified destination: %s\n"
			      "The destination refspec neither matches an "
			      "existing ref on the remote nor\n"
			      "begins with refs/, and we are unable to "
			      "guess a prefix based on the source ref.",
			      dst_value);
		break;
	default:
		matched_dst = NULL;
		error("dst refspec %s matches more than one.",
		      dst_value);
		break;
	}
	if (!matched_dst)
		return -1;
	if (matched_dst->peer_ref)
		return error("dst ref %s receives from more than one src.",
		      matched_dst->name);
	else {
		matched_dst->peer_ref = matched_src;
		matched_dst->force = rs->force;
	}
	return 0;
}