Add git remote set-url
Add 'git remote set-url' for changing URL of remote repository with one "porcelain-level" command. Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
ff6d26a0e1
commit
433f2be139
@ -14,6 +14,9 @@ SYNOPSIS
|
|||||||
'git remote rename' <old> <new>
|
'git remote rename' <old> <new>
|
||||||
'git remote rm' <name>
|
'git remote rm' <name>
|
||||||
'git remote set-head' <name> (-a | -d | <branch>)
|
'git remote set-head' <name> (-a | -d | <branch>)
|
||||||
|
'git remote set-url' [--push] <name> <newurl> [<oldurl>]
|
||||||
|
'git remote set-url --add' [--push] <name> <newurl>
|
||||||
|
'git remote set-url --delete' [--push] <name> <url>
|
||||||
'git remote' [-v | --verbose] 'show' [-n] <name>
|
'git remote' [-v | --verbose] 'show' [-n] <name>
|
||||||
'git remote prune' [-n | --dry-run] <name>
|
'git remote prune' [-n | --dry-run] <name>
|
||||||
'git remote' [-v | --verbose] 'update' [-p | --prune] [group | remote]...
|
'git remote' [-v | --verbose] 'update' [-p | --prune] [group | remote]...
|
||||||
@ -101,6 +104,20 @@ remote set-head origin master" will set `$GIT_DIR/refs/remotes/origin/HEAD` to
|
|||||||
`refs/remotes/origin/master` already exists; if not it must be fetched first.
|
`refs/remotes/origin/master` already exists; if not it must be fetched first.
|
||||||
+
|
+
|
||||||
|
|
||||||
|
'set-url'::
|
||||||
|
|
||||||
|
Changes URL remote points to. Sets first URL remote points to matching
|
||||||
|
regex <oldurl> (first URL if no <oldurl> is given) to <newurl>. If
|
||||||
|
<oldurl> doesn't match any URL, error occurs and nothing is changed.
|
||||||
|
+
|
||||||
|
With '--push', push URLs are manipulated instead of fetch URLs.
|
||||||
|
+
|
||||||
|
With '--add', instead of changing some URL, new URL is added.
|
||||||
|
+
|
||||||
|
With '--delete', instead of changing some URL, all URLs matching
|
||||||
|
regex <url> are deleted. Trying to delete all non-push URLs is an
|
||||||
|
error.
|
||||||
|
|
||||||
'show'::
|
'show'::
|
||||||
|
|
||||||
Gives some information about the remote <name>.
|
Gives some information about the remote <name>.
|
||||||
|
@ -16,6 +16,9 @@ static const char * const builtin_remote_usage[] = {
|
|||||||
"git remote [-v | --verbose] show [-n] <name>",
|
"git remote [-v | --verbose] show [-n] <name>",
|
||||||
"git remote prune [-n | --dry-run] <name>",
|
"git remote prune [-n | --dry-run] <name>",
|
||||||
"git remote [-v | --verbose] update [-p | --prune] [group | remote]",
|
"git remote [-v | --verbose] update [-p | --prune] [group | remote]",
|
||||||
|
"git remote set-url <name> <newurl> [<oldurl>]",
|
||||||
|
"git remote set-url --add <name> <newurl>",
|
||||||
|
"git remote set-url --delete <name> <url>",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,6 +57,13 @@ static const char * const builtin_remote_update_usage[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const builtin_remote_seturl_usage[] = {
|
||||||
|
"git remote set-url [--push] <name> <newurl> [<oldurl>]",
|
||||||
|
"git remote set-url --add <name> <newurl>",
|
||||||
|
"git remote set-url --delete <name> <url>",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
#define GET_REF_STATES (1<<0)
|
#define GET_REF_STATES (1<<0)
|
||||||
#define GET_HEAD_NAMES (1<<1)
|
#define GET_HEAD_NAMES (1<<1)
|
||||||
#define GET_PUSH_REF_STATES (1<<2)
|
#define GET_PUSH_REF_STATES (1<<2)
|
||||||
@ -1255,6 +1265,92 @@ static int update(int argc, const char **argv)
|
|||||||
return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
|
return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_url(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
int i, push_mode = 0, add_mode = 0, delete_mode = 0;
|
||||||
|
int matches = 0, negative_matches = 0;
|
||||||
|
const char *remotename = NULL;
|
||||||
|
const char *newurl = NULL;
|
||||||
|
const char *oldurl = NULL;
|
||||||
|
struct remote *remote;
|
||||||
|
regex_t old_regex;
|
||||||
|
const char **urlset;
|
||||||
|
int urlset_nr;
|
||||||
|
struct strbuf name_buf = STRBUF_INIT;
|
||||||
|
struct option options[] = {
|
||||||
|
OPT_BOOLEAN('\0', "push", &push_mode,
|
||||||
|
"manipulate push URLs"),
|
||||||
|
OPT_BOOLEAN('\0', "add", &add_mode,
|
||||||
|
"add URL"),
|
||||||
|
OPT_BOOLEAN('\0', "delete", &delete_mode,
|
||||||
|
"delete URLs"),
|
||||||
|
OPT_END()
|
||||||
|
};
|
||||||
|
argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,
|
||||||
|
PARSE_OPT_KEEP_ARGV0);
|
||||||
|
|
||||||
|
if (add_mode && delete_mode)
|
||||||
|
die("--add --delete doesn't make sense");
|
||||||
|
|
||||||
|
if (argc < 3 || argc > 4 || ((add_mode || delete_mode) && argc != 3))
|
||||||
|
usage_with_options(builtin_remote_seturl_usage, options);
|
||||||
|
|
||||||
|
remotename = argv[1];
|
||||||
|
newurl = argv[2];
|
||||||
|
if (argc > 3)
|
||||||
|
oldurl = argv[3];
|
||||||
|
|
||||||
|
if (delete_mode)
|
||||||
|
oldurl = newurl;
|
||||||
|
|
||||||
|
if (!remote_is_configured(remotename))
|
||||||
|
die("No such remote '%s'", remotename);
|
||||||
|
remote = remote_get(remotename);
|
||||||
|
|
||||||
|
if (push_mode) {
|
||||||
|
strbuf_addf(&name_buf, "remote.%s.pushurl", remotename);
|
||||||
|
urlset = remote->pushurl;
|
||||||
|
urlset_nr = remote->pushurl_nr;
|
||||||
|
} else {
|
||||||
|
strbuf_addf(&name_buf, "remote.%s.url", remotename);
|
||||||
|
urlset = remote->url;
|
||||||
|
urlset_nr = remote->url_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special cases that add new entry. */
|
||||||
|
if ((!oldurl && !delete_mode) || add_mode) {
|
||||||
|
if (add_mode)
|
||||||
|
git_config_set_multivar(name_buf.buf, newurl,
|
||||||
|
"^$", 0);
|
||||||
|
else
|
||||||
|
git_config_set(name_buf.buf, newurl);
|
||||||
|
strbuf_release(&name_buf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Old URL specified. Demand that one matches. */
|
||||||
|
if (regcomp(&old_regex, oldurl, REG_EXTENDED))
|
||||||
|
die("Invalid old URL pattern: %s", oldurl);
|
||||||
|
|
||||||
|
for (i = 0; i < urlset_nr; i++)
|
||||||
|
if (!regexec(&old_regex, urlset[i], 0, NULL, 0))
|
||||||
|
matches++;
|
||||||
|
else
|
||||||
|
negative_matches++;
|
||||||
|
if (!delete_mode && !matches)
|
||||||
|
die("No such URL found: %s", oldurl);
|
||||||
|
if (delete_mode && !negative_matches && !push_mode)
|
||||||
|
die("Will not delete all non-push URLs");
|
||||||
|
|
||||||
|
regfree(&old_regex);
|
||||||
|
|
||||||
|
if (!delete_mode)
|
||||||
|
git_config_set_multivar(name_buf.buf, newurl, oldurl, 0);
|
||||||
|
else
|
||||||
|
git_config_set_multivar(name_buf.buf, NULL, oldurl, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_one_entry(struct remote *remote, void *priv)
|
static int get_one_entry(struct remote *remote, void *priv)
|
||||||
{
|
{
|
||||||
struct string_list *list = priv;
|
struct string_list *list = priv;
|
||||||
@ -1334,6 +1430,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
|
|||||||
result = rm(argc, argv);
|
result = rm(argc, argv);
|
||||||
else if (!strcmp(argv[0], "set-head"))
|
else if (!strcmp(argv[0], "set-head"))
|
||||||
result = set_head(argc, argv);
|
result = set_head(argc, argv);
|
||||||
|
else if (!strcmp(argv[0], "set-url"))
|
||||||
|
result = set_url(argc, argv);
|
||||||
else if (!strcmp(argv[0], "show"))
|
else if (!strcmp(argv[0], "show"))
|
||||||
result = show(argc, argv);
|
result = show(argc, argv);
|
||||||
else if (!strcmp(argv[0], "prune"))
|
else if (!strcmp(argv[0], "prune"))
|
||||||
|
@ -533,5 +533,219 @@ test_expect_success 'show empty remote' '
|
|||||||
)
|
)
|
||||||
'
|
'
|
||||||
|
|
||||||
test_done
|
test_expect_success 'new remote' '
|
||||||
|
(
|
||||||
|
git remote add someremote foo &&
|
||||||
|
echo foo >expect &&
|
||||||
|
git config --get-all remote.someremote.url >actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url bar' '
|
||||||
|
(
|
||||||
|
git remote set-url someremote bar &&
|
||||||
|
echo bar >expect &&
|
||||||
|
git config --get-all remote.someremote.url >actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url baz bar' '
|
||||||
|
(
|
||||||
|
git remote set-url someremote baz bar &&
|
||||||
|
echo baz >expect &&
|
||||||
|
git config --get-all remote.someremote.url >actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url zot bar' '
|
||||||
|
(
|
||||||
|
test_must_fail git remote set-url someremote zot bar &&
|
||||||
|
echo baz >expect &&
|
||||||
|
git config --get-all remote.someremote.url >actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push zot baz' '
|
||||||
|
(
|
||||||
|
test_must_fail git remote set-url --push someremote zot baz &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push zot' '
|
||||||
|
(
|
||||||
|
git remote set-url --push someremote zot &&
|
||||||
|
echo zot >expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push qux zot' '
|
||||||
|
(
|
||||||
|
git remote set-url --push someremote qux zot &&
|
||||||
|
echo qux >expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push foo qu+x' '
|
||||||
|
(
|
||||||
|
git remote set-url --push someremote foo qu+x &&
|
||||||
|
echo foo >expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push --add aaa' '
|
||||||
|
(
|
||||||
|
git remote set-url --push --add someremote aaa &&
|
||||||
|
echo foo >expect &&
|
||||||
|
echo aaa >>expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push bar aaa' '
|
||||||
|
(
|
||||||
|
git remote set-url --push someremote bar aaa &&
|
||||||
|
echo foo >expect &&
|
||||||
|
echo bar >>expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push --delete bar' '
|
||||||
|
(
|
||||||
|
git remote set-url --push --delete someremote bar &&
|
||||||
|
echo foo >expect &&
|
||||||
|
echo "YYY" >>expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --push --delete foo' '
|
||||||
|
(
|
||||||
|
git remote set-url --push --delete someremote foo &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --add bbb' '
|
||||||
|
(
|
||||||
|
git remote set-url --add someremote bbb &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
echo bbb >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --delete .*' '
|
||||||
|
(
|
||||||
|
test_must_fail git remote set-url --delete someremote .* &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
echo bbb >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --delete bbb' '
|
||||||
|
(
|
||||||
|
git remote set-url --delete someremote bbb &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --delete baz' '
|
||||||
|
(
|
||||||
|
test_must_fail git remote set-url --delete someremote baz &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --add ccc' '
|
||||||
|
(
|
||||||
|
git remote set-url --add someremote ccc &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo baz >>expect &&
|
||||||
|
echo ccc >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'remote set-url --delete baz' '
|
||||||
|
(
|
||||||
|
git remote set-url --delete someremote baz &&
|
||||||
|
echo "YYY" >expect &&
|
||||||
|
echo ccc >>expect &&
|
||||||
|
test_must_fail git config --get-all remote.someremote.pushurl >actual &&
|
||||||
|
echo "YYY" >>actual &&
|
||||||
|
git config --get-all remote.someremote.url >>actual &&
|
||||||
|
cmp expect actual
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
||||||
|
Loading…
Reference in New Issue
Block a user