{"thread":{"id":"23818","subject":"Re: git remote add should be able to extend remotes","startedAt":"2010-05-16T00:45:38Z","lastAt":"2010-05-19T18:38:50Z","messageCount":2,"participants":["Jonathan Nieder"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"141752","messageId":"20100516004538.GA5528@progeny.tock","threadId":"23818","inReplyTo":"20070710133226.GA23751@piper.oerlikon.madduck.net","subject":"Re: git remote add should be able to extend remotes","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-05-16T00:45:38Z","receivedAt":"2010-05-16T00:45:38Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"reassign 432557 git git/1:1.5.2.3-1\nfound 432557 git/1:1.7.1-1\ntags 432557 + upstream\nquit\n\nHi Martin,\n\nSorry for the long silence.\n\nmartin f krafft wrote:\n\n> piper:/tmp/cdt.xBt19067/host1> git remote add -t A -t B base ../base\n> piper:/tmp/cdt.xBt19067/host1> git remote add -t C base ../base\n> remote base already exists.\n> \n> It would be nice if I could add branches to be tracked in a given\n> remote, ideally without having to specify the path:\n> \n>   git remote add -t C base\n\nYes, this seems like useful functionality.\n\nIt would be handy to be able to remove branches, too.  I have not\nreally wrapped my head around the set-* subcommands, but how about\nsomething like this?\n\n  git remote set-branches base --add C\n  git remote set-branches base A B D\n  git remote set-branches base --delete D; # not implemented\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-remote.txt |   13 +++++\n builtin/remote.c             |  102 +++++++++++++++++++++++++++++++++++++-----\n t/t5505-remote.sh            |   88 ++++++++++++++++++++++++++++++++++++\n 3 files changed, 192 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex 3fc599c..de4386b 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -14,6 +14,7 @@ SYNOPSIS\n 'git remote rename' <old> <new>\n 'git remote rm' <name>\n 'git remote set-head' <name> (-a | -d | <branch>)\n+'git remote set-branches' <name> [--add] <branch>...\n 'git remote set-url' [--push] <name> <newurl> [<oldurl>]\n 'git remote set-url --add' [--push] <name> <newurl>\n 'git remote set-url --delete' [--push] <name> <url>\n@@ -104,6 +105,18 @@ remote set-head origin master\" will set `$GIT_DIR/refs/remotes/origin/HEAD` to\n `refs/remotes/origin/master` already exists; if not it must be fetched first.\n +\n \n+'set-branches'::\n+\n+Changes the list of branches tracked by the named remote.\n+This can be used to track a subset of the available remote branches\n+after the initial setup for a remote.\n++\n+The named branches will be interpreted as if specified with the\n+`-t` option on the 'git remote add' command line.\n++\n+With `--add`, instead of replacing the list of currently tracked\n+branches, adds to that list.\n+\n 'set-url'::\n \n Changes URL remote points to. Sets first URL remote points to matching\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex c13e2dd..7de1614 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -16,6 +16,7 @@ static const char * const builtin_remote_usage[] = {\n \t\"git remote [-v | --verbose] show [-n] <name>\",\n \t\"git remote prune [-n | --dry-run] <name>\",\n \t\"git remote [-v | --verbose] update [-p | --prune] [group | remote]\",\n+\t\"git remote set-branches <name> [--add] <branch>...\",\n \t\"git remote set-url <name> <newurl> [<oldurl>]\",\n \t\"git remote set-url --add <name> <newurl>\",\n \t\"git remote set-url --delete <name> <url>\",\n@@ -42,6 +43,12 @@ static const char * const builtin_remote_sethead_usage[] = {\n \tNULL\n };\n \n+static const char * const builtin_remote_setbranches_usage[] = {\n+\t\"git remote set-branches <name> <branch>...\",\n+\t\"git remote set-branches --add <name> <branch>...\",\n+\tNULL\n+};\n+\n static const char * const builtin_remote_show_usage[] = {\n \t\"git remote show [<options>] <name>\",\n \tNULL\n@@ -104,6 +111,20 @@ static int fetch_remote(const char *name)\n \treturn 0;\n }\n \n+static int add_branch(const char *key, const char *branchname,\n+\t\tconst char *remotename, int mirror, struct strbuf *tmp)\n+{\n+\tstrbuf_reset(tmp);\n+\tstrbuf_addch(tmp, '+');\n+\tif (mirror)\n+\t\tstrbuf_addf(tmp, \"refs/%s:refs/%s\",\n+\t\t\t\tbranchname, branchname);\n+\telse\n+\t\tstrbuf_addf(tmp, \"refs/heads/%s:refs/remotes/%s/%s\",\n+\t\t\t\tbranchname, remotename, branchname);\n+\treturn git_config_set_multivar(key, tmp->buf, \"^$\", 0);\n+}\n+\n static int add(int argc, const char **argv)\n {\n \tint fetch = 0, mirror = 0;\n@@ -151,17 +172,8 @@ static int add(int argc, const char **argv)\n \tif (track.nr == 0)\n \t\tstring_list_append(\"*\", &track);\n \tfor (i = 0; i < track.nr; i++) {\n-\t\tstruct string_list_item *item = track.items + i;\n-\n-\t\tstrbuf_reset(&buf2);\n-\t\tstrbuf_addch(&buf2, '+');\n-\t\tif (mirror)\n-\t\t\tstrbuf_addf(&buf2, \"refs/%s:refs/%s\",\n-\t\t\t\t\titem->string, item->string);\n-\t\telse\n-\t\t\tstrbuf_addf(&buf2, \"refs/heads/%s:refs/remotes/%s/%s\",\n-\t\t\t\t\titem->string, name, item->string);\n-\t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n+\t\tif (add_branch(buf.buf, track.items[i].string,\n+\t\t\t\tname, mirror, &buf2))\n \t\t\treturn 1;\n \t}\n \n@@ -1265,6 +1277,72 @@ static int update(int argc, const char **argv)\n \treturn run_command_v_opt(fetch_argv, RUN_GIT_CMD);\n }\n \n+static int remove_all_fetch_refspecs(const char *remote, const char *key)\n+{\n+\treturn git_config_set_multivar(key, NULL, NULL, 1);\n+}\n+\n+static int add_branches(struct remote *remote, const char **branches,\n+\t\t\tconst char *key)\n+{\n+\tconst char *remotename = remote->name;\n+\tint mirror = remote->mirror;\n+\tstruct strbuf refspec = STRBUF_INIT;\n+\n+\tfor (; *branches; branches++)\n+\t\tif (add_branch(key, *branches, remotename, mirror, &refspec)) {\n+\t\t\tstrbuf_release(&refspec);\n+\t\t\treturn 1;\n+\t\t}\n+\n+\tstrbuf_release(&refspec);\n+\treturn 0;\n+}\n+\n+static int set_remote_branches(const char *remotename, const char **branches,\n+\t\t\t\tint add_mode)\n+{\n+\tstruct strbuf key = STRBUF_INIT;\n+\tstruct remote *remote;\n+\n+\tstrbuf_addf(&key, \"remote.%s.fetch\", remotename);\n+\n+\tif (!remote_is_configured(remotename))\n+\t\tdie(\"No such remote '%s'\", remotename);\n+\tremote = remote_get(remotename);\n+\n+\tif (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) {\n+\t\tstrbuf_release(&key);\n+\t\treturn 1;\n+\t}\n+\tif (add_branches(remote, branches, key.buf)) {\n+\t\tstrbuf_release(&key);\n+\t\treturn 1;\n+\t}\n+\n+\tstrbuf_release(&key);\n+\treturn 0;\n+}\n+\n+static int set_branches(int argc, const char **argv)\n+{\n+\tint add_mode = 0;\n+\tstruct option options[] = {\n+\t\tOPT_BOOLEAN('\\0', \"add\", &add_mode, \"add branch\"),\n+\t\tOPT_END()\n+\t};\n+\n+\targc = parse_options(argc, argv, NULL, options,\n+\t\t\t     builtin_remote_setbranches_usage, 0);\n+\tif (argc == 0) {\n+\t\terror(\"no remote specified\");\n+\t\tusage_with_options(builtin_remote_seturl_usage, options);\n+\t}\n+\targv[argc] = NULL;\n+\n+\treturn set_remote_branches(argv[0], argv + 1, add_mode);\n+}\n+\n static int set_url(int argc, const char **argv)\n {\n \tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n@@ -1430,6 +1508,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)\n \t\tresult = rm(argc, argv);\n \telse if (!strcmp(argv[0], \"set-head\"))\n \t\tresult = set_head(argc, argv);\n+\telse if (!strcmp(argv[0], \"set-branches\"))\n+\t\tresult = set_branches(argc, argv);\n \telse if (!strcmp(argv[0], \"set-url\"))\n \t\tresult = set_url(argc, argv);\n \telse if (!strcmp(argv[0], \"show\"))\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 230c0cd..8aaf53e 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -534,6 +534,94 @@ test_expect_success 'show empty remote' '\n \t)\n '\n \n+test_expect_success 'remote set-branches requires a remote' '\n+\ttest_must_fail git remote set-branches &&\n+\ttest_must_fail git remote set-branches --add\n+'\n+\n+test_expect_success 'remote set-branches' '\n+\techo \"+refs/heads/*:refs/remotes/scratch/*\" >expect.initial &&\n+\tsort <<-\\EOF >expect.add &&\n+\t+refs/heads/*:refs/remotes/scratch/*\n+\t+refs/heads/other:refs/remotes/scratch/other\n+\tEOF\n+\tsort <<-\\EOF >expect.replace &&\n+\t+refs/heads/maint:refs/remotes/scratch/maint\n+\t+refs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\tEOF\n+\tsort <<-\\EOF >expect.add-two &&\n+\t+refs/heads/maint:refs/remotes/scratch/maint\n+\t+refs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\t+refs/heads/pu:refs/remotes/scratch/pu\n+\t+refs/heads/t/topic:refs/remotes/scratch/t/topic\n+\tEOF\n+\tsort <<-\\EOF >expect.setup-ffonly &&\n+\trefs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\tEOF\n+\tsort <<-\\EOF >expect.respect-ffonly &&\n+\trefs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\t+refs/heads/pu:refs/remotes/scratch/pu\n+\tEOF\n+\n+\tgit clone .git/ setbranches &&\n+\t(\n+\t\tcd setbranches &&\n+\t\tgit remote rename origin scratch &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.initial &&\n+\n+\t\tgit remote set-branches scratch --add other &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.add &&\n+\n+\t\tgit remote set-branches scratch maint master next &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.replace &&\n+\n+\t\tgit remote set-branches --add scratch pu t/topic &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.add-two &&\n+\n+\t\tgit config --unset-all remote.scratch.fetch &&\n+\t\tgit config remote.scratch.fetch \\\n+\t\t\trefs/heads/master:refs/remotes/scratch/master &&\n+\t\tgit config --add remote.scratch.fetch \\\n+\t\t\t+refs/heads/next:refs/remotes/scratch/next &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.setup-ffonly &&\n+\n+\t\tgit remote set-branches --add scratch pu &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.respect-ffonly\n+\t) &&\n+\ttest_cmp expect.initial actual.initial &&\n+\ttest_cmp expect.add actual.add &&\n+\ttest_cmp expect.replace actual.replace &&\n+\ttest_cmp expect.add-two actual.add-two &&\n+\ttest_cmp expect.setup-ffonly actual.setup-ffonly &&\n+\ttest_cmp expect.respect-ffonly actual.respect-ffonly\n+'\n+\n+test_expect_success 'remote set-branches with --mirror' '\n+\techo \"+refs/*:refs/*\" >expect.initial &&\n+\techo \"+refs/heads/master:refs/heads/master\" >expect.replace &&\n+\tgit clone --mirror .git/ setbranches-mirror &&\n+\t(\n+\t\tcd setbranches-mirror &&\n+\t\tgit remote rename origin scratch &&\n+\t\tgit config --get-all remote.scratch.fetch >../actual.initial &&\n+\n+\t\tgit remote set-branches scratch heads/master &&\n+\t\tgit config --get-all remote.scratch.fetch >../actual.replace\n+\t) &&\n+\ttest_cmp expect.initial actual.initial &&\n+\ttest_cmp expect.replace actual.replace\n+'\n+\n test_expect_success 'new remote' '\n \tgit remote add someremote foo &&\n \techo foo >expect &&\n-- \n1.7.1\n"},{"id":"141917","messageId":"20100519183850.GA18623@progeny.tock","threadId":"23818","inReplyTo":"20100516004538.GA5528@progeny.tock","subject":"[PATCH] Add git remote set-branches","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-05-19T18:38:50Z","receivedAt":"2010-05-19T18:38:50Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Add ‘git remote set-branches’ for changing the list of tracked refs\nfor a remote repository with one \"porcelain-level\" command.  This\ncomplements the longstanding ‘git remote add --track’ option.\n\nThe interface is based on the ‘git remote set-url’ subcommand.\n\n   git remote set-branches base --add C\n   git remote set-branches base A B D\n   git remote set-branches base --delete D; # not implemented\n\nSuggested-by: martin f. krafft <madduck@debian.org>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nJunio C Hamano wrote:\n\n> This, and the other patch, look Ok except these unsightly debbugs cruft in\n> the commit log message.  Could you redo them please?\n\nSorry about that.  Hoping someone would take inspiration from my rough\nsketch and finish it off, I didn’t even bother to consider whether it\nmight be usable as-is.\n\n Documentation/git-remote.txt |   13 +++++\n builtin/remote.c             |  102 +++++++++++++++++++++++++++++++++++++-----\n t/t5505-remote.sh            |   88 ++++++++++++++++++++++++++++++++++++\n 3 files changed, 192 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex 3fc599c..de4386b 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -14,6 +14,7 @@ SYNOPSIS\n 'git remote rename' <old> <new>\n 'git remote rm' <name>\n 'git remote set-head' <name> (-a | -d | <branch>)\n+'git remote set-branches' <name> [--add] <branch>...\n 'git remote set-url' [--push] <name> <newurl> [<oldurl>]\n 'git remote set-url --add' [--push] <name> <newurl>\n 'git remote set-url --delete' [--push] <name> <url>\n@@ -104,6 +105,18 @@ remote set-head origin master\" will set `$GIT_DIR/refs/remotes/origin/HEAD` to\n `refs/remotes/origin/master` already exists; if not it must be fetched first.\n +\n \n+'set-branches'::\n+\n+Changes the list of branches tracked by the named remote.\n+This can be used to track a subset of the available remote branches\n+after the initial setup for a remote.\n++\n+The named branches will be interpreted as if specified with the\n+`-t` option on the 'git remote add' command line.\n++\n+With `--add`, instead of replacing the list of currently tracked\n+branches, adds to that list.\n+\n 'set-url'::\n \n Changes URL remote points to. Sets first URL remote points to matching\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 277765b..c4d17b5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -16,6 +16,7 @@ static const char * const builtin_remote_usage[] = {\n \t\"git remote [-v | --verbose] show [-n] <name>\",\n \t\"git remote prune [-n | --dry-run] <name>\",\n \t\"git remote [-v | --verbose] update [-p | --prune] [group | remote]\",\n+\t\"git remote set-branches <name> [--add] <branch>...\",\n \t\"git remote set-url <name> <newurl> [<oldurl>]\",\n \t\"git remote set-url --add <name> <newurl>\",\n \t\"git remote set-url --delete <name> <url>\",\n@@ -42,6 +43,12 @@ static const char * const builtin_remote_sethead_usage[] = {\n \tNULL\n };\n \n+static const char * const builtin_remote_setbranches_usage[] = {\n+\t\"git remote set-branches <name> <branch>...\",\n+\t\"git remote set-branches --add <name> <branch>...\",\n+\tNULL\n+};\n+\n static const char * const builtin_remote_show_usage[] = {\n \t\"git remote show [<options>] <name>\",\n \tNULL\n@@ -104,6 +111,20 @@ static int fetch_remote(const char *name)\n \treturn 0;\n }\n \n+static int add_branch(const char *key, const char *branchname,\n+\t\tconst char *remotename, int mirror, struct strbuf *tmp)\n+{\n+\tstrbuf_reset(tmp);\n+\tstrbuf_addch(tmp, '+');\n+\tif (mirror)\n+\t\tstrbuf_addf(tmp, \"refs/%s:refs/%s\",\n+\t\t\t\tbranchname, branchname);\n+\telse\n+\t\tstrbuf_addf(tmp, \"refs/heads/%s:refs/remotes/%s/%s\",\n+\t\t\t\tbranchname, remotename, branchname);\n+\treturn git_config_set_multivar(key, tmp->buf, \"^$\", 0);\n+}\n+\n static int add(int argc, const char **argv)\n {\n \tint fetch = 0, mirror = 0;\n@@ -151,17 +172,8 @@ static int add(int argc, const char **argv)\n \tif (track.nr == 0)\n \t\tstring_list_append(\"*\", &track);\n \tfor (i = 0; i < track.nr; i++) {\n-\t\tstruct string_list_item *item = track.items + i;\n-\n-\t\tstrbuf_reset(&buf2);\n-\t\tstrbuf_addch(&buf2, '+');\n-\t\tif (mirror)\n-\t\t\tstrbuf_addf(&buf2, \"refs/%s:refs/%s\",\n-\t\t\t\t\titem->string, item->string);\n-\t\telse\n-\t\t\tstrbuf_addf(&buf2, \"refs/heads/%s:refs/remotes/%s/%s\",\n-\t\t\t\t\titem->string, name, item->string);\n-\t\tif (git_config_set_multivar(buf.buf, buf2.buf, \"^$\", 0))\n+\t\tif (add_branch(buf.buf, track.items[i].string,\n+\t\t\t\tname, mirror, &buf2))\n \t\t\treturn 1;\n \t}\n \n@@ -1265,6 +1277,72 @@ static int update(int argc, const char **argv)\n \treturn run_command_v_opt(fetch_argv, RUN_GIT_CMD);\n }\n \n+static int remove_all_fetch_refspecs(const char *remote, const char *key)\n+{\n+\treturn git_config_set_multivar(key, NULL, NULL, 1);\n+}\n+\n+static int add_branches(struct remote *remote, const char **branches,\n+\t\t\tconst char *key)\n+{\n+\tconst char *remotename = remote->name;\n+\tint mirror = remote->mirror;\n+\tstruct strbuf refspec = STRBUF_INIT;\n+\n+\tfor (; *branches; branches++)\n+\t\tif (add_branch(key, *branches, remotename, mirror, &refspec)) {\n+\t\t\tstrbuf_release(&refspec);\n+\t\t\treturn 1;\n+\t\t}\n+\n+\tstrbuf_release(&refspec);\n+\treturn 0;\n+}\n+\n+static int set_remote_branches(const char *remotename, const char **branches,\n+\t\t\t\tint add_mode)\n+{\n+\tstruct strbuf key = STRBUF_INIT;\n+\tstruct remote *remote;\n+\n+\tstrbuf_addf(&key, \"remote.%s.fetch\", remotename);\n+\n+\tif (!remote_is_configured(remotename))\n+\t\tdie(\"No such remote '%s'\", remotename);\n+\tremote = remote_get(remotename);\n+\n+\tif (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) {\n+\t\tstrbuf_release(&key);\n+\t\treturn 1;\n+\t}\n+\tif (add_branches(remote, branches, key.buf)) {\n+\t\tstrbuf_release(&key);\n+\t\treturn 1;\n+\t}\n+\n+\tstrbuf_release(&key);\n+\treturn 0;\n+}\n+\n+static int set_branches(int argc, const char **argv)\n+{\n+\tint add_mode = 0;\n+\tstruct option options[] = {\n+\t\tOPT_BOOLEAN('\\0', \"add\", &add_mode, \"add branch\"),\n+\t\tOPT_END()\n+\t};\n+\n+\targc = parse_options(argc, argv, NULL, options,\n+\t\t\t     builtin_remote_setbranches_usage, 0);\n+\tif (argc == 0) {\n+\t\terror(\"no remote specified\");\n+\t\tusage_with_options(builtin_remote_seturl_usage, options);\n+\t}\n+\targv[argc] = NULL;\n+\n+\treturn set_remote_branches(argv[0], argv + 1, add_mode);\n+}\n+\n static int set_url(int argc, const char **argv)\n {\n \tint i, push_mode = 0, add_mode = 0, delete_mode = 0;\n@@ -1430,6 +1508,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)\n \t\tresult = rm(argc, argv);\n \telse if (!strcmp(argv[0], \"set-head\"))\n \t\tresult = set_head(argc, argv);\n+\telse if (!strcmp(argv[0], \"set-branches\"))\n+\t\tresult = set_branches(argc, argv);\n \telse if (!strcmp(argv[0], \"set-url\"))\n \t\tresult = set_url(argc, argv);\n \telse if (!strcmp(argv[0], \"show\"))\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 230c0cd..8aaf53e 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -534,6 +534,94 @@ test_expect_success 'show empty remote' '\n \t)\n '\n \n+test_expect_success 'remote set-branches requires a remote' '\n+\ttest_must_fail git remote set-branches &&\n+\ttest_must_fail git remote set-branches --add\n+'\n+\n+test_expect_success 'remote set-branches' '\n+\techo \"+refs/heads/*:refs/remotes/scratch/*\" >expect.initial &&\n+\tsort <<-\\EOF >expect.add &&\n+\t+refs/heads/*:refs/remotes/scratch/*\n+\t+refs/heads/other:refs/remotes/scratch/other\n+\tEOF\n+\tsort <<-\\EOF >expect.replace &&\n+\t+refs/heads/maint:refs/remotes/scratch/maint\n+\t+refs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\tEOF\n+\tsort <<-\\EOF >expect.add-two &&\n+\t+refs/heads/maint:refs/remotes/scratch/maint\n+\t+refs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\t+refs/heads/pu:refs/remotes/scratch/pu\n+\t+refs/heads/t/topic:refs/remotes/scratch/t/topic\n+\tEOF\n+\tsort <<-\\EOF >expect.setup-ffonly &&\n+\trefs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\tEOF\n+\tsort <<-\\EOF >expect.respect-ffonly &&\n+\trefs/heads/master:refs/remotes/scratch/master\n+\t+refs/heads/next:refs/remotes/scratch/next\n+\t+refs/heads/pu:refs/remotes/scratch/pu\n+\tEOF\n+\n+\tgit clone .git/ setbranches &&\n+\t(\n+\t\tcd setbranches &&\n+\t\tgit remote rename origin scratch &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.initial &&\n+\n+\t\tgit remote set-branches scratch --add other &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.add &&\n+\n+\t\tgit remote set-branches scratch maint master next &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.replace &&\n+\n+\t\tgit remote set-branches --add scratch pu t/topic &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.add-two &&\n+\n+\t\tgit config --unset-all remote.scratch.fetch &&\n+\t\tgit config remote.scratch.fetch \\\n+\t\t\trefs/heads/master:refs/remotes/scratch/master &&\n+\t\tgit config --add remote.scratch.fetch \\\n+\t\t\t+refs/heads/next:refs/remotes/scratch/next &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.setup-ffonly &&\n+\n+\t\tgit remote set-branches --add scratch pu &&\n+\t\tgit config --get-all remote.scratch.fetch >config-result &&\n+\t\tsort <config-result >../actual.respect-ffonly\n+\t) &&\n+\ttest_cmp expect.initial actual.initial &&\n+\ttest_cmp expect.add actual.add &&\n+\ttest_cmp expect.replace actual.replace &&\n+\ttest_cmp expect.add-two actual.add-two &&\n+\ttest_cmp expect.setup-ffonly actual.setup-ffonly &&\n+\ttest_cmp expect.respect-ffonly actual.respect-ffonly\n+'\n+\n+test_expect_success 'remote set-branches with --mirror' '\n+\techo \"+refs/*:refs/*\" >expect.initial &&\n+\techo \"+refs/heads/master:refs/heads/master\" >expect.replace &&\n+\tgit clone --mirror .git/ setbranches-mirror &&\n+\t(\n+\t\tcd setbranches-mirror &&\n+\t\tgit remote rename origin scratch &&\n+\t\tgit config --get-all remote.scratch.fetch >../actual.initial &&\n+\n+\t\tgit remote set-branches scratch heads/master &&\n+\t\tgit config --get-all remote.scratch.fetch >../actual.replace\n+\t) &&\n+\ttest_cmp expect.initial actual.initial &&\n+\ttest_cmp expect.replace actual.replace\n+'\n+\n test_expect_success 'new remote' '\n \tgit remote add someremote foo &&\n \techo foo >expect &&\n-- \n1.7.1\n"}]}