This adds the --fetch option to `git remote set-url` such that when executed we move the remote.*.url to remote.*.pushurl and set remote.*.url to the given url argument. For example, if we have the following config: [remote "origin"] url = git@xxxxxxxxxx:git/git.git `git remote set-url --fetch origin https://github.com/git/git.git` would change the config to the following: [remote "origin"] url = https://github.com/git/git.git pushurl = git@xxxxxxxxxx:git/git.git Signed-off-by: Denton Liu <liu.denton@xxxxxxxxx> Signed-off-by: Filip Francetic <f.francet@xxxxxxxxxxx> --- builtin/remote.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/builtin/remote.c b/builtin/remote.c index f7edf7f2c..fcf1220c6 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -23,9 +23,9 @@ static const char * const builtin_remote_usage[] = { N_("git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"), N_("git remote set-branches [--add] <name> <branch>..."), N_("git remote get-url [--push] [--all] <name>"), - N_("git remote set-url [--push] <name> <newurl> [<oldurl>]"), - N_("git remote set-url --add <name> <newurl>"), - N_("git remote set-url --delete <name> <url>"), + N_("git remote set-url [--push|--fetch] <name> <newurl> [<oldurl>]"), + N_("git remote set-url --add [--push|--fetch] <name> <newurl>"), + N_("git remote set-url --delete [--push|--fetch] <name> <url>"), NULL }; @@ -76,9 +76,9 @@ static const char * const builtin_remote_geturl_usage[] = { }; static const char * const builtin_remote_seturl_usage[] = { - N_("git remote set-url [--push] <name> <newurl> [<oldurl>]"), - N_("git remote set-url --add <name> <newurl>"), - N_("git remote set-url --delete <name> <url>"), + N_("git remote set-url [--push|--fetch] <name> <newurl> [<oldurl>]"), + N_("git remote set-url --add [--push|--fetch] <name> <newurl>"), + N_("git remote set-url --delete [--push|--fetch] <name> <url>"), NULL }; @@ -1519,7 +1519,7 @@ static int get_url(int argc, const char **argv) static int set_url(int argc, const char **argv) { - int i, push_mode = 0, add_mode = 0, delete_mode = 0; + int i, push_mode = 0, fetch_mode = 0, add_mode = 0, delete_mode = 0, move_fetch_to_push = 0; int matches = 0, negative_matches = 0; const char *remotename = NULL; const char *newurl = NULL; @@ -1532,6 +1532,8 @@ static int set_url(int argc, const char **argv) struct option options[] = { OPT_BOOL('\0', "push", &push_mode, N_("manipulate push URLs")), + OPT_BOOL('\0', "fetch", &fetch_mode, + N_("manipulate fetch URLs")), OPT_BOOL('\0', "add", &add_mode, N_("add URL")), OPT_BOOL('\0', "delete", &delete_mode, @@ -1543,6 +1545,8 @@ static int set_url(int argc, const char **argv) if (add_mode && delete_mode) die(_("--add --delete doesn't make sense")); + if (push_mode && fetch_mode) + die(_("--push --fetch doesn't make sense")); if (argc < 3 || argc > 4 || ((add_mode || delete_mode) && argc != 3)) usage_with_options(builtin_remote_seturl_usage, options); @@ -1559,18 +1563,40 @@ static int set_url(int argc, const char **argv) if (!remote_is_configured(remote, 1)) die(_("No such remote '%s'"), remotename); + /* + * If add_mode, we will be appending to remote.*.url so we shouldn't move the urls over. + * If pushurls exist, we don't need to move the urls over to pushurl. + */ + move_fetch_to_push = fetch_mode && !add_mode && !remote->pushurl_nr; + if (push_mode) { strbuf_addf(&name_buf, "remote.%s.pushurl", remotename); urlset = remote->pushurl; urlset_nr = remote->pushurl_nr; } else { + if (move_fetch_to_push) { + strbuf_addf(&name_buf, "remote.%s.pushurl", remotename); + for (i = 0; i < remote->url_nr; i++) { + git_config_set_multivar(name_buf.buf, remote->url[i], + "^$", 0); + } + strbuf_reset(&name_buf); + } + strbuf_addf(&name_buf, "remote.%s.url", remotename); urlset = remote->url; urlset_nr = remote->url_nr; } + /* Empty fetch URLs if they are being replaced */ + if (move_fetch_to_push) { + for (i = 0; i < remote->url_nr; i++) { + git_config_set_multivar(name_buf.buf, NULL, remote->url[i], 1); + } + } + /* Special cases that add new entry. */ - if ((!oldurl && !delete_mode) || add_mode) { + if ((!oldurl && !delete_mode) || move_fetch_to_push || add_mode) { if (add_mode) git_config_set_multivar(name_buf.buf, newurl, "^$", 0); -- 2.19.1.542.gc4df23f79.dirty