git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: git@vger.kernel.org
Subject: [PATCH] git-push: allow globbing wildcard refspec.
Date: Mon, 05 Feb 2007 23:48:09 -0800	[thread overview]
Message-ID: <7vtzxziv5y.fsf_-_@assigned-by-dhcp.cox.net> (raw)
In-Reply-To: <7v3b5jka3t.fsf_-_@assigned-by-dhcp.cox.net> (Junio C. Hamano's message of "Mon, 05 Feb 2007 23:40:06 -0800")

This allows you to set up mothership-satellite configuration
more symmetrically and naturally by allowing the globbing
wildcard refspec for git-push.  On your satellite machine:

    [remote "mothership"]
        url = mothership:project.git
        pull = refs/heads/*:refs/remotes/mothership/*
        push = refs/heads/*:refs/remotes/satellite/*

You would say "git fetch mothership" to update your tracking
branches under mothership/ to keep track of the progress on the
mothership side, and when you are done working on the satellite
machine, you would "git push mothership" to update their
tracking branches under satellite/.  Corresponding configuration
on the mothership machine can be used to make "git fetch satellite"
update its tracking branch under satellite/. on the mothership.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 builtin-push.c |  114 ++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 82 insertions(+), 32 deletions(-)

diff --git a/builtin-push.c b/builtin-push.c
index 5f4d7d3..c45649e 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -54,38 +54,84 @@ static void expand_refspecs(void)
 	for_each_ref(expand_one_ref, NULL);
 }
 
+struct wildcard_cb {
+	const char *from_prefix;
+	int from_prefix_len;
+	const char *to_prefix;
+	int to_prefix_len;
+	int force;
+};
+
+static int expand_wildcard_ref(const char *ref, const unsigned char *sha1, int flag, void *cb_data)
+{
+	struct wildcard_cb *cb = cb_data;
+	int len = strlen(ref);
+	char *expanded, *newref;
+
+	if (len < cb->from_prefix_len ||
+	    memcmp(cb->from_prefix, ref, cb->from_prefix_len))
+		return 0;
+	expanded = xmalloc(len * 2 + cb->force +
+			   (cb->to_prefix_len - cb->from_prefix_len) + 2);
+	newref = expanded + cb->force;
+	if (cb->force)
+		expanded[0] = '+';
+	memcpy(newref, ref, len);
+	newref[len] = ':';
+	memcpy(newref + len + 1, cb->to_prefix, cb->to_prefix_len);
+	strcpy(newref + len + 1 + cb->to_prefix_len,
+	       ref + cb->from_prefix_len);
+	add_refspec(expanded);
+	return 0;
+}
+
+static int wildcard_ref(const char *ref)
+{
+	int len;
+	const char *colon;
+	struct wildcard_cb cb;
+
+	memset(&cb, 0, sizeof(cb));
+	if (ref[0] == '+') {
+		cb.force = 1;
+		ref++;
+	}
+	len = strlen(ref);
+	colon = strchr(ref, ':');
+	if (! (colon && ref < colon &&
+	       colon[-2] == '/' && colon[-1] == '*' &&
+	       /* "<mine>/<asterisk>:<yours>/<asterisk>" is at least 7 bytes */
+	       7 <= len &&
+	       ref[len-2] == '/' && ref[len-1] == '*') )
+		return 0 ;
+	cb.from_prefix = ref;
+	cb.from_prefix_len = colon - ref - 1;
+	cb.to_prefix = colon + 1;
+	cb.to_prefix_len = len - (colon - ref) - 2;
+	for_each_ref(expand_wildcard_ref, &cb);
+	return 1;
+}
+
 static void set_refspecs(const char **refs, int nr)
 {
 	if (nr) {
-		int pass;
-		for (pass = 0; pass < 2; pass++) {
-			/* pass 0 counts and allocates, pass 1 fills */
-			int i, cnt;
-			for (i = cnt = 0; i < nr; i++) {
-				if (!strcmp("tag", refs[i])) {
-					int len;
-					char *tag;
-					if (nr <= ++i)
-						die("tag <tag> shorthand without <tag>");
-					if (pass) {
-						len = strlen(refs[i]) + 11;
-						tag = xmalloc(len);
-						strcpy(tag, "refs/tags/");
-						strcat(tag, refs[i]);
-						refspec[cnt] = tag;
-					}
-					cnt++;
-					continue;
-				}
-				if (pass)
-					refspec[cnt] = refs[i];
-				cnt++;
-			}
-			if (!pass) {
-				size_t bytes = cnt * sizeof(char *);
-				refspec_nr = cnt;
-				refspec = xrealloc(refspec, bytes);
+		int i;
+		for (i = 0; i < nr; i++) {
+			const char *ref = refs[i];
+			if (!strcmp("tag", ref)) {
+				char *tag;
+				int len;
+				if (nr <= ++i)
+					die("tag shorthand without <tag>");
+				len = strlen(refs[i]) + 11;
+				tag = xmalloc(len);
+				strcpy(tag, "refs/tags/");
+				strcat(tag, refs[i]);
+				ref = tag;
 			}
+			else if (wildcard_ref(ref))
+				continue;
+			add_refspec(ref);
 		}
 	}
 	expand_refspecs();
@@ -129,8 +175,10 @@ static int get_remotes_uri(const char *repo, const char *uri[MAX_URI])
 			else
 				error("more than %d URL's specified, ignoring the rest", MAX_URI);
 		}
-		else if (is_refspec && !has_explicit_refspec)
-			add_refspec(xstrdup(s));
+		else if (is_refspec && !has_explicit_refspec) {
+			if (!wildcard_ref(s))
+				add_refspec(xstrdup(s));
+		}
 	}
 	fclose(f);
 	if (!n)
@@ -156,8 +204,10 @@ static int get_remote_config(const char* key, const char* value)
 				error("more than %d URL's specified, ignoring the rest", MAX_URI);
 		}
 		else if (config_get_refspecs &&
-			 !strcmp(key + 7 + config_repo_len, ".push"))
-			add_refspec(xstrdup(value));
+			 !strcmp(key + 7 + config_repo_len, ".push")) {
+			if (!wildcard_ref(value))
+				add_refspec(xstrdup(value));
+		}
 		else if (config_get_receivepack &&
 			 !strcmp(key + 7 + config_repo_len, ".receivepack")) {
 			if (!receivepack) {
-- 
1.5.0.rc3.83.g88293c-dirty

  reply	other threads:[~2007-02-06  7:48 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-02-01  0:26 [ANNOUNCE] GIT 1.5.0-rc3 Junio C Hamano
2007-02-01 16:51 ` Bill Lear
2007-02-01 20:34 ` Robin Rosenberg
2007-02-04  9:36 ` What's in git.git (stable) Junio C Hamano
2007-02-04 18:51   ` Jeff King
2007-02-04 19:12     ` Linus Torvalds
2007-02-04 20:58       ` Theodore Tso
2007-02-04 21:34         ` Jakub Narebski
2007-02-04 22:25           ` David Kågedal
2007-02-05  3:00         ` [PATCH 1/2] Rename get_ident() to fmt_ident() and make it available to outside Junio C Hamano
2007-02-05  3:00         ` [PATCH 2/2] git-blame: no rev means start from the working tree file Junio C Hamano
2007-02-06  7:40   ` Quick status updates Junio C Hamano
2007-02-06  7:48     ` Junio C Hamano [this message]
2007-02-06  7:53       ` [PATCH] git-push: allow globbing wildcard refspec Shawn O. Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vtzxziv5y.fsf_-_@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).