[v2] submodule: teach set-url subcommand
diff mbox series

Message ID d8841c6009c91ac921d30b35ed9a441c87b332e2.1572337964.git.liu.denton@gmail.com
State New
Headers show
Series
  • [v2] submodule: teach set-url subcommand
Related show

Commit Message

Denton Liu Oct. 29, 2019, 8:34 a.m. UTC
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>
---
Range-diff against v1:
1:  3c7a496209 ! 1:  d8841c6009 submodule: teach set-url subcommand
    @@ Documentation/git-submodule.txt: SYNOPSIS
      'git submodule' [--quiet] summary [<options>] [--] [<path>...]
      'git submodule' [--quiet] foreach [--recursive] <command>
      'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
    -@@ Documentation/git-submodule.txt: set-branch ((-d|--default)|(-b|--branch <branch>)) [--] <path>::
    +@@ Documentation/git-submodule.txt: set-branch (-d|--default) [--] <path>::
      	`--default` option removes the submodule.<name>.branch configuration
      	key, which causes the tracking branch to default to 'master'.
      
    @@ t/t7420-submodule-set-url.sh (new)
     +
     +test_expect_success 'submodule config cache setup' '
     +	mkdir submodule &&
    -+	(cd submodule &&
    ++	(
    ++		cd submodule &&
     +		git init &&
     +		echo a >file &&
     +		git add file &&
     +		git commit -ma
     +	) &&
     +	mkdir super &&
    -+	(cd super &&
    ++	(
    ++		cd super &&
     +		git init &&
     +		git submodule add ../submodule &&
     +		git commit -m "add submodule"
    @@ t/t7420-submodule-set-url.sh (new)
     +
     +test_expect_success 'test submodule set-url' '
     +	# add a commit and move the submodule (change the url)
    -+	(cd submodule &&
    ++	(
    ++		cd submodule &&
     +		echo b >>file &&
     +		git add file &&
     +		git commit -mb
    @@ t/t7420-submodule-set-url.sh (new)
     +	mv submodule newsubmodule &&
     +
     +	git -C newsubmodule show >expect &&
    -+	(cd super &&
    ++	(
    ++		cd super &&
     +		test_must_fail git submodule update --remote &&
     +		git submodule set-url submodule ../newsubmodule &&
     +		grep "url = \.\./newsubmodule" .gitmodules &&
    -+		git submodule update --remote &&
    -+		git -C submodule show >../actual
    ++		git submodule update --remote
     +	) &&
    ++	git -C super/submodule show >actual &&
     +	test_cmp expect actual
     +'
     +

 Documentation/git-submodule.txt        |  6 +++
 contrib/completion/git-completion.bash |  2 +-
 git-submodule.sh                       | 52 +++++++++++++++++++++++-
 t/t7420-submodule-set-url.sh           | 55 ++++++++++++++++++++++++++
 4 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100755 t/t7420-submodule-set-url.sh

Comments

Danh Doan Oct. 29, 2019, 9:15 a.m. UTC | #1
On 2019-10-29 01:34:19 -0700, Denton Liu wrote:
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index 1f46380af2..f1c4689f24 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -16,6 +16,7 @@ SYNOPSIS
>  'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
>  'git submodule' [--quiet] update [<options>] [--] [<path>...]
>  'git submodule' [--quiet] set-branch [<options>] [--] <path>
> +'git submodule' [--quiet] set-url [<options>] [--] <path> <newurl>

I skimmed over this patch and found no options.
[<options>] should be removed

> @@ -180,6 +181,11 @@ set-branch (-d|--default) [--] <path>::
>  	`--default` option removes the submodule.<name>.branch configuration
>  	key, which causes the tracking branch to default to 'master'.
>  
> +set-url [--] <path> <newurl>::
> +	Sets the URL of the specified submodule to <newurl>. Then, it will
> +	automatically synchronize the submodule's new remote URL
> +	configuration.
> +
>  summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]::
>  	Show commit summary between the given commit (defaults to HEAD) and
>  	working tree/index. For a submodule in question, a series of commits
> diff --git a/git-submodule.sh b/git-submodule.sh
> index c7f58c5756..f7374ddbd6 100755
> --- a/git-submodule.sh
> +++ b/git-submodule.sh
> @@ -12,6 +12,7 @@ USAGE="[--quiet] [--cached]
>     or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
>     or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
>     or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
> +   or: $dashless [--quiet] set-url [--] <path> <newurl>
>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
>     or: $dashless [--quiet] foreach [--recursive] <command>
>     or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
> diff --git a/t/t7420-submodule-set-url.sh b/t/t7420-submodule-set-url.sh
> new file mode 100755
> index 0000000000..9bc941ced3
> --- /dev/null
> +++ b/t/t7420-submodule-set-url.sh
> +		grep "url = \.\./newsubmodule" .gitmodules &&

grep -F "url = ../newsubmodule"
will be easier to read.

Patch
diff mbox series

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 1f46380af2..f1c4689f24 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -16,6 +16,7 @@  SYNOPSIS
 'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...)
 'git submodule' [--quiet] update [<options>] [--] [<path>...]
 'git submodule' [--quiet] set-branch [<options>] [--] <path>
+'git submodule' [--quiet] set-url [<options>] [--] <path> <newurl>
 'git submodule' [--quiet] summary [<options>] [--] [<path>...]
 'git submodule' [--quiet] foreach [--recursive] <command>
 'git submodule' [--quiet] sync [--recursive] [--] [<path>...]
@@ -180,6 +181,11 @@  set-branch (-d|--default) [--] <path>::
 	`--default` option removes the submodule.<name>.branch configuration
 	key, which causes the tracking branch to default to 'master'.
 
+set-url [--] <path> <newurl>::
+	Sets the URL of the specified submodule to <newurl>. Then, it will
+	automatically synchronize the submodule's new remote URL
+	configuration.
+
 summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...]::
 	Show commit summary between the given commit (defaults to HEAD) and
 	working tree/index. For a submodule in question, a series of commits
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 00fbe6c03d..88c7446414 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2779,7 +2779,7 @@  _git_submodule ()
 {
 	__git_has_doubledash && return
 
-	local subcommands="add status init deinit update set-branch summary foreach sync absorbgitdirs"
+	local subcommands="add status init deinit update set-branch set-url summary foreach sync absorbgitdirs"
 	local subcommand="$(__git_find_on_cmdline "$subcommands")"
 	if [ -z "$subcommand" ]; then
 		case "$cur" in
diff --git a/git-submodule.sh b/git-submodule.sh
index c7f58c5756..f7374ddbd6 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -12,6 +12,7 @@  USAGE="[--quiet] [--cached]
    or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
+   or: $dashless [--quiet] set-url [--] <path> <newurl>
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
@@ -760,6 +761,55 @@  cmd_set_branch() {
 	fi
 }
 
+#
+# Configures a submodule's remote url
+#
+# $@ = requested path, requested url
+#
+cmd_set_url() {
+	while test $# -ne 0
+	do
+		case "$1" in
+		-q|--quiet)
+			GIT_QUIET=1
+			;;
+		--)
+			shift
+			break
+			;;
+		-*)
+			usage
+			;;
+		*)
+			break
+			;;
+		esac
+		shift
+	done
+
+	if test $# -ne 2
+	then
+		usage
+	fi
+
+	# we can't use `git submodule--helper name` here because internally, it
+	# hashes the path so a trailing slash could lead to an unintentional no match
+	name="$(git submodule--helper list "$1" | cut -f2)"
+	if test -z "$name"
+	then
+		exit 1
+	fi
+
+	url="$2"
+	if test -z "$url"
+	then
+		exit 1
+	fi
+
+	git submodule--helper config submodule."$name".url "$url"
+	git submodule--helper sync ${GIT_QUIET:+--quiet} "$name"
+}
+
 #
 # Show commit summary for submodules in index or working tree
 #
@@ -1059,7 +1109,7 @@  cmd_absorbgitdirs()
 while test $# != 0 && test -z "$command"
 do
 	case "$1" in
-	add | foreach | init | deinit | update | set-branch | status | summary | sync | absorbgitdirs)
+	add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
 		command=$1
 		;;
 	-q|--quiet)
diff --git a/t/t7420-submodule-set-url.sh b/t/t7420-submodule-set-url.sh
new file mode 100755
index 0000000000..9bc941ced3
--- /dev/null
+++ b/t/t7420-submodule-set-url.sh
@@ -0,0 +1,55 @@ 
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='Test submodules set-url subcommand
+
+This test verifies that the set-url subcommand of git-submodule is working
+as expected.
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule config cache setup' '
+	mkdir submodule &&
+	(
+		cd submodule &&
+		git init &&
+		echo a >file &&
+		git add file &&
+		git commit -ma
+	) &&
+	mkdir super &&
+	(
+		cd super &&
+		git init &&
+		git submodule add ../submodule &&
+		git commit -m "add submodule"
+	)
+'
+
+test_expect_success 'test submodule set-url' '
+	# add a commit and move the submodule (change the url)
+	(
+		cd submodule &&
+		echo b >>file &&
+		git add file &&
+		git commit -mb
+	) &&
+	mv submodule newsubmodule &&
+
+	git -C newsubmodule show >expect &&
+	(
+		cd super &&
+		test_must_fail git submodule update --remote &&
+		git submodule set-url submodule ../newsubmodule &&
+		grep "url = \.\./newsubmodule" .gitmodules &&
+		git submodule update --remote
+	) &&
+	git -C super/submodule show >actual &&
+	test_cmp expect actual
+'
+
+test_done