diff options
Diffstat (limited to 'git-submodule.sh')
| -rwxr-xr-x | git-submodule.sh | 175 | 
1 files changed, 25 insertions, 150 deletions
diff --git a/git-submodule.sh b/git-submodule.sh index 36797c3c00..9bc5c5f94d 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -22,6 +22,15 @@ require_work_tree  wt_prefix=$(git rev-parse --show-prefix)  cd_to_toplevel +# Restrict ourselves to a vanilla subset of protocols; the URLs +# we get are under control of a remote repository, and we do not +# want them kicking off arbitrary git-remote-* programs. +# +# If the user has already specified a set of allowed protocols, +# we assume they know what they're doing and use that instead. +: ${GIT_ALLOW_PROTOCOL=file:git:http:https:ssh} +export GIT_ALLOW_PROTOCOL +  command=  branch=  force= @@ -145,48 +154,6 @@ relative_path ()  	echo "$result$target"  } -# -# Get submodule info for registered submodules -# $@ = path to limit submodule list -# -module_list() -{ -	eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")" -	( -		git ls-files -z --error-unmatch --stage -- "$@" || -		echo "unmatched pathspec exists" -	) | -	@@PERL@@ -e ' -	my %unmerged = (); -	my ($null_sha1) = ("0" x 40); -	my @out = (); -	my $unmatched = 0; -	$/ = "\0"; -	while (<STDIN>) { -		if (/^unmatched pathspec/) { -			$unmatched = 1; -			next; -		} -		chomp; -		my ($mode, $sha1, $stage, $path) = -			/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/; -		next unless $mode eq "160000"; -		if ($stage ne "0") { -			if (!$unmerged{$path}++) { -				push @out, "$mode $null_sha1 U\t$path\n"; -			} -			next; -		} -		push @out, "$_\n"; -	} -	if ($unmatched) { -		print "#unmatched\n"; -	} else { -		print for (@out); -	} -	' -} -  die_if_unmatched ()  {  	if test "$1" = "#unmatched" @@ -220,98 +187,6 @@ get_submodule_config () {  	printf '%s' "${value:-$default}"  } - -# -# Map submodule path to submodule name -# -# $1 = path -# -module_name() -{ -	# Do we have "submodule.<something>.path = $1" defined in .gitmodules file? -	sm_path="$1" -	re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g') -	name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | -		sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' ) -	test -z "$name" && -	die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")" -	printf '%s\n' "$name" -} - -# -# Clone a submodule -# -# $1 = submodule path -# $2 = submodule name -# $3 = URL to clone -# $4 = reference repository to reuse (empty for independent) -# $5 = depth argument for shallow clones (empty for deep) -# -# Prior to calling, cmd_update checks that a possibly existing -# path is not a git repository. -# Likewise, cmd_add checks that path does not exist at all, -# since it is the location of a new submodule. -# -module_clone() -{ -	sm_path=$1 -	name=$2 -	url=$3 -	reference="$4" -	depth="$5" -	quiet= -	if test -n "$GIT_QUIET" -	then -		quiet=-q -	fi - -	gitdir= -	gitdir_base= -	base_name=$(dirname "$name") - -	gitdir=$(git rev-parse --git-dir) -	gitdir_base="$gitdir/modules/$base_name" -	gitdir="$gitdir/modules/$name" - -	if test -d "$gitdir" -	then -		mkdir -p "$sm_path" -		rm -f "$gitdir/index" -	else -		mkdir -p "$gitdir_base" -		( -			clear_local_git_env -			git clone $quiet ${depth:+"$depth"} -n ${reference:+"$reference"} \ -				--separate-git-dir "$gitdir" "$url" "$sm_path" -		) || -		die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")" -	fi - -	# We already are at the root of the work tree but cd_to_toplevel will -	# resolve any symlinks that might be present in $PWD -	a=$(cd_to_toplevel && cd "$gitdir" && pwd)/ -	b=$(cd_to_toplevel && cd "$sm_path" && pwd)/ -	# Remove all common leading directories after a sanity check -	if test "${a#$b}" != "$a" || test "${b#$a}" != "$b"; then -		die "$(eval_gettext "Gitdir '\$a' is part of the submodule path '\$b' or vice versa")" -	fi -	while test "${a%%/*}" = "${b%%/*}" -	do -		a=${a#*/} -		b=${b#*/} -	done -	# Now chop off the trailing '/'s that were added in the beginning -	a=${a%/} -	b=${b%/} - -	# Turn each leading "*/" component into "../" -	rel=$(printf '%s\n' "$b" | sed -e 's|[^/][^/]*|..|g') -	printf '%s\n' "gitdir: $rel/$a" >"$sm_path/.git" - -	rel=$(printf '%s\n' "$a" | sed -e 's|[^/][^/]*|..|g') -	(clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b") -} -  isnumber()  {  	n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1" @@ -472,7 +347,7 @@ Use -f if you really want to add it." >&2  				echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")"  			fi  		fi -		module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" "$depth" || exit +		git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" "$reference" "$depth" || exit  		(  			clear_local_git_env  			cd "$sm_path" && @@ -532,7 +407,7 @@ cmd_foreach()  	# command in the subshell (and a recursive call to this function)  	exec 3<&0 -	module_list | +	git submodule--helper list --prefix "$wt_prefix"|  	while read mode sha1 stage sm_path  	do  		die_if_unmatched "$mode" @@ -540,7 +415,7 @@ cmd_foreach()  		then  			displaypath=$(relative_path "$sm_path")  			say "$(eval_gettext "Entering '\$prefix\$displaypath'")" -			name=$(module_name "$sm_path") +			name=$(git submodule--helper name "$sm_path")  			(  				prefix="$prefix$sm_path/"  				clear_local_git_env @@ -592,11 +467,11 @@ cmd_init()  		shift  	done -	module_list "$@" | +	git submodule--helper list --prefix "$wt_prefix" "$@" |  	while read mode sha1 stage sm_path  	do  		die_if_unmatched "$mode" -		name=$(module_name "$sm_path") || exit +		name=$(git submodule--helper name "$sm_path") || exit  		displaypath=$(relative_path "$sm_path") @@ -674,11 +549,11 @@ cmd_deinit()  		die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"  	fi -	module_list "$@" | +	git submodule--helper list --prefix "$wt_prefix" "$@" |  	while read mode sha1 stage sm_path  	do  		die_if_unmatched "$mode" -		name=$(module_name "$sm_path") || exit +		name=$(git submodule--helper name "$sm_path") || exit  		displaypath=$(relative_path "$sm_path") @@ -790,7 +665,7 @@ cmd_update()  	fi  	cloned_modules= -	module_list "$@" | { +	git submodule--helper list --prefix "$wt_prefix" "$@" | {  	err=  	while read mode sha1 stage sm_path  	do @@ -800,7 +675,7 @@ cmd_update()  			echo >&2 "Skipping unmerged submodule $prefix$sm_path"  			continue  		fi -		name=$(module_name "$sm_path") || exit +		name=$(git submodule--helper name "$sm_path") || exit  		url=$(git config submodule."$name".url)  		branch=$(get_submodule_config "$name" branch master)  		if ! test -z "$update" @@ -834,7 +709,7 @@ Maybe you want to use 'update --init'?")"  		if ! test -d "$sm_path"/.git && ! test -f "$sm_path"/.git  		then -			module_clone "$sm_path" "$name" "$url" "$reference" "$depth" || exit +			git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$prefix" --path "$sm_path" --name "$name" --url "$url" "$reference" "$depth" || exit  			cloned_modules="$cloned_modules;$name"  			subsha1=  		else @@ -904,7 +779,7 @@ Maybe you want to use 'update --init'?")"  				;;  			!*)  				command="${update_module#!}" -				die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule  path '\$prefix\$sm_path'")" +				die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$prefix\$sm_path'")"  				say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': '\$command \$sha1'")"  				must_die_on_failure=yes  				;; @@ -1064,7 +939,7 @@ cmd_summary() {  			# Respect the ignore setting for --for-status.  			if test -n "$for_status"  			then -				name=$(module_name "$sm_path") +				name=$(git submodule--helper name "$sm_path")  				ignore_config=$(get_submodule_config "$name" ignore none)  				test $status != A && test $ignore_config = all && continue  			fi @@ -1222,11 +1097,11 @@ cmd_status()  		shift  	done -	module_list "$@" | +	git submodule--helper list --prefix "$wt_prefix" "$@" |  	while read mode sha1 stage sm_path  	do  		die_if_unmatched "$mode" -		name=$(module_name "$sm_path") || exit +		name=$(git submodule--helper name "$sm_path") || exit  		url=$(git config submodule."$name".url)  		displaypath=$(relative_path "$prefix$sm_path")  		if test "$stage" = U @@ -1299,11 +1174,11 @@ cmd_sync()  		esac  	done  	cd_to_toplevel -	module_list "$@" | +	git submodule--helper list --prefix "$wt_prefix" "$@" |  	while read mode sha1 stage sm_path  	do  		die_if_unmatched "$mode" -		name=$(module_name "$sm_path") +		name=$(git submodule--helper name "$sm_path")  		url=$(git config -f .gitmodules --get submodule."$name".url)  		# Possibly a url relative to parent  | 
