[PATCH 1/3] git-submodule - Follow top-level remote on init/update/clone

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This change allows the remote used for relative submodules (those defined
using a url that is relative to their parent) to be defined by explicit
definition on the command line or through the top-level project's
branch.<name>.remote configuration.  This override is applied *only* to
submodules defined using a url relative to the top-level project's url,
under the assumption that such modules are logically part of the same
project and managed as a unit.  For relative submodules, the given remote
will be defined in each submodule using the relative url applied to the
top-level's url the first time the remote is used.  Any existing remote
definition is unaffected, so this can be changed manually by the user at
any time.

Submodules defined using an absolute url are unaffected.

Signed-off-by: Mark Levedahl <mlevedahl@xxxxxxxxx>
---
 Documentation/git-submodule.txt |   16 +++++++-
 git-submodule.sh                |   76 ++++++++++++++++++++++++++++++++-------
 2 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index e818e6e..4fc17f6 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -9,9 +9,9 @@ git-submodule - Initialize, update or inspect submodules
 SYNOPSIS
 --------
 [verse]
-'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
+'git-submodule' [--quiet] add [-b branch] [-r <remote>] [--] <repository> [<path>]
 'git-submodule' [--quiet] status [--cached] [--] [<path>...]
-'git-submodule' [--quiet] [init|update] [--] [<path>...]
+'git-submodule' [--quiet] [init|update] [-r <remote>] [--] [<path>...]
 
 
 COMMANDS
@@ -55,6 +55,18 @@ OPTIONS
 -b, --branch::
 	Branch of repository to add as submodule.
 
+-r remote::
+	Name of remote to use or define when working with relative submodules
+	(i.e., submodules whose url is given relative to the top-level
+	project). If this value is undefined, the top-level project's
+	branch.<name>.remote is used, and if that is undefined the default
+	"origin" is used. The remote will be defined in each relative
+	submodule as needed by appending the relative url to the top level
+	project's url. This option has no effect upon submodules defined
+	using an absolute url: such project's are cloned using the default
+	"origin," and are updated using the submodule's branch.<name>.remote
+	machinery and defaulting to "origin."
+
 --cached::
 	Display the SHA-1 stored in the index, not the SHA-1 of the currently
 	checked out submodule commit. This option is only valid for the
diff --git a/git-submodule.sh b/git-submodule.sh
index a6aaf40..b97bf18 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -4,15 +4,17 @@
 #
 # Copyright (c) 2007 Lars Hjemli
 
-USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
+USAGE='[--quiet] [--cached] [add [-r remote] <repo> [-b branch]|status|init [-r remote]|update [-r remote]] [--] [<path>...]'
 OPTIONS_SPEC=
 . git-sh-setup
+. git-parse-remote
 require_work_tree
 
 command=
 branch=
 quiet=
 cached=
+remote=
 
 #
 # print stuff on stdout unless -q was specified
@@ -40,11 +42,13 @@ get_repo_base() {
 # Resolve relative url by appending to parent's url
 resolve_relative_url ()
 {
-	branch="$(git symbolic-ref HEAD 2>/dev/null)"
-	remote="$(git config branch.${branch#refs/heads/}.remote)"
-	remote="${remote:-origin}"
-	remoteurl="$(git config remote.$remote.url)" ||
-		die "remote ($remote) does not have a url in .git/config"
+	remote="${remote:-$(get_default_remote)}"
+	remoteurl=$(git config remote.$remote.url)
+	if test -z "$remoteurl" ; then
+		echo >&2 "remote ($remote) does not have a url defined in .git/config"
+		return 1
+	fi
+	remoteurl="${remoteurl%/.git}"
 	url="$1"
 	while test -n "$url"
 	do
@@ -92,6 +96,7 @@ module_clone()
 {
 	path=$1
 	url=$2
+	remote=$3
 
 	# If there already is a directory at the submodule path,
 	# expect it to be empty (since that is the default checkout
@@ -107,7 +112,7 @@ module_clone()
 	test -e "$path" &&
 	die "A file already exist at path '$path'"
 
-	git-clone -n "$url" "$path" ||
+	git-clone -n -o "$remote" "$url" "$path" ||
 	die "Clone of '$url' into submodule path '$path' failed"
 }
 
@@ -129,6 +134,14 @@ cmd_add()
 			branch=$2
 			shift
 			;;
+		-r)
+			case "$2" in
+			'')
+				usage
+				;;
+			esac
+			remote="$2"; shift
+			;;
 		-q|--quiet)
 			quiet=1
 			;;
@@ -156,13 +169,16 @@ cmd_add()
 	case "$repo" in
 	./*|../*)
 		# dereference source url relative to parent's url
-		realrepo="$(resolve_relative_url $repo)" ;;
+		realremote=${remote:-$(get_default_remote)}
+		realrepo=$(resolve_relative_url $repo) || exit 1
+		;;
 	*)
 		# Turn the source into an absolute path if
 		# it is local
 		if base=$(get_repo_base "$repo"); then
 			repo="$base"
 		fi
+		realremote=origin
 		realrepo=$repo
 		;;
 	esac
@@ -180,8 +196,8 @@ cmd_add()
 	git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
 	die "'$path' already exists in the index"
 
-	module_clone "$path" "$realrepo" || exit
-	(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
+	module_clone "$path" "$realrepo" "$realremote" || exit
+	(unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "$realremote/$branch"}) ||
 	die "Unable to checkout submodule '$path'"
 	git add "$path" ||
 	die "Failed to add submodule '$path'"
@@ -206,6 +222,14 @@ cmd_init()
 		-q|--quiet)
 			quiet=1
 			;;
+		-r)
+			case "$2" in
+			'')
+				usage
+				;;
+			esac
+			remote="$2"; shift
+			;;
 		--)
 			shift
 			break
@@ -235,7 +259,7 @@ cmd_init()
 		# Possibly a url relative to parent
 		case "$url" in
 		./*|../*)
-			url="$(resolve_relative_url "$url")"
+			url=$(resolve_relative_url "$url") || exit 1
 			;;
 		esac
 
@@ -248,6 +272,8 @@ cmd_init()
 
 #
 # Update each submodule path to correct revision, using clone and checkout as needed
+# For relative submodules (defined using relative url), we use master project's remote
+# and define that in each submodule if not already there
 #
 # $@ = requested paths (default to all)
 #
@@ -260,6 +286,14 @@ cmd_update()
 		-q|--quiet)
 			quiet=1
 			;;
+		-r)
+			case "$2" in
+			'')
+				usage
+				;;
+			esac
+			remote="$2"; shift
+			;;
 		--)
 			shift
 			break
@@ -274,6 +308,7 @@ cmd_update()
 		shift
 	done
 
+	remote=${remote:-$(get_default_remote)}
 	git ls-files --stage -- "$@" | grep -e '^160000 ' |
 	while read mode sha1 stage path
 	do
@@ -290,7 +325,7 @@ cmd_update()
 
 		if ! test -d "$path"/.git
 		then
-			module_clone "$path" "$url" || exit
+			module_clone "$path" "$url" "$remote" || exit
 			subsha1=
 		else
 			subsha1=$(unset GIT_DIR; cd "$path" &&
@@ -298,9 +333,24 @@ cmd_update()
 			die "Unable to find current revision in submodule path '$path'"
 		fi
 
+		baseurl="$(GIT_CONFIG=.gitmodules git config submodule."$name".url)"
+		case "$baseurl" in
+		./*|../*)
+			fetch_remote=$remote
+			absurl=$(resolve_relative_url $baseurl) || exit 1
+			(unset GIT_DIR ; cd "$path" && git config remote."$fetch_remote".url > /dev/null) ||
+			(
+				unset GIT_DIR; cd "$path" && git remote add "$fetch_remote" "$absurl"
+			) || die "Unable to define remote '$fetch_remote' in submodule path '$path'"
+			;;
+		*)
+			fetch_remote=
+			;;
+		esac
+
 		if test "$subsha1" != "$sha1"
 		then
-			(unset GIT_DIR; cd "$path" && git-fetch &&
+			(unset GIT_DIR; cd "$path" && git-fetch $fetch_remote &&
 				git-checkout -q "$sha1") ||
 			die "Unable to checkout '$sha1' in submodule path '$path'"
 
-- 
1.5.4.47.gcca7b3

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux