@matheusbsbs / matheus-bagliano / commits / 433f2be139
Fork 0

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>

Ilari Liusvaara committed Jan 18, 2010 at 19:18 UTC 433f2be139710e2fc7c0693a8411b2773f1a4b38
3 files changed +330 -1
Documentation/git-remote.txt
+17
@@ -14,6 +14,9 @@ SYNOPSIS
14 'git remote rename' <old> <new>
15 'git remote rm' <name>
16 'git remote set-head' <name> (-a | -d | <branch>)
17 +'git remote set-url' [--push] <name> <newurl> [<oldurl>]
18 +'git remote set-url --add' [--push] <name> <newurl>
19 +'git remote set-url --delete' [--push] <name> <url>
20 'git remote' [-v | --verbose] 'show' [-n] <name>
21 'git remote prune' [-n | --dry-run] <name>
22 '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
104 `refs/remotes/origin/master` already exists; if not it must be fetched first.
105 +
106
107 +'set-url'::
108 +
109 +Changes URL remote points to. Sets first URL remote points to matching
110 +regex <oldurl> (first URL if no <oldurl> is given) to <newurl>. If
111 +<oldurl> doesn't match any URL, error occurs and nothing is changed.
112 ++
113 +With '--push', push URLs are manipulated instead of fetch URLs.
114 ++
115 +With '--add', instead of changing some URL, new URL is added.
116 ++
117 +With '--delete', instead of changing some URL, all URLs matching
118 +regex <url> are deleted. Trying to delete all non-push URLs is an
119 +error.
120 +
121 'show'::
122
123 Gives some information about the remote <name>.
builtin-remote.c
+98
@@ -16,6 +16,9 @@ static const char * const builtin_remote_usage[] = {
16 "git remote [-v | --verbose] show [-n] <name>",
17 "git remote prune [-n | --dry-run] <name>",
18 "git remote [-v | --verbose] update [-p | --prune] [group | remote]",
19 + "git remote set-url <name> <newurl> [<oldurl>]",
20 + "git remote set-url --add <name> <newurl>",
21 + "git remote set-url --delete <name> <url>",
22 NULL
23 };
24
@@ -54,6 +57,13 @@ static const char * const builtin_remote_update_usage[] = {
57 NULL
58 };
59
60 +static const char * const builtin_remote_seturl_usage[] = {
61 + "git remote set-url [--push] <name> <newurl> [<oldurl>]",
62 + "git remote set-url --add <name> <newurl>",
63 + "git remote set-url --delete <name> <url>",
64 + NULL
65 +};
66 +
67 #define GET_REF_STATES (1<<0)
68 #define GET_HEAD_NAMES (1<<1)
69 #define GET_PUSH_REF_STATES (1<<2)
@@ -1255,6 +1265,92 @@ static int update(int argc, const char **argv)
1265 return run_command_v_opt(fetch_argv, RUN_GIT_CMD);
1266 }
1267
1268 +static int set_url(int argc, const char **argv)
1269 +{
1270 + int i, push_mode = 0, add_mode = 0, delete_mode = 0;
1271 + int matches = 0, negative_matches = 0;
1272 + const char *remotename = NULL;
1273 + const char *newurl = NULL;
1274 + const char *oldurl = NULL;
1275 + struct remote *remote;
1276 + regex_t old_regex;
1277 + const char **urlset;
1278 + int urlset_nr;
1279 + struct strbuf name_buf = STRBUF_INIT;
1280 + struct option options[] = {
1281 + OPT_BOOLEAN('\0', "push", &push_mode,
1282 + "manipulate push URLs"),
1283 + OPT_BOOLEAN('\0', "add", &add_mode,
1284 + "add URL"),
1285 + OPT_BOOLEAN('\0', "delete", &delete_mode,
1286 + "delete URLs"),
1287 + OPT_END()
1288 + };
1289 + argc = parse_options(argc, argv, NULL, options, builtin_remote_update_usage,
1290 + PARSE_OPT_KEEP_ARGV0);
1291 +
1292 + if (add_mode && delete_mode)
1293 + die("--add --delete doesn't make sense");
1294 +
1295 + if (argc < 3 || argc > 4 || ((add_mode || delete_mode) && argc != 3))
1296 + usage_with_options(builtin_remote_seturl_usage, options);
1297 +
1298 + remotename = argv[1];
1299 + newurl = argv[2];
1300 + if (argc > 3)
1301 + oldurl = argv[3];
1302 +
1303 + if (delete_mode)
1304 + oldurl = newurl;
1305 +
1306 + if (!remote_is_configured(remotename))
1307 + die("No such remote '%s'", remotename);
1308 + remote = remote_get(remotename);
1309 +
1310 + if (push_mode) {
1311 + strbuf_addf(&name_buf, "remote.%s.pushurl", remotename);
1312 + urlset = remote->pushurl;
1313 + urlset_nr = remote->pushurl_nr;
1314 + } else {
1315 + strbuf_addf(&name_buf, "remote.%s.url", remotename);
1316 + urlset = remote->url;
1317 + urlset_nr = remote->url_nr;
1318 + }
1319 +
1320 + /* Special cases that add new entry. */
1321 + if ((!oldurl && !delete_mode) || add_mode) {
1322 + if (add_mode)
1323 + git_config_set_multivar(name_buf.buf, newurl,
1324 + "^$", 0);
1325 + else
1326 + git_config_set(name_buf.buf, newurl);
1327 + strbuf_release(&name_buf);
1328 + return 0;
1329 + }
1330 +
1331 + /* Old URL specified. Demand that one matches. */
1332 + if (regcomp(&old_regex, oldurl, REG_EXTENDED))
1333 + die("Invalid old URL pattern: %s", oldurl);
1334 +
1335 + for (i = 0; i < urlset_nr; i++)
1336 + if (!regexec(&old_regex, urlset[i], 0, NULL, 0))
1337 + matches++;
1338 + else
1339 + negative_matches++;
1340 + if (!delete_mode && !matches)
1341 + die("No such URL found: %s", oldurl);
1342 + if (delete_mode && !negative_matches && !push_mode)
1343 + die("Will not delete all non-push URLs");
1344 +
1345 + regfree(&old_regex);
1346 +
1347 + if (!delete_mode)
1348 + git_config_set_multivar(name_buf.buf, newurl, oldurl, 0);
1349 + else
1350 + git_config_set_multivar(name_buf.buf, NULL, oldurl, 1);
1351 + return 0;
1352 +}
1353 +
1354 static int get_one_entry(struct remote *remote, void *priv)
1355 {
1356 struct string_list *list = priv;
@@ -1334,6 +1430,8 @@ int cmd_remote(int argc, const char **argv, const char *prefix)
1430 result = rm(argc, argv);
1431 else if (!strcmp(argv[0], "set-head"))
1432 result = set_head(argc, argv);
1433 + else if (!strcmp(argv[0], "set-url"))
1434 + result = set_url(argc, argv);
1435 else if (!strcmp(argv[0], "show"))
1436 result = show(argc, argv);
1437 else if (!strcmp(argv[0], "prune"))
t/t5505-remote.sh
+215 -1
@@ -533,5 +533,219 @@ test_expect_success 'show empty remote' '
533 )
534 '
535
536 -test_done
536 +test_expect_success 'new remote' '
537 +(
538 + git remote add someremote foo &&
539 + echo foo >expect &&
540 + git config --get-all remote.someremote.url >actual &&
541 + cmp expect actual
542 +)
543 +'
544 +
545 +test_expect_success 'remote set-url bar' '
546 +(
547 + git remote set-url someremote bar &&
548 + echo bar >expect &&
549 + git config --get-all remote.someremote.url >actual &&
550 + cmp expect actual
551 +)
552 +'
553
554 +test_expect_success 'remote set-url baz bar' '
555 +(
556 + git remote set-url someremote baz bar &&
557 + echo baz >expect &&
558 + git config --get-all remote.someremote.url >actual &&
559 + cmp expect actual
560 +)
561 +'
562 +
563 +test_expect_success 'remote set-url zot bar' '
564 +(
565 + test_must_fail git remote set-url someremote zot bar &&
566 + echo baz >expect &&
567 + git config --get-all remote.someremote.url >actual &&
568 + cmp expect actual
569 +)
570 +'
571 +
572 +test_expect_success 'remote set-url --push zot baz' '
573 +(
574 + test_must_fail git remote set-url --push someremote zot baz &&
575 + echo "YYY" >expect &&
576 + echo baz >>expect &&
577 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
578 + echo "YYY" >>actual &&
579 + git config --get-all remote.someremote.url >>actual &&
580 + cmp expect actual
581 +)
582 +'
583 +
584 +test_expect_success 'remote set-url --push zot' '
585 +(
586 + git remote set-url --push someremote zot &&
587 + echo zot >expect &&
588 + echo "YYY" >>expect &&
589 + echo baz >>expect &&
590 + git config --get-all remote.someremote.pushurl >actual &&
591 + echo "YYY" >>actual &&
592 + git config --get-all remote.someremote.url >>actual &&
593 + cmp expect actual
594 +)
595 +'
596 +
597 +test_expect_success 'remote set-url --push qux zot' '
598 +(
599 + git remote set-url --push someremote qux zot &&
600 + echo qux >expect &&
601 + echo "YYY" >>expect &&
602 + echo baz >>expect &&
603 + git config --get-all remote.someremote.pushurl >actual &&
604 + echo "YYY" >>actual &&
605 + git config --get-all remote.someremote.url >>actual &&
606 + cmp expect actual
607 +)
608 +'
609 +
610 +test_expect_success 'remote set-url --push foo qu+x' '
611 +(
612 + git remote set-url --push someremote foo qu+x &&
613 + echo foo >expect &&
614 + echo "YYY" >>expect &&
615 + echo baz >>expect &&
616 + git config --get-all remote.someremote.pushurl >actual &&
617 + echo "YYY" >>actual &&
618 + git config --get-all remote.someremote.url >>actual &&
619 + cmp expect actual
620 +)
621 +'
622 +
623 +test_expect_success 'remote set-url --push --add aaa' '
624 +(
625 + git remote set-url --push --add someremote aaa &&
626 + echo foo >expect &&
627 + echo aaa >>expect &&
628 + echo "YYY" >>expect &&
629 + echo baz >>expect &&
630 + git config --get-all remote.someremote.pushurl >actual &&
631 + echo "YYY" >>actual &&
632 + git config --get-all remote.someremote.url >>actual &&
633 + cmp expect actual
634 +)
635 +'
636 +
637 +test_expect_success 'remote set-url --push bar aaa' '
638 +(
639 + git remote set-url --push someremote bar aaa &&
640 + echo foo >expect &&
641 + echo bar >>expect &&
642 + echo "YYY" >>expect &&
643 + echo baz >>expect &&
644 + git config --get-all remote.someremote.pushurl >actual &&
645 + echo "YYY" >>actual &&
646 + git config --get-all remote.someremote.url >>actual &&
647 + cmp expect actual
648 +)
649 +'
650 +
651 +test_expect_success 'remote set-url --push --delete bar' '
652 +(
653 + git remote set-url --push --delete someremote bar &&
654 + echo foo >expect &&
655 + echo "YYY" >>expect &&
656 + echo baz >>expect &&
657 + git config --get-all remote.someremote.pushurl >actual &&
658 + echo "YYY" >>actual &&
659 + git config --get-all remote.someremote.url >>actual &&
660 + cmp expect actual
661 +)
662 +'
663 +
664 +test_expect_success 'remote set-url --push --delete foo' '
665 +(
666 + git remote set-url --push --delete someremote foo &&
667 + echo "YYY" >expect &&
668 + echo baz >>expect &&
669 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
670 + echo "YYY" >>actual &&
671 + git config --get-all remote.someremote.url >>actual &&
672 + cmp expect actual
673 +)
674 +'
675 +
676 +test_expect_success 'remote set-url --add bbb' '
677 +(
678 + git remote set-url --add someremote bbb &&
679 + echo "YYY" >expect &&
680 + echo baz >>expect &&
681 + echo bbb >>expect &&
682 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
683 + echo "YYY" >>actual &&
684 + git config --get-all remote.someremote.url >>actual &&
685 + cmp expect actual
686 +)
687 +'
688 +
689 +test_expect_success 'remote set-url --delete .*' '
690 +(
691 + test_must_fail git remote set-url --delete someremote .* &&
692 + echo "YYY" >expect &&
693 + echo baz >>expect &&
694 + echo bbb >>expect &&
695 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
696 + echo "YYY" >>actual &&
697 + git config --get-all remote.someremote.url >>actual &&
698 + cmp expect actual
699 +)
700 +'
701 +
702 +test_expect_success 'remote set-url --delete bbb' '
703 +(
704 + git remote set-url --delete someremote bbb &&
705 + echo "YYY" >expect &&
706 + echo baz >>expect &&
707 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
708 + echo "YYY" >>actual &&
709 + git config --get-all remote.someremote.url >>actual &&
710 + cmp expect actual
711 +)
712 +'
713 +
714 +test_expect_success 'remote set-url --delete baz' '
715 +(
716 + test_must_fail git remote set-url --delete someremote baz &&
717 + echo "YYY" >expect &&
718 + echo baz >>expect &&
719 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
720 + echo "YYY" >>actual &&
721 + git config --get-all remote.someremote.url >>actual &&
722 + cmp expect actual
723 +)
724 +'
725 +
726 +test_expect_success 'remote set-url --add ccc' '
727 +(
728 + git remote set-url --add someremote ccc &&
729 + echo "YYY" >expect &&
730 + echo baz >>expect &&
731 + echo ccc >>expect &&
732 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
733 + echo "YYY" >>actual &&
734 + git config --get-all remote.someremote.url >>actual &&
735 + cmp expect actual
736 +)
737 +'
738 +
739 +test_expect_success 'remote set-url --delete baz' '
740 +(
741 + git remote set-url --delete someremote baz &&
742 + echo "YYY" >expect &&
743 + echo ccc >>expect &&
744 + test_must_fail git config --get-all remote.someremote.pushurl >actual &&
745 + echo "YYY" >>actual &&
746 + git config --get-all remote.someremote.url >>actual &&
747 + cmp expect actual
748 +)
749 +'
750 +
751 +test_done