submodule: teach set-url subcommand
Currently, in the event that a submodule's upstream URL changes, users have to manually alter the URL in the .gitmodules file then run `git submodule sync`. Let's make that process easier. Teach submodule the set-url subcommand which will automatically change the `submodule.$name.url` property in the .gitmodules file and then run `git submodule sync` to complete the process. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Denton Liu committed
Oct 29, 2019 at 10:01 UTC
26b061007c1259ed4692554994961dd26874e63e
4 files changed
+113
-2
Documentation/git-submodule.txt
+6
@@ -16,6 +16,7 @@ SYNOPSIS
16
'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
17
'git submodule' [--quiet] update [<options>] [--] [<path>...]
18
'git submodule' [--quiet] set-branch [<options>] [--] <path>
19
+'git submodule' [--quiet] set-url [--] <path> <newurl>
20
'git submodule' [--quiet] summary [<options>] [--] [<path>...]
21
'git submodule' [--quiet] foreach [--recursive] <command>
22
'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
@@ -180,6 +181,11 @@ set-branch (-d|--default) [--] <path>::
181
`--default` option removes the submodule.<name>.branch configuration
182
key, which causes the tracking branch to default to 'master'.
183
184
+set-url [--] <path> <newurl>::
185
+ Sets the URL of the specified submodule to <newurl>. Then, it will
186
+ automatically synchronize the submodule's new remote URL
187
+ configuration.
188
+
189
summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]::
190
Show commit summary between the given commit (defaults to HEAD) and
191
working tree/index. For a submodule in question, a series of commits
contrib/completion/git-completion.bash
+1
-1
@@ -2779,7 +2779,7 @@ _git_submodule ()
2779
{
2780
__git_has_doubledash && return
2781
2782
- local subcommands="add status init deinit update set-branch summary foreach sync absorbgitdirs"
2782
+ local subcommands="add status init deinit update set-branch set-url summary foreach sync absorbgitdirs"
2783
local subcommand="$(__git_find_on_cmdline "$subcommands")"
2784
if [ -z "$subcommand" ]; then
2785
case "$cur" in
git-submodule.sh
+51
-1
@@ -12,6 +12,7 @@ USAGE="[--quiet] [--cached]
12
or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
13
or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
14
or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
15
+ or: $dashless [--quiet] set-url [--] <path> <newurl>
16
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
17
or: $dashless [--quiet] foreach [--recursive] <command>
18
or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
@@ -760,6 +761,55 @@ cmd_set_branch() {
761
fi
762
}
763
764
+#
765
+# Configures a submodule's remote url
766
+#
767
+# $@ = requested path, requested url
768
+#
769
+cmd_set_url() {
770
+ while test $# -ne 0
771
+ do
772
+ case "$1" in
773
+ -q|--quiet)
774
+ GIT_QUIET=1
775
+ ;;
776
+ --)
777
+ shift
778
+ break
779
+ ;;
780
+ -*)
781
+ usage
782
+ ;;
783
+ *)
784
+ break
785
+ ;;
786
+ esac
787
+ shift
788
+ done
789
+
790
+ if test $# -ne 2
791
+ then
792
+ usage
793
+ fi
794
+
795
+ # we can't use `git submodule--helper name` here because internally, it
796
+ # hashes the path so a trailing slash could lead to an unintentional no match
797
+ name="$(git submodule--helper list "$1" | cut -f2)"
798
+ if test -z "$name"
799
+ then
800
+ exit 1
801
+ fi
802
+
803
+ url="$2"
804
+ if test -z "$url"
805
+ then
806
+ exit 1
807
+ fi
808
+
809
+ git submodule--helper config submodule."$name".url "$url"
810
+ git submodule--helper sync ${GIT_QUIET:+--quiet} "$name"
811
+}
812
+
813
#
814
# Show commit summary for submodules in index or working tree
815
#
@@ -1059,7 +1109,7 @@ cmd_absorbgitdirs()
1109
while test $# != 0 && test -z "$command"
1110
do
1111
case "$1" in
1062
- add | foreach | init | deinit | update | set-branch | status | summary | sync | absorbgitdirs)
1112
+ add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
1113
command=$1
1114
;;
1115
-q|--quiet)
t/t7420-submodule-set-url.sh
new
+55
@@ -0,0 +1,55 @@
1
+#!/bin/sh
2
+#
3
+# Copyright (c) 2019 Denton Liu
4
+#
5
+
6
+test_description='Test submodules set-url subcommand
7
+
8
+This test verifies that the set-url subcommand of git-submodule is working
9
+as expected.
10
+'
11
+
12
+TEST_NO_CREATE_REPO=1
13
+. ./test-lib.sh
14
+
15
+test_expect_success 'submodule config cache setup' '
16
+ mkdir submodule &&
17
+ (
18
+ cd submodule &&
19
+ git init &&
20
+ echo a >file &&
21
+ git add file &&
22
+ git commit -ma
23
+ ) &&
24
+ mkdir super &&
25
+ (
26
+ cd super &&
27
+ git init &&
28
+ git submodule add ../submodule &&
29
+ git commit -m "add submodule"
30
+ )
31
+'
32
+
33
+test_expect_success 'test submodule set-url' '
34
+ # add a commit and move the submodule (change the url)
35
+ (
36
+ cd submodule &&
37
+ echo b >>file &&
38
+ git add file &&
39
+ git commit -mb
40
+ ) &&
41
+ mv submodule newsubmodule &&
42
+
43
+ git -C newsubmodule show >expect &&
44
+ (
45
+ cd super &&
46
+ test_must_fail git submodule update --remote &&
47
+ git submodule set-url submodule ../newsubmodule &&
48
+ grep -F "url = ../newsubmodule" .gitmodules &&
49
+ git submodule update --remote
50
+ ) &&
51
+ git -C super/submodule show >actual &&
52
+ test_cmp expect actual
53
+'
54
+
55
+test_done