From: Junio C Hamano Date: Wed, 6 Apr 2011 17:38:14 +0000 (-0700) Subject: Merge branch 'jk/maint-remote-mirror-safer' X-Git-Tag: v1.7.5-rc1~2 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cea667e955cca71e517f259c86bf974d03064df2?ds=inline;hp=-c Merge branch 'jk/maint-remote-mirror-safer' * jk/maint-remote-mirror-safer: remote: deprecate --mirror remote: separate the concept of push and fetch mirrors remote: disallow some nonsensical option combinations --- cea667e955cca71e517f259c86bf974d03064df2 diff --combined Documentation/git-remote.txt index 37bd3e5388,ddcbcc00ae..528f34a131 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@@ -10,7 -10,7 +10,7 @@@ SYNOPSI -------- [verse] 'git remote' [-v | --verbose] - 'git remote add' [-t ] [-m ] [-f] [--tags|--no-tags] [--mirror] + 'git remote add' [-t ] [-m ] [-f] [--tags|--no-tags] [--mirror=] 'git remote rename' 'git remote rm' 'git remote set-head' (-a | -d | ) @@@ -67,11 -67,14 +67,14 @@@ multiple branches without grabbing all With `-m ` option, `$GIT_DIR/remotes//HEAD` is set up to point at remote's `` branch. See also the set-head command. + - In mirror mode, enabled with `\--mirror`, the refs will not be stored - in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option - only makes sense in bare repositories. If a remote uses mirror - mode, furthermore, `git push` will always behave as if `\--mirror` - was passed. + When a fetch mirror is created with `\--mirror=fetch`, the refs will not + be stored in the 'refs/remotes/' namespace, but rather everything in + 'refs/' on the remote will be directly mirrored into 'refs/' in the + local repository. This option only makes sense in bare repositories, + because a fetch would overwrite any local commits. + + + When a push mirror is created with `\--mirror=push`, then `git push` + will always behave as if `\--mirror` was passed. 'rename':: @@@ -214,6 -217,16 +217,6 @@@ linkgit:git-fetch[1 linkgit:git-branch[1] linkgit:git-config[1] -Author ------- -Written by Junio Hamano - - -Documentation --------------- -Documentation by J. Bruce Fields and the git-list . - - GIT --- Part of the linkgit:git[1] suite diff --combined builtin/remote.c index b71ecd228f,eb1229d689..8424152269 --- a/builtin/remote.c +++ b/builtin/remote.c @@@ -1,4 -1,4 +1,4 @@@ -#include "cache.h" +#include "builtin.h" #include "parse-options.h" #include "transport.h" #include "remote.h" @@@ -9,7 -9,7 +9,7 @@@ static const char * const builtin_remote_usage[] = { "git remote [-v | --verbose]", - "git remote add [-t ] [-m ] [-f] [--mirror] ", + "git remote add [-t ] [-m ] [-f] [--mirror=] ", "git remote rename ", "git remote rm ", "git remote set-head (-a | -d | )", @@@ -117,6 -117,11 +117,11 @@@ enum TAGS_SET = 2 }; + #define MIRROR_NONE 0 + #define MIRROR_FETCH 1 + #define MIRROR_PUSH 2 + #define MIRROR_BOTH (MIRROR_FETCH|MIRROR_PUSH) + static int add_branch(const char *key, const char *branchname, const char *remotename, int mirror, struct strbuf *tmp) { @@@ -131,9 -136,32 +136,32 @@@ return git_config_set_multivar(key, tmp->buf, "^$", 0); } + static const char mirror_advice[] = + "--mirror is dangerous and deprecated; please\n" + "\t use --mirror=fetch or --mirror=push instead"; + + static int parse_mirror_opt(const struct option *opt, const char *arg, int not) + { + unsigned *mirror = opt->value; + if (not) + *mirror = MIRROR_NONE; + else if (!arg) { + warning("%s", mirror_advice); + *mirror = MIRROR_BOTH; + } + else if (!strcmp(arg, "fetch")) + *mirror = MIRROR_FETCH; + else if (!strcmp(arg, "push")) + *mirror = MIRROR_PUSH; + else + return error("unknown mirror argument: %s", arg); + return 0; + } + static int add(int argc, const char **argv) { - int fetch = 0, mirror = 0, fetch_tags = TAGS_DEFAULT; + int fetch = 0, fetch_tags = TAGS_DEFAULT; + unsigned mirror = MIRROR_NONE; struct string_list track = STRING_LIST_INIT_NODUP; const char *master = NULL; struct remote *remote; @@@ -151,7 -179,9 +179,9 @@@ OPT_CALLBACK('t', "track", &track, "branch", "branch(es) to track", opt_parse_track), OPT_STRING('m', "master", &master, "branch", "master branch"), - OPT_BOOLEAN(0, "mirror", &mirror, "no separate remotes"), + { OPTION_CALLBACK, 0, "mirror", &mirror, "push|fetch", + "set up remote as a mirror to push to or fetch from", + PARSE_OPT_OPTARG, parse_mirror_opt }, OPT_END() }; @@@ -161,6 -191,11 +191,11 @@@ if (argc < 2) usage_with_options(builtin_remote_add_usage, options); + if (mirror && master) + die("specifying a master branch makes no sense with --mirror"); + if (mirror && track.nr) + die("specifying branches to track makes no sense with --mirror"); + name = argv[0]; url = argv[1]; @@@ -177,18 -212,19 +212,19 @@@ if (git_config_set(buf.buf, url)) return 1; - strbuf_reset(&buf); - strbuf_addf(&buf, "remote.%s.fetch", name); - - if (track.nr == 0) - string_list_append(&track, "*"); - for (i = 0; i < track.nr; i++) { - if (add_branch(buf.buf, track.items[i].string, - name, mirror, &buf2)) - return 1; + if (!mirror || mirror & MIRROR_FETCH) { + strbuf_reset(&buf); + strbuf_addf(&buf, "remote.%s.fetch", name); + if (track.nr == 0) + string_list_append(&track, "*"); + for (i = 0; i < track.nr; i++) { + if (add_branch(buf.buf, track.items[i].string, + name, mirror, &buf2)) + return 1; + } } - if (mirror) { + if (mirror & MIRROR_PUSH) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.mirror", name); if (git_config_set(buf.buf, "true"))