threads / patch / 11519

patchAdded initialize and update support for submodule in git clone

Subject: [PATCH] Added initialize and update support for submodule in git clone

## tl;dr

3 messages between Jan 8, 2008 and Jan 9, 2008. Diffs are folded; open one to read it.

replies: 2people: 2as markdown or json

Imran M Yousuf· Jan 8, 2008, 03:22 UTC · lore

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.

Show changes to git-clone +60 −1
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


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
Junio C Hamano· Jan 8, 2008, 06:19 UTC · re: Imran M Yousuf · lore

Re: [PATCH] Added initialize and update support for submodule in git clone

"Imran M Yousuf" <imyousuf@gmail.com> writes:
Show 5 quoted lines
> 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· Jan 9, 2008, 06:05 UTC · re: Junio C Hamano · lore

Re: [PATCH] Added initialize and update support for submodule in git clone

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:
Show 38 quoted lines
> "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

← back to recent threads