[PATCH] Pass --upload-pack and --receive-pack through submodules.

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

 



While I no longer have to worry about a zillion ancient OS versions,
I now have to worry about a remote site where I cannot control the
path for non-interactive shells.  Thus, submodules need to handle
explicitly specified git-upload-pack and git-receive-pack programs.

There may be a fun shell quoting dance to avoid the extra conditionals.
Any such dance would be even more confusing to read.

Signed-off-by: Jason Riedy <jason@xxxxxxx>
---
  Sorry; I forgot the documentation patch last time.  And it might be
  better just to copy the entire submodule config directly to the remote
  section...

 Documentation/git-submodule.txt |   15 +++++++-
 Documentation/gitmodules.txt    |   13 ++++++-
 git-submodule.sh                |   81 +++++++++++++++++++++++++++++++++++++--
 t/t7404-submodule-packbin.sh    |   53 +++++++++++++++++++++++++
 4 files changed, 156 insertions(+), 6 deletions(-)
 create mode 100755 t/t7404-submodule-packbin.sh

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 2f207fb..9e2de16 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
 SYNOPSIS
 --------
 [verse]
-'git submodule' [--quiet] add [-b branch] [--] <repository> <path>
+'git submodule' [--quiet] add [-b branch] [-u <git-upload-pack>] [--receive-pack <git-receive-pack>] [--] <repository> <path>
 'git submodule' [--quiet] status [--cached] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
 'git submodule' [--quiet] update [--init] [--] [<path>...]
@@ -159,6 +159,19 @@ OPTIONS
 --branch::
 	Branch of repository to add as submodule.
 
+--upload-pack <upload-pack>::
+-u <upload-pack>::
+	When given, and the repository to clone from is accessed
+	via ssh, this specifies a non-default path for the
+	'git-upload-pack' program on the remote end.  See
+	linkgit:git-fetch-pack[1].
+
+--receive-pack <receive-pack>::
+	When given, and the repository to clone from is accessed
+	via ssh, this specifies a non-default path for the
+	'git-receive-pack' program on the remote end.  See
+	linkgit:git-push[1].
+
 --cached::
 	This option is only valid for status and summary commands.  These
 	commands typically use the commit found in the submodule HEAD, but
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index d1a17e2..3387951 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -30,6 +30,13 @@ submodule.<name>.path::
 submodule.<name>.url::
 	Defines an url from where the submodule repository can be cloned.
 
+submodule.<name>.receivepack::
+	The default program to execute on the remote side when pushing.  See
+	option \--receive-pack of linkgit:git-push[1].
+
+submodule.<name>.uploadpack::
+	The default program to execute on the remote side when fetching.  See
+	option \--upload-pack of linkgit:git-fetch-pack[1].
 
 EXAMPLES
 --------
@@ -42,12 +49,16 @@ Consider the following .gitmodules file:
 
 	[submodule "libbar"]
 		path = include/bar
-		url = git://bar.com/git/lib.git
+		url = ssh://bar.com/~/git/lib.git
+		uploadpack = /home/you/bin/git-upload-pack-wrapper
+		receivepack = /home/you/bin/git-receive-pack-wrapper
 
 
 This defines two submodules, `libfoo` and `libbar`. These are expected to
 be checked out in the paths 'include/foo' and 'include/bar', and for both
 submodules an url is specified which can be used for cloning the submodules.
+For `libbar`, packs are retrieved and stored via the upload and receive
+wrappers, respectively.
 
 SEE ALSO
 --------
diff --git a/git-submodule.sh b/git-submodule.sh
index 2f47e06..1a8a968 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -90,6 +90,8 @@ module_clone()
 {
 	path=$1
 	url=$2
+	uploadpack=$3
+	receivepack=$4
 
 	# If there already is a directory at the submodule path,
 	# expect it to be empty (since that is the default checkout
@@ -105,8 +107,23 @@ module_clone()
 	test -e "$path" &&
 	die "A file already exist at path '$path'"
 
-	git-clone -n "$url" "$path" ||
+	if test "$uploadpack"
+	then
+	    git-clone --upload-pack $uploadpack -n "$url" "$path"
+	else
+	    git-clone -n "$url" "$path"
+	fi ||
 	die "Clone of '$url' into submodule path '$path' failed"
+	if test "$uploadpack"
+	then
+	    git config -f "${path}/.git/config" remote.origin.uploadpack "$uploadpack" ||
+	    echo "  Warn: Failed to set uploadpack for '$url' in submodule path '$path'."
+	fi
+	if test "$receivepack"
+	then
+	    git config -f "${path}/.git/config" remote.origin.receivepack "$receivepack" ||
+	    echo "  Warn: Failed to set receivepack for '$url' in submodule path '$path'."
+	fi
 }
 
 #
@@ -130,6 +147,16 @@ cmd_add()
 		-q|--quiet)
 			quiet=1
 			;;
+		-u|--upload-pack)
+			case "$2" in '') usage ;; esac
+			uploadpack=$2
+			shift
+			;;
+		--receive-pack)
+			case "$2" in '') usage ;; esac
+			receivepack=$2
+			shift
+			;;
 		--)
 			shift
 			break
@@ -191,9 +218,17 @@ cmd_add()
 			;;
 		esac
 		git config submodule."$path".url "$url"
+		if test "$uploadpack"
+		then
+		    git config submodule."$path".uploadpack "$uploadpack"
+		fi
+		if test "$receivepack"
+		then
+		    git config submodule."$path".receivepack "$receivepack"
+		fi
 	else
 
-		module_clone "$path" "$realrepo" || exit
+		module_clone "$path" "$realrepo" "$uploadpack" "$receivepack" || exit
 		(unset GIT_DIR; cd "$path" && git checkout -f -q ${branch:+-b "$branch" "origin/$branch"}) ||
 		die "Unable to checkout submodule '$path'"
 	fi
@@ -202,7 +237,19 @@ cmd_add()
 	die "Failed to add submodule '$path'"
 
 	git config -f .gitmodules submodule."$path".path "$path" &&
-	git config -f .gitmodules submodule."$path".url "$repo" &&
+	git config -f .gitmodules submodule."$path".url "$repo" ||
+	die "Failed to register submodule '$path'"
+
+	if test "$uploadpack"
+        then
+	    git config -f .gitmodules submodule."$path".uploadpack "$uploadpack" ||
+	    die "Failed to register submodule '$path'"
+	fi
+	if test "$receivepack"
+        then
+	    git config -f .gitmodules submodule."$path".receivepack "$receivepack" ||
+	    die "Failed to register submodule '$path'"
+	fi
 	git add .gitmodules ||
 	die "Failed to register submodule '$path'"
 }
@@ -277,6 +324,19 @@ cmd_init()
 		git config submodule."$name".url "$url" ||
 		die "Failed to register url for submodule path '$path'"
 
+		uploadpack=$(git config -f .gitmodules submodule."$name".uploadpack)
+		receivepack=$(git config -f .gitmodules submodule."$name".receivepack)
+		if test "$uploadpack"
+		then
+		    git config submodule."$name".uploadpack "$uploadpack" ||
+		    echo "  Warn: Failed to set uploadpack for '$url' in submodule path '$path'."
+		fi
+		if test "$receivepack"
+		then
+		    git config submodule."$name".receivepack "$receivepack" ||
+		    echo "  Warn: Failed to set receivepack for '$url' in submodule path '$path'."
+		fi
+
 		say "Submodule '$name' ($url) registered for path '$path'"
 	done
 }
@@ -330,7 +390,8 @@ cmd_update()
 
 		if ! test -d "$path"/.git -o -f "$path"/.git
 		then
-			module_clone "$path" "$url" || exit
+			module_clone "$path" "$url" "$(git config submodule."$name".uploadpack)" \
+			    "$(git config submodule."$name".receivepack)" || exit
 			subsha1=
 		else
 			subsha1=$(unset GIT_DIR; cd "$path" &&
@@ -655,6 +716,18 @@ cmd_sync()
 			remote=$(get_default_remote)
 			say "Synchronizing submodule url for '$name'"
 			git config remote."$remote".url "$url"
+			uploadpack=$(git config -f .gitmodules submodule."$name".uploadpack)
+			receivepack=$(git config -f .gitmodules submodule."$name".receivepack)
+			if test "$uploadpack"
+			then
+			    git config submodule."$name".uploadpack "$uploadpack" ||
+			    echo "  Warn: Failed to set uploadpack for '$url' in submodule path '$name'."
+			fi
+			if test "$receivepack"
+			then
+			    git config submodule."$name".receivepack "$receivepack" ||
+			    echo "  Warn: Failed to set receivepack for '$url' in submodule path '$name'."
+			fi
 		)
 		fi
 	done
diff --git a/t/t7404-submodule-packbin.sh b/t/t7404-submodule-packbin.sh
new file mode 100755
index 0000000..d46b3e6
--- /dev/null
+++ b/t/t7404-submodule-packbin.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 E. Jason Riedy
+#
+
+test_description='git submodule with explicit pack programs
+
+These tests exercise git submodule with --upload-pack and --receive-pack arguments.
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	echo file > file &&
+	git add file &&
+	test_tick &&
+	git commit -m upstream
+	git clone . super &&
+	git clone super submodule &&
+	(cd super &&
+	 git submodule add --upload-pack "${GIT_EXEC_PATH}/git-upload-pack" --receive-pack "${GIT_EXEC_PATH}/git-receive-pack" ../submodule submodule &&
+	 test_tick &&
+	 git commit -m "submodule"
+	) &&
+	git clone super super-clone &&
+	(cd super-clone && git submodule update --init)
+'
+
+test_expect_success 'push submodule change' '
+	(cd super &&
+         cd submodule &&
+         git checkout master &&
+	 echo second line >> file &&
+	 test_tick &&
+	 git commit -a -m "change submodule inside" &&
+         git push origin +master:pushed
+	)
+'
+
+test_expect_success 'pull submodule change' '
+	(cd submodule &&
+         git pull . pushed &&
+	 echo second line >> file &&
+	 test_tick &&
+	 git commit -a -m "change submodule outside"
+	) &&
+        (cd super &&
+         cd submodule &&
+         git pull origin master
+        )
+'
+
+test_done
-- 
1.6.1.60.g1f086.dirty

--
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