git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Added initialize and update support for submodule in git clone
@ 2008-01-08  3:22 Imran M Yousuf
  2008-01-08  6:19 ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Imran M Yousuf @ 2008-01-08  3:22 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 3917 bytes --]

This patch adds support for initializing and updating submodules when
a repo is cloned. The advantage it adds is, the user actually does not
have to know whether it has a module or not and if it does to what
depth and path. For this I added a option -w or --with-submodule for
initializing and updating during clone stage.

I am working on project that has multiple maven modules and some of
the modules have separate GIT repo and needs to be linked with the
main project after maturity; we wanted that when developers clone the
main repo it should fetch all the submodules at once.

Following is the diff with git-clone 1.5.3.7; I also attached the diff
and modified file in the attachment. I would like to add that I am not
fully sure about unsetting the GIT_DIR, GIT_CONFIG and GIT_WORK_TREE
and resetting them and thus added them to the comment. If there is a
better way to achieve it I would gratefully incorporate it.

diff --git a/git-clone b/git-clone
index 204a769..63510c4 100755
--- a/git-clone
+++ b/git-clone
@@ -14,7 +14,7 @@ die() {
 }

 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference
<reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin
<name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference
<reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u
<upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
 }

 get_repo_base() {
@@ -90,6 +90,29 @@ Perhaps git-update-server-info needs to be run there?"
 	fi
 }

+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		git-submodule-test init "$1"; git-submodule-test update "$1"
+	fi
+}
+
+initSubModules() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ -f .gitmodules ]; then
+                for sub_mod_path in `grep "path =" .gitmodules | awk
'{print $3}'`; do
+			initSubModules "$sub_mod_path"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
 quiet=
 local=no
 use_local_hardlink=yes
@@ -106,6 +129,7 @@ depth=
 no_progress=
 local_explicitly_asked_for=
 test -t 1 || no_progress=--no-progress
+with_submodule=0
 while
 	case "$#,$1" in
 	0,*) break ;;
@@ -156,6 +180,7 @@ while
 		upload_pack="--upload-pack=$1" ;;
 	*,--upload-pack=*)
 		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
+	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule)
with_submodule=1 ;;
 	1,--depth) usage;;
 	*,--depth)
 		shift
@@ -465,4 +490,38 @@ then
 fi
 rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"

+# The following section initializes the submodules of the repo
+if [ $with_submodule -eq 1  ]; then
+	if [ -f .gitmodules ]; then
+
+		# Need to know either what is the alternate
+		# or what else to backup and unset
+		# If this is not done in that case recursion
+		# in a subdirectory of the top level fails
+		# Thus the old values are backed up and restored
+		# after recursion
+		OLD_GIT_DIR="$GIT_DIR"
+		OLD_GIT_CONFIG="$GIT_CONFIG"
+		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
+		unset GIT_DIR
+		unset GIT_CONFIG
+		unset GIT_WORK_TREE
+
+		# The following loop iterates over the submodules
+		# visible from he top of the module
+	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+                        initSubModules "$mod_path"
+                done
+
+		GIT_DIR="$OLD_GIT_DIR"
+		GIT_CONFIG="$OLD_GIT_CONFIG"
+		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"
+
+		# The following export is probably not required
+		export GIT_DIR
+		export GIT_CONFIG
+		export GIT_WORK_TREE
+	fi
+fi
+
 trap - 0

-- 
Imran M Yousuf

[-- Attachment #2: git-clone --]
[-- Type: application/octet-stream, Size: 13388 bytes --]

#!/bin/sh
#
# Copyright (c) 2005, Linus Torvalds
# Copyright (c) 2005, Junio C Hamano
#
# Clone a repository into a different directory that does not yet exist.

# See git-sh-setup why.
unset CDPATH

die() {
	echo >&2 "$@"
	exit 1
}

usage() {
	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
}

get_repo_base() {
	(
		cd "`/bin/pwd`" &&
		cd "$1" || cd "$1.git" &&
		{
			cd .git
			pwd
		}
	) 2>/dev/null
}

if [ -n "$GIT_SSL_NO_VERIFY" -o \
	"`git config --bool http.sslVerify`" = false ]; then
    curl_extra_args="-k"
fi

http_fetch () {
	# $1 = Remote, $2 = Local
	curl -nsfL $curl_extra_args "$1" >"$2" ||
		case $? in
		126|127) exit ;;
		*)	 return $? ;;
		esac
}

clone_dumb_http () {
	# $1 - remote, $2 - local
	cd "$2" &&
	clone_tmp="$GIT_DIR/clone-tmp" &&
	mkdir -p "$clone_tmp" || exit 1
	if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
		"`git config --bool http.noEPSV`" = true ]; then
		curl_extra_args="${curl_extra_args} --disable-epsv"
	fi
	http_fetch "$1/info/refs" "$clone_tmp/refs" ||
		die "Cannot get remote repository information.
Perhaps git-update-server-info needs to be run there?"
	test "z$quiet" = z && v=-v || v=
	while read sha1 refname
	do
		name=`expr "z$refname" : 'zrefs/\(.*\)'` &&
		case "$name" in
		*^*)	continue;;
		esac
		case "$bare,$name" in
		yes,* | ,heads/* | ,tags/*) ;;
		*)	continue ;;
		esac
		if test -n "$use_separate_remote" &&
		   branch_name=`expr "z$name" : 'zheads/\(.*\)'`
		then
			tname="remotes/$origin/$branch_name"
		else
			tname=$name
		fi
		git-http-fetch $v -a -w "$tname" "$sha1" "$1" || exit 1
	done <"$clone_tmp/refs"
	rm -fr "$clone_tmp"
	http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
	rm -f "$GIT_DIR/REMOTE_HEAD"
	if test -f "$GIT_DIR/REMOTE_HEAD"; then
		head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
		case "$head_sha1" in
		'ref: refs/'*)
			;;
		*)
			git-http-fetch $v -a "$head_sha1" "$1" ||
			rm -f "$GIT_DIR/REMOTE_HEAD"
			;;
		esac
	fi
}

initializeSubModule() {
	if [ ! -d "$1"/.git ]; then
		git-submodule-test init "$1"; git-submodule-test update "$1"
	fi
}

initSubModules() {
	current_dir=`pwd`
	dir_path="$current_dir:$dir_path"
	initializeSubModule "$1"
        cd "$1"
	if [ -f .gitmodules ]; then
                for sub_mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
			initSubModules "$sub_mod_path"
                done
        fi
	old_dir=$(echo $dir_path | cut -d':' -f1-1)
	length_old_dir=`expr "$old_dir" : '.*'`
	cd $old_dir
	index=$(echo "$length_old_dir+2" | bc)
	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
}

quiet=
local=no
use_local_hardlink=yes
local_shared=no
unset template
no_checkout=
upload_pack=
bare=
reference=
origin=
origin_override=
use_separate_remote=t
depth=
no_progress=
local_explicitly_asked_for=
test -t 1 || no_progress=--no-progress
with_submodule=0
while
	case "$#,$1" in
	0,*) break ;;
	*,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\
	*,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout)
	  no_checkout=yes ;;
	*,--na|*,--nak|*,--nake|*,--naked|\
	*,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
	*,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
	  local_explicitly_asked_for=yes
	  use_local_hardlink=yes ;;
	*,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
	*,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
	  use_local_hardlink=no ;;
        *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
          local_shared=yes; ;;
	1,--template) usage ;;
	*,--template)
		shift; template="--template=$1" ;;
	*,--template=*)
	  template="$1" ;;
	*,-q|*,--quiet) quiet=-q ;;
	*,--use-separate-remote) ;;
	*,--no-separate-remote)
		die "clones are always made with separate-remote layout" ;;
	1,--reference) usage ;;
	*,--reference)
		shift; reference="$1" ;;
	*,--reference=*)
		reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
	*,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
		case "$2" in
		'')
		    usage ;;
		*/*)
		    die "'$2' is not suitable for an origin name"
		esac
		git check-ref-format "heads/$2" ||
		    die "'$2' is not suitable for a branch name"
		test -z "$origin_override" ||
		    die "Do not give more than one --origin options."
		origin_override=yes
		origin="$2"; shift
		;;
	1,-u|1,--upload-pack) usage ;;
	*,-u|*,--upload-pack)
		shift
		upload_pack="--upload-pack=$1" ;;
	*,--upload-pack=*)
		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule) with_submodule=1 ;;
	1,--depth) usage;;
	*,--depth)
		shift
		depth="--depth=$1";;
	*,-*) usage ;;
	*) break ;;
	esac
do
	shift
done

repo="$1"
test -n "$repo" ||
    die 'you must specify a repository to clone.'

# --bare implies --no-checkout and --no-separate-remote
if test yes = "$bare"
then
	if test yes = "$origin_override"
	then
		die '--bare and --origin $origin options are incompatible.'
	fi
	no_checkout=yes
	use_separate_remote=
fi

if test -z "$origin"
then
	origin=origin
fi

# Turn the source into an absolute path if
# it is local
if base=$(get_repo_base "$repo"); then
	repo="$base"
	local=yes
fi

dir="$2"
# Try using "humanish" part of source repo if user didn't specify one
[ -z "$dir" ] && dir=$(echo "$repo" | sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
[ -e "$dir" ] && die "destination directory '$dir' already exists."
[ yes = "$bare" ] && unset GIT_WORK_TREE
[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] &&
die "working tree '$GIT_WORK_TREE' already exists."
D=
W=
cleanup() {
	err=$?
	test -z "$D" && rm -rf "$dir"
	test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE"
	cd ..
	test -n "$D" && rm -rf "$D"
	test -n "$W" && rm -rf "$W"
	exit $err
}
trap cleanup 0
mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage
test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" &&
W=$(cd "$GIT_WORK_TREE" && pwd) && export GIT_WORK_TREE="$W"
if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then
	GIT_DIR="$D"
else
	GIT_DIR="$D/.git"
fi &&
export GIT_DIR &&
GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage

if test -n "$bare"
then
	GIT_CONFIG="$GIT_DIR/config" git config core.bare true
fi

if test -n "$reference"
then
	ref_git=
	if test -d "$reference"
	then
		if test -d "$reference/.git/objects"
		then
			ref_git="$reference/.git"
		elif test -d "$reference/objects"
		then
			ref_git="$reference"
		fi
	fi
	if test -n "$ref_git"
	then
		ref_git=$(cd "$ref_git" && pwd)
		echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
		(
			GIT_DIR="$ref_git" git for-each-ref \
				--format='%(objectname) %(*objectname)'
		) |
		while read a b
		do
			test -z "$a" ||
			git update-ref "refs/reference-tmp/$a" "$a"
			test -z "$b" ||
			git update-ref "refs/reference-tmp/$b" "$b"
		done
	else
		die "reference repository '$reference' is not a local directory."
	fi
fi

rm -f "$GIT_DIR/CLONE_HEAD"

# We do local magic only when the user tells us to.
case "$local" in
yes)
	( cd "$repo/objects" ) ||
		die "cannot chdir to local '$repo/objects'."

	if test "$local_shared" = yes
	then
		mkdir -p "$GIT_DIR/objects/info"
		echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
	else
		l= &&
		if test "$use_local_hardlink" = yes
		then
			# See if we can hardlink and drop "l" if not.
			sample_file=$(cd "$repo" && \
				      find objects -type f -print | sed -e 1q)
			# objects directory should not be empty because
			# we are cloning!
			test -f "$repo/$sample_file" || exit
			if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
			then
				rm -f "$GIT_DIR/objects/sample"
				l=l
			elif test -n "$local_explicitly_asked_for"
			then
				echo >&2 "Warning: -l asked but cannot hardlink to $repo"
			fi
		fi &&
		cd "$repo" &&
		find objects -depth -print | cpio -pumd$l "$GIT_DIR/" || exit 1
	fi
	git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
	;;
*)
	case "$repo" in
	rsync://*)
		case "$depth" in
		"") ;;
		*) die "shallow over rsync not supported" ;;
		esac
		rsync $quiet -av --ignore-existing  \
			--exclude info "$repo/objects/" "$GIT_DIR/objects/" ||
		exit
		# Look at objects/info/alternates for rsync -- http will
		# support it natively and git native ones will do it on the
		# remote end.  Not having that file is not a crime.
		rsync -q "$repo/objects/info/alternates" \
			"$GIT_DIR/TMP_ALT" 2>/dev/null ||
			rm -f "$GIT_DIR/TMP_ALT"
		if test -f "$GIT_DIR/TMP_ALT"
		then
		    ( cd "$D" &&
		      . git-parse-remote &&
		      resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) |
		    while read alt
		    do
			case "$alt" in 'bad alternate: '*) die "$alt";; esac
			case "$quiet" in
			'')	echo >&2 "Getting alternate: $alt" ;;
			esac
			rsync $quiet -av --ignore-existing  \
			    --exclude info "$alt" "$GIT_DIR/objects" || exit
		    done
		    rm -f "$GIT_DIR/TMP_ALT"
		fi
		git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
		;;
	https://*|http://*|ftp://*)
		case "$depth" in
		"") ;;
		*) die "shallow over http or ftp not supported" ;;
		esac
		if test -z ""
		then
			clone_dumb_http "$repo" "$D"
		else
			die "http transport not supported, rebuild Git with curl support"
		fi
		;;
	*)
		case "$upload_pack" in
		'') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
		*) git-fetch-pack --all -k $quiet "$upload_pack" $depth $no_progress "$repo" ;;
		esac >"$GIT_DIR/CLONE_HEAD" ||
			die "fetch-pack from '$repo' failed."
		;;
	esac
	;;
esac
test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"

if test -f "$GIT_DIR/CLONE_HEAD"
then
	# Read git-fetch-pack -k output and store the remote branches.
	if [ -n "$use_separate_remote" ]
	then
		branch_top="remotes/$origin"
	else
		branch_top="heads"
	fi
	tag_top="tags"
	while read sha1 name
	do
		case "$name" in
		*'^{}')
			continue ;;
		HEAD)
			destname="REMOTE_HEAD" ;;
		refs/heads/*)
			destname="refs/$branch_top/${name#refs/heads/}" ;;
		refs/tags/*)
			destname="refs/$tag_top/${name#refs/tags/}" ;;
		*)
			continue ;;
		esac
		git update-ref -m "clone: from $repo" "$destname" "$sha1" ""
	done < "$GIT_DIR/CLONE_HEAD"
fi

if test -n "$W"; then
	cd "$W" || exit
else
	cd "$D" || exit
fi

if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD"
then
	# a non-bare repository is always in separate-remote layout
	remote_top="refs/remotes/$origin"
	head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"`
	case "$head_sha1" in
	'ref: refs/'*)
		# Uh-oh, the remote told us (http transport done against
		# new style repository with a symref HEAD).
		# Ideally we should skip the guesswork but for now
		# opt for minimum change.
		head_sha1=`expr "z$head_sha1" : 'zref: refs/heads/\(.*\)'`
		head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"`
		;;
	esac

	# The name under $remote_top the remote HEAD seems to point at.
	head_points_at=$(
		(
			test -f "$GIT_DIR/$remote_top/master" && echo "master"
			cd "$GIT_DIR/$remote_top" &&
			find . -type f -print | sed -e 's/^\.\///'
		) | (
		done=f
		while read name
		do
			test t = $done && continue
			branch_tip=`cat "$GIT_DIR/$remote_top/$name"`
			if test "$head_sha1" = "$branch_tip"
			then
				echo "$name"
				done=t
			fi
		done
		)
	)

	# Upstream URL
	git config remote."$origin".url "$repo" &&

	# Set up the mappings to track the remote branches.
	git config remote."$origin".fetch \
		"+refs/heads/*:$remote_top/*" '^$' &&

	# Write out remote.$origin config, and update our "$head_points_at".
	case "$head_points_at" in
	?*)
		# Local default branch
		git symbolic-ref HEAD "refs/heads/$head_points_at" &&

		# Tracking branch for the primary branch at the remote.
		git update-ref HEAD "$head_sha1" &&

		rm -f "refs/remotes/$origin/HEAD"
		git symbolic-ref "refs/remotes/$origin/HEAD" \
			"refs/remotes/$origin/$head_points_at" &&

		git config branch."$head_points_at".remote "$origin" &&
		git config branch."$head_points_at".merge "refs/heads/$head_points_at"
		;;
	'')
		# Source had detached HEAD pointing nowhere
		git update-ref --no-deref HEAD "$head_sha1" &&
		rm -f "refs/remotes/$origin/HEAD"
		;;
	esac

	case "$no_checkout" in
	'')
		test "z$quiet" = z -a "z$no_progress" = z && v=-v || v=
		git read-tree -m -u $v HEAD HEAD
	esac
fi
rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"

# The following section initializes the submodules of the repo
if [ $with_submodule -eq 1  ]; then
	if [ -f .gitmodules ]; then

		# Need to know either what is the alternate 
		# or what else to backup and unset
		# If this is not done in that case recursion 
		# in a subdirectory of the top level fails
		# Thus the old values are backed up and restored
		# after recursion
		OLD_GIT_DIR="$GIT_DIR"
		OLD_GIT_CONFIG="$GIT_CONFIG"
		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
		unset GIT_DIR
		unset GIT_CONFIG
		unset GIT_WORK_TREE

		# The following loop iterates over the submodules
		# visible from he top of the module
	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
                        initSubModules "$mod_path"
                done

		GIT_DIR="$OLD_GIT_DIR"
		GIT_CONFIG="$OLD_GIT_CONFIG"
		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"

		# The following export is probably not required
		export GIT_DIR
		export GIT_CONFIG
		export GIT_WORK_TREE
	fi
fi

trap - 0

[-- Attachment #3: git-clone-diff-1.5.3.7.txt --]
[-- Type: text/plain, Size: 2978 bytes --]

diff --git a/git-clone b/git-clone
index 204a769..63510c4 100755
--- a/git-clone
+++ b/git-clone
@@ -14,7 +14,7 @@ die() {
 }
 
 usage() {
-	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
+	die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-w|--with-submodule] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] <repo> [<dir>]"
 }
 
 get_repo_base() {
@@ -90,6 +90,29 @@ Perhaps git-update-server-info needs to be run there?"
 	fi
 }
 
+initializeSubModule() {
+	if [ ! -d "$1"/.git ]; then
+		git-submodule-test init "$1"; git-submodule-test update "$1"
+	fi
+}
+
+initSubModules() {
+	current_dir=`pwd`
+	dir_path="$current_dir:$dir_path"
+	initializeSubModule "$1"
+        cd "$1"
+	if [ -f .gitmodules ]; then
+                for sub_mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+			initSubModules "$sub_mod_path"
+                done
+        fi
+	old_dir=$(echo $dir_path | cut -d':' -f1-1)
+	length_old_dir=`expr "$old_dir" : '.*'`
+	cd $old_dir
+	index=$(echo "$length_old_dir+2" | bc)
+	dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'`
+}
+
 quiet=
 local=no
 use_local_hardlink=yes
@@ -106,6 +129,7 @@ depth=
 no_progress=
 local_explicitly_asked_for=
 test -t 1 || no_progress=--no-progress
+with_submodule=0
 while
 	case "$#,$1" in
 	0,*) break ;;
@@ -156,6 +180,7 @@ while
 		upload_pack="--upload-pack=$1" ;;
 	*,--upload-pack=*)
 		upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
+	*,-w|*,--w|*,--wi|*,--wit|*,--with|*,--with-s|*,--with-su|*,--with-sub|*,--with-subm|*,--with-submo|*,--with-submod|*,--with-submodu|*,--with-submodul|*,--with-submodule) with_submodule=1 ;;
 	1,--depth) usage;;
 	*,--depth)
 		shift
@@ -465,4 +490,38 @@ then
 fi
 rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
 
+# The following section initializes the submodules of the repo
+if [ $with_submodule -eq 1  ]; then
+	if [ -f .gitmodules ]; then
+
+		# Need to know either what is the alternate 
+		# or what else to backup and unset
+		# If this is not done in that case recursion 
+		# in a subdirectory of the top level fails
+		# Thus the old values are backed up and restored
+		# after recursion
+		OLD_GIT_DIR="$GIT_DIR"
+		OLD_GIT_CONFIG="$GIT_CONFIG"
+		OLD_GIT_WORK_TREE="$GIT_WORK_TREE"
+		unset GIT_DIR
+		unset GIT_CONFIG
+		unset GIT_WORK_TREE
+
+		# The following loop iterates over the submodules
+		# visible from he top of the module
+	        for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do
+                        initSubModules "$mod_path"
+                done
+
+		GIT_DIR="$OLD_GIT_DIR"
+		GIT_CONFIG="$OLD_GIT_CONFIG"
+		GIT_WORK_TREE="$OLD_GIT_WORK_TREE"
+
+		# The following export is probably not required
+		export GIT_DIR
+		export GIT_CONFIG
+		export GIT_WORK_TREE
+	fi
+fi
+
 trap - 0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] Added initialize and update support for submodule in git clone
  2008-01-08  3:22 [PATCH] Added initialize and update support for submodule in git clone Imran M Yousuf
@ 2008-01-08  6:19 ` Junio C Hamano
  2008-01-09  6:05   ` Imran M Yousuf
  0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2008-01-08  6:19 UTC (permalink / raw)
  To: Imran M Yousuf; +Cc: git

"Imran M Yousuf" <imyousuf@gmail.com> writes:

> This patch adds support for initializing and updating submodules when
> a repo is cloned. The advantage it adds is, the user actually does not
> have to know whether it has a module or not and if it does to what
> depth and path. For this I added a option -w or --with-submodule for
> initializing and updating during clone stage.

For everything else, I strongly agree [*1*] that the notion that
all subprojects are populated is a bug.  I am not convinced the
all-or-nothing approach you implemented in "git clone" is useful
outside small toy projects where all of your users are almost
always interested in everything (which inevitably invites a very
valid question: why use submodule at all then?), but in the very
narrow special case of "clone", all-or-nothing is the best you
can do without giving additional hints somewhere in-tree
(perhaps enhanced .gitmodules entries), and it certainly is
better than "you do not have any choice --- you only get the
toplevel".

> Following is the diff with git-clone 1.5.3.7; I also attached the diff
> and modified file in the attachment.

The same comment as diff plus attachment applies to this patch
as the other message.  Also please do not base new development
on 4-digit maintenance releases, which are meant to contain only
bugfixes and no new features.  A patch like this, primarily for
discussion and not for immediate inclusion, is Ok, but it is
better to get into the habit of producing applicable patches
earlier rather than later.

I'll step aside and let others discuss code and design of the
patch.

[Reference]

*1* http://thread.gmane.org/gmane.comp.version-control.git/44106/focus=44308

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Added initialize and update support for submodule in git clone
  2008-01-08  6:19 ` Junio C Hamano
@ 2008-01-09  6:05   ` Imran M Yousuf
  0 siblings, 0 replies; 3+ messages in thread
From: Imran M Yousuf @ 2008-01-09  6:05 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Thanks again Junio.

I will resend the patch with the latest code base. After implementing
I also felt that it is not logical to go all way down, so I was
thinking of adding -l | --level with -w or use --depth already in use;
that will add some flexibility; what do you thing about this? I will
make the similar changes you mentioned in the earlier email in this as
well.

I was actually concerned about unsetting and re-setting the
environment variables. Is there a alternate to it?

Thank you,

Imran

On Jan 8, 2008 12:19 PM, Junio C Hamano <gitster@pobox.com> wrote:
> "Imran M Yousuf" <imyousuf@gmail.com> writes:
>
> > This patch adds support for initializing and updating submodules when
> > a repo is cloned. The advantage it adds is, the user actually does not
> > have to know whether it has a module or not and if it does to what
> > depth and path. For this I added a option -w or --with-submodule for
> > initializing and updating during clone stage.
>
> For everything else, I strongly agree [*1*] that the notion that
> all subprojects are populated is a bug.  I am not convinced the
> all-or-nothing approach you implemented in "git clone" is useful
> outside small toy projects where all of your users are almost
> always interested in everything (which inevitably invites a very
> valid question: why use submodule at all then?), but in the very
> narrow special case of "clone", all-or-nothing is the best you
> can do without giving additional hints somewhere in-tree
> (perhaps enhanced .gitmodules entries), and it certainly is
> better than "you do not have any choice --- you only get the
> toplevel".
>
> > Following is the diff with git-clone 1.5.3.7; I also attached the diff
> > and modified file in the attachment.
>
> The same comment as diff plus attachment applies to this patch
> as the other message.  Also please do not base new development
> on 4-digit maintenance releases, which are meant to contain only
> bugfixes and no new features.  A patch like this, primarily for
> discussion and not for immediate inclusion, is Ok, but it is
> better to get into the habit of producing applicable patches
> earlier rather than later.
>
> I'll step aside and let others discuss code and design of the
> patch.
>
> [Reference]
>
> *1* http://thread.gmane.org/gmane.comp.version-control.git/44106/focus=44308
>



-- 
Imran M Yousuf
Entrepreneur & Software Engineer
Smart IT Engineering
Dhaka, Bangladesh
Email: imran@smartitengineering.com
Mobile: +880-1711402557

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-01-09  6:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-08  3:22 [PATCH] Added initialize and update support for submodule in git clone Imran M Yousuf
2008-01-08  6:19 ` Junio C Hamano
2008-01-09  6:05   ` Imran M Yousuf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).