@matheusbsbs / matheus-bagliano / commits / 26b061007c
Fork 0

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