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