[PATCH] push: Learn to set up branch tracking with '--track'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When pushing a branch to a remote repository that the remote side did
not know beforehand, it is often handy to set up the branch tracking
such that

	$ git checkout xyz
	$ git push --track origin xyz:abc
	$ git pull

will pull the branch 'abc' from the remote 'origin' into the branch
'xyz'.

Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx>
---

	This is a companion patch to the one I sent earlier:

	http://article.gmane.org/gmane.comp.version-control.git/13735

 Documentation/git-push.txt |    7 ++++++-
 builtin-push.c             |   42 ++++++++++++++++++++++++++++++++++++++++++
 t/t5516-fetch-push.sh      |   11 +++++++++++
 3 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 7d1eced..fa1d54c 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git push' [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>]
-	   [--repo=<repository>] [-f | --force] [-v | --verbose]
+	   [--repo=<repository>] [-f | --force] [-v | --verbose] [-t | --track]
 	   [<repository> <refspec>...]
 
 DESCRIPTION
@@ -126,6 +126,11 @@ useful if you write an alias or script around 'git-push'.
 	transfer spends extra cycles to minimize the number of
 	objects to be sent and meant to be used on slower connection.
 
+-t::
+--track::
+	Set up tracking information for the pushed branches, so that
+	'git pull' will remember the indicated mapping.
+
 -v::
 --verbose::
 	Run verbosely.
diff --git a/builtin-push.c b/builtin-push.c
index 122fdcf..9fd445d 100644
--- a/builtin-push.c
+++ b/builtin-push.c
@@ -16,6 +16,7 @@ static const char * const push_usage[] = {
 
 static int thin;
 static const char *receivepack;
+static int track;
 
 static const char **refspec;
 static int refspec_nr;
@@ -48,6 +49,41 @@ static void set_refspecs(const char **refs, int nr)
 	}
 }
 
+static void setup_tracking(const char *url)
+{
+	struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT;
+	int i;
+
+	for (i = 0; i < refspec_nr; i++) {
+		const char *branch = refspec[i], *colon;
+
+		/* skip non-branches */
+		if (!prefixcmp("refs/", branch)) {
+			if (prefixcmp("refs/heads/", branch))
+				continue;
+			branch += strlen("refs/heads/");
+		}
+		colon = strchrnul(branch, ':');
+
+		strbuf_reset(&buf);
+		strbuf_addf(&buf, "branch.%.*s.remote",
+				(int)(colon - branch), branch);
+		git_config_set(buf.buf, url);
+
+		strbuf_reset(&buf);
+		strbuf_addf(&buf, "branch.%.*s.merge",
+				(int)(colon - branch), branch);
+		strbuf_reset(&buf2);
+		strbuf_addf(&buf2, "%s%s",
+			*colon && !prefixcmp("refs/heads/", colon + 1) ?
+			"" : "refs/heads/",
+			*colon ? colon + 1 : branch);
+		git_config_set(buf.buf, buf2.buf);
+	}
+	strbuf_release(&buf);
+	strbuf_release(&buf2);
+}
+
 static int do_push(const char *repo, int flags)
 {
 	int i, errs;
@@ -96,6 +132,8 @@ static int do_push(const char *repo, int flags)
 		if (flags & TRANSPORT_PUSH_VERBOSE)
 			fprintf(stderr, "Pushing to %s\n", remote->url[i]);
 		err = transport_push(transport, refspec_nr, refspec, flags);
+		if (!err && track)
+			setup_tracking(transport->url);
 		err |= transport_disconnect(transport);
 
 		if (!err)
@@ -126,11 +164,15 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		OPT_BOOLEAN( 0 , "thin", &thin, "use thin pack"),
 		OPT_STRING( 0 , "receive-pack", &receivepack, "receive-pack", "receive pack program"),
 		OPT_STRING( 0 , "exec", &receivepack, "receive-pack", "receive pack program"),
+		OPT_BOOLEAN('t', "track", &track, "set up branch tracking information"),
 		OPT_END()
 	};
 
 	argc = parse_options(argc, argv, options, push_usage, 0);
 
+	if (track && !tags && !argc)
+		die ("Need explicit arguments for branch tracking");
+
 	if (tags)
 		add_refspec("refs/tags/*");
 
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 4426df9..e18b2f6 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -573,4 +573,15 @@ test_expect_success 'push with branches containing #' '
 	git checkout master
 '
 
+test_expect_success 'push --track' '
+
+	git push --track testrepo master &&
+	test ! -z "$(git ls-remote testrepo master)" &&
+	test "testrepo" = $(git config branch.master.remote) &&
+	test "refs/heads/master" = $(git config branch.master.merge) &&
+	git push --track testrepo master:test &&
+	test "refs/heads/test" = $(git config branch.master.merge)
+
+'
+
 test_done
-- 
1.6.1.1.506.gdbe181
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux