From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:12
This command can be used to initialize, update and inspect submodules. It
uses a .gitmodules file, readable by git-config, in the top level directory
of the 'superproject' to specify a mapping between submodule paths and
repository url. There is currently no way to override the mappings in the
.gitmodules file, except by manually creating the subproject repository.
Example .gitmodules layout:
[module "git"]
url = git://git.kernel.org/pub/scm/git/git.git
Signed-off-by: Lars Hjemli <redacted>
---
On 5/24/07, Johannes Schindelin [off-list ref] wrote:
On Thu, 24 May 2007, Lars Hjemli wrote:
quoted
What I think would be nice is some porcelain support to manually init,
update and see the checked out version of selected subprojects, but as
standalone commands.
Yes, a la git-remote. I'd be much happier with that, too, especially since
I think that this can be a relatively small and easy-to-review script.
So, here it is. Please be kind :)
Btw: I've never managed to get asciidoc working on my machine, so the doc
isn't checked in any other format than plain text.
Documentation/git-submodule.txt | 49 ++++++++++++
Makefile | 2 +-
git-submodule.sh | 163 +++++++++++++++++++++++++++++++++++++++
3 files changed, 213 insertions(+), 1 deletions(-)
create mode 100644 Documentation/git-submodule.txt
create mode 100755 git-submodule.sh
@@ -0,0 +1,49 @@+git-submodule(1)+================++NAME+----+git-submodule - Initialize, update or inspect submodules+++SYNOPSIS+--------+'git-submodule' [--init | --update | --cached] [--quiet] <path>...++DESCRIPTION+-----------+The command shows the status of each specified submodule path, or all+submodules if none is specified. Each submodule sha1 is prefixed with '-'+if the submodule is uninitialized and '+' if the checked out version of+the submodule is different from the commit sha1 stored in the index.+++OPTIONS+-------+<path>::+ Path to submodule++-i, --init::+ Initialize the specified submodules, i.e. clone the git repository+ specified in .gitmodules and checkout the sha1 specified in the+ index.++-u, --update::+ Update the specified submodules, i.e. checkout the sha1 specified+ in the index++--cached::+ Display the sha1 stored in the index, not the currently checked+ out revsion.++-q, --quiet::+ Be quiet+++Author+------+Written by Lars Hjemli <hjemli@gmail.com>++GIT+---+Part of the gitlink:git[7] suite
@@ -0,0 +1,163 @@+#!/bin/sh+#+# git-submodule.sh: init, update or list git submodules+#+# Copyright (c) 2007 Lars Hjemli++USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'+.git-sh-setup+require_work_tree++init=+update=+quiet=+cached=++#+# print stuff on stdout unless -q was specified+#+say()+{+iftest-z"$quiet"+then+echo-e"$@"+fi+}++#+# Find all (requested) submodules, run clone + checkout on missing paths+#+# $@ = requested paths (default to all)+#+modules_init()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmodesha1stagepath+do+test-d"$path/.git"&&continue++iftest-d"$path"+then+rmdir"$path"2>/dev/null||+die"Directory '$path' exist, but not as a submodule"+fi++test-e"$path"&&+die"A file already exist at path '$path'"++url=$(GIT_CONFIG=.gitmodulesgit-configmodule."$path".url)+test-z"$url"&&+die"No url found for submodule '$path' in .gitmodules"++git-clone"$url""$path"||+die"Clone of submodule '$path' failed"++$(cd"$path"&&git-checkout-q"$sha1")||+die"Checkout of submodule '$path' failed"++say"Submodule '$path' initialized"+done+}++#+# Checkout correct revision of each initialized submodule+#+# $@ = requested paths (default to all)+#+modules_update()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmodesha1stagepath+do+if!test-d"$path/.git"+then+say"Submodule '$path' not initialized"+continue;+fi+subsha1=$(cd"$path"&&git-rev-parse--verifyHEAD)||+die"Unable to find current revision of submodule '$path'"++iftest"$subsha1"!="$sha1"+then+$(cd"$path"&&git-fetch&&git-checkout-q"$sha1")||+die"Unable to checkout revision $sha1 of submodule '$path'"++say"Submodule '$path' reset to revision $sha1"+fi+done+}++#+# List all registered submodules, prefixed with:+# - submodule not initialized+# + different version checked out+#+# If --cached was specified the revision in the index will be printed+# instead of the currently checked out revision.+#+# $@ = requested paths (default to all)+#+modules_list()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmodesha1stagepath+do+if!test-d"$path/.git"+then+say"-$sha1$path"+continue;+fi+revname=$(cd"$path"&&git-describe$sha1)+ifgitdiff-files--quiet--"$path"+then+say" $sha1$path\t($revname)"+else+iftest-z"$cached"+then+sha1=$(cd"$path"&&git-rev-parse--verifyHEAD)+revname=$(cd"$path"&&git-describe$sha1)+fi+say"+$sha1$path\t($revname)"+fi+done+}+++whilecase"$#"in0)break;;esac+do+case"$1"in+-i|--init)+init=1+;;+-u|--update)+update=1+;;+-q|--quiet)+quiet=1+;;+--cached)+cached=1+;;+--)+break+;;+-*)+usage+;;+*)+break+;;+esac+shift+done+++iftest"$init"="1"+then+modules_init$@+eliftest"$update"="1"+then+modules_update$@+else+modules_list$@+fi
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:12
Hi,
On Fri, 25 May 2007, Lars Hjemli wrote:
On 5/24/07, Johannes Schindelin [off-list ref] wrote:
quoted
On Thu, 24 May 2007, Lars Hjemli wrote:
quoted
What I think would be nice is some porcelain support to manually init,
update and see the checked out version of selected subprojects, but as
standalone commands.
Yes, a la git-remote. I'd be much happier with that, too, especially since
I think that this can be a relatively small and easy-to-review script.
So, here it is. Please be kind :)
Thank you very much! And it looks small enough that I will review it right
away.
Btw: I've never managed to get asciidoc working on my machine, so the doc
isn't checked in any other format than plain text.
@@ -0,0 +1,163 @@+#!/bin/sh+#+# git-submodule.sh: init, update or list git submodules+#+# Copyright (c) 2007 Lars Hjemli++USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'+.git-sh-setup+require_work_tree++init=+update=+quiet=+cached=++#+# print stuff on stdout unless -q was specified+#+say()+{+iftest-z"$quiet"+then+echo-e"$@"+fi+}++#+# Find all (requested) submodules, run clone + checkout on missing paths+#+# $@ = requested paths (default to all)+#+modules_init()+{+gitls-files--stage--$@|grep-e'^160000 '|
Any reason you read in the stage? It does not seem that you use it.
+ while read mode sha1 stage path
+ do
+ test -d "$path/.git" && continue
+
+ if test -d "$path"
+ then
+ rmdir "$path" 2>/dev/null ||
+ die "Directory '$path' exist, but not as a submodule"
+ fi
+
+ test -e "$path" &&
+ die "A file already exist at path '$path'"
+
+ url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
I like that command ;-)
+ test -z "$url" &&
+ die "No url found for submodule '$path' in .gitmodules"
+
+ git-clone "$url" "$path" ||
+ die "Clone of submodule '$path' failed"
+
+ $(cd "$path" && git-checkout -q "$sha1") ||
+ die "Checkout of submodule '$path' failed"
+
+ say "Submodule '$path' initialized"
+ done
+}
+
+#
+# Checkout correct revision of each initialized submodule
+#
+# $@ = requested paths (default to all)
+#
+modules_update()
+{
+ git ls-files --stage -- $@ | grep -e '^160000 ' |
Same here.
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path/.git"
+ then
+ say "Submodule '$path' not initialized"
+ continue;
+ fi
+ subsha1=$(cd "$path" && git-rev-parse --verify HEAD) ||
Maybe it would be a better idea to use "git --git-dir="$path" rev-parse
..."? Just in case somebody calls this with GIT_DIR overridden...
Or, unset GIT_DIR explicitely.
+ die "Unable to find current revision of submodule '$path'"
+
+ if test "$subsha1" != "$sha1"
+ then
+ $(cd "$path" && git-fetch && git-checkout -q "$sha1") ||
This will make a detached HEAD, right? Do you want that? (I am not really
interested in submodules myself, so I haven't thought about it, and I
haven't followed that monster discussion.)
+ die "Unable to checkout revision $sha1 of submodule '$path'"
+
+ say "Submodule '$path' reset to revision $sha1"
I'd rather not say "reset", since this has a different meaning in Git, but
rather "set to revision $sha1".
+ fi
+ done
+}
+
+#
+# List all registered submodules, prefixed with:
+# - submodule not initialized
+# + different version checked out
+#
+# If --cached was specified the revision in the index will be printed
+# instead of the currently checked out revision.
+#
+# $@ = requested paths (default to all)
+#
+modules_list()
+{
+ git ls-files --stage -- $@ | grep -e '^160000 ' |
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path/.git"
+ then
+ say "-$sha1 $path"
+ continue;
+ fi
+ revname=$(cd "$path" && git-describe $sha1)
+ if git diff-files --quiet -- "$path"
+ then
+ say " $sha1 $path\t($revname)"
+ else
+ if test -z "$cached"
+ then
+ sha1=$(cd "$path" && git-rev-parse --verify HEAD)
+ revname=$(cd "$path" && git-describe $sha1)
+ fi
+ say "+$sha1 $path\t($revname)"
+ fi
+ done
+}
+
+
+while case "$#" in 0) break ;; esac
+do
+ case "$1" in
+ -i|--init)
+ init=1
+ ;;
+ -u|--update)
+ update=1
+ ;;
+ -q|--quiet)
+ quiet=1
+ ;;
+ --cached)
+ cached=1
+ ;;
+ --)
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+
+if test "$init" = "1"
+then
+ modules_init $@
+elif test "$update" = "1"
+then
+ modules_update $@
+else
+ modules_list $@
+fi
I'll let Junio comment on that command line parsing...
All in all, I like it: it is short, to the point, and it should do the job
(maybe with a few enhancements like "--update" without arguments means
_all_ submodules).
Ciao,
Dscho
@@ -0,0 +1,163 @@+#!/bin/sh+#+# git-submodule.sh: init, update or list git submodules+#+# Copyright (c) 2007 Lars Hjemli++USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'+.git-sh-setup+require_work_tree++init=+update=+quiet=+cached=++#+# print stuff on stdout unless -q was specified+#+say()+{+iftest-z"$quiet"+then+echo-e"$@"+fi+}++#+# Find all (requested) submodules, run clone + checkout on missing paths+#+# $@ = requested paths (default to all)+#+modules_init()+{+gitls-files--stage--$@|grep-e'^160000 '|
Any reason you read in the stage? It does not seem that you use it.
Are there any other way to get the mode info?
quoted
+ while read mode sha1 stage path
+ do
+ test -d "$path/.git" && continue
+
+ if test -d "$path"
+ then
+ rmdir "$path" 2>/dev/null ||
+ die "Directory '$path' exist, but not as a submodule"
+ fi
+
+ test -e "$path" &&
+ die "A file already exist at path '$path'"
+
+ url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
I like that command ;-)
quoted
+ test -z "$url" &&
+ die "No url found for submodule '$path' in .gitmodules"
+
+ git-clone "$url" "$path" ||
+ die "Clone of submodule '$path' failed"
+
+ $(cd "$path" && git-checkout -q "$sha1") ||
+ die "Checkout of submodule '$path' failed"
+
+ say "Submodule '$path' initialized"
+ done
+}
+
+#
+# Checkout correct revision of each initialized submodule
+#
+# $@ = requested paths (default to all)
+#
+modules_update()
+{
+ git ls-files --stage -- $@ | grep -e '^160000 ' |
Same here.
quoted
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path/.git"
+ then
+ say "Submodule '$path' not initialized"
+ continue;
+ fi
+ subsha1=$(cd "$path" && git-rev-parse --verify HEAD) ||
Maybe it would be a better idea to use "git --git-dir="$path" rev-parse
..."? Just in case somebody calls this with GIT_DIR overridden...
Or, unset GIT_DIR explicitely.
Hmm, that's annoying (overridden GIT_DIR). I guess 'git --git-dir
$path/.git' would be the easiest solution.
quoted
+ die "Unable to find current revision of submodule '$path'"
+
+ if test "$subsha1" != "$sha1"
+ then
+ $(cd "$path" && git-fetch && git-checkout -q "$sha1") ||
This will make a detached HEAD, right? Do you want that? (I am not really
interested in submodules myself, so I haven't thought about it, and I
haven't followed that monster discussion.)
Well, we might want to be smarter about this, but on the other hand:
if the user cares, he can always do 'cd $path && git checkout
$branch', since 'git submodule -u' will skip submodules with the
correct commit checked out.
quoted
+ die "Unable to checkout revision $sha1 of submodule '$path'"
+
+ say "Submodule '$path' reset to revision $sha1"
I'd rather not say "reset", since this has a different meaning in Git, but
rather "set to revision $sha1".
Ok.
quoted
+ fi
+ done
+}
+
+#
+# List all registered submodules, prefixed with:
+# - submodule not initialized
+# + different version checked out
+#
+# If --cached was specified the revision in the index will be printed
+# instead of the currently checked out revision.
+#
+# $@ = requested paths (default to all)
+#
+modules_list()
+{
+ git ls-files --stage -- $@ | grep -e '^160000 ' |
+ while read mode sha1 stage path
+ do
+ if ! test -d "$path/.git"
+ then
+ say "-$sha1 $path"
+ continue;
+ fi
+ revname=$(cd "$path" && git-describe $sha1)
+ if git diff-files --quiet -- "$path"
+ then
+ say " $sha1 $path\t($revname)"
+ else
+ if test -z "$cached"
+ then
+ sha1=$(cd "$path" && git-rev-parse --verify HEAD)
+ revname=$(cd "$path" && git-describe $sha1)
+ fi
+ say "+$sha1 $path\t($revname)"
+ fi
+ done
+}
+
+
+while case "$#" in 0) break ;; esac
+do
+ case "$1" in
+ -i|--init)
+ init=1
+ ;;
+ -u|--update)
+ update=1
+ ;;
+ -q|--quiet)
+ quiet=1
+ ;;
+ --cached)
+ cached=1
+ ;;
+ --)
+ break
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+
+if test "$init" = "1"
+then
+ modules_init $@
+elif test "$update" = "1"
+then
+ modules_update $@
+else
+ modules_list $@
+fi
I'll let Junio comment on that command line parsing...
Heh, I'm a shell illiterate...
All in all, I like it: it is short, to the point, and it should do the job
(maybe with a few enhancements like "--update" without arguments means
_all_ submodules).
Well, it does (or should) update all initialized submodules, but maybe
that's not what you meant?
Thanks for the review!
--
larsh
Maybe it would be a better idea to use "git --git-dir="$path"
rev-parse ..."? Just in case somebody calls this with GIT_DIR
overridden...
Or, unset GIT_DIR explicitely.
Hmm, that's annoying (overridden GIT_DIR). I guess 'git --git-dir
$path/.git' would be the easiest solution.
But you have to repeat it on every subsequent Git command. OTOH if you
unset GIT_DIR, you can no longer be sure that you have the correct git dir
for Git calls in the superproject...
quoted
quoted
+ die "Unable to find current revision of submodule '$path'"
+
+ if test "$subsha1" != "$sha1"
+ then
+ $(cd "$path" && git-fetch && git-checkout -q
"$sha1") ||
This will make a detached HEAD, right? Do you want that? (I am not
really interested in submodules myself, so I haven't thought about it,
and I haven't followed that monster discussion.)
Well, we might want to be smarter about this, but on the other hand: if
the user cares, he can always do 'cd $path && git checkout $branch',
since 'git submodule -u' will skip submodules with the correct commit
checked out.
Fair enough, I guess...
quoted
I'll let Junio comment on that command line parsing...
Heh, I'm a shell illiterate...
;-)
I guess Junio would like one of his famous
case ,"$init","$update",[...] in
*1*1) usage
esac
to prevent running with two actions...
quoted
All in all, I like it: it is short, to the point, and it should do the
job (maybe with a few enhancements like "--update" without arguments
means _all_ submodules).
Well, it does (or should) update all initialized submodules, but maybe
that's not what you meant?
Oops. I meant "init". I mean, most people who want to clone a superproject
want the submodules being initialized without hassles, probably. But maybe
that should be another option: "--clone-superproject" or something. Dunno.
There's time for that after the initial git-submodule.
Ciao,
Dscho
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:12
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
On Fri, 25 May 2007, Lars Hjemli wrote:
quoted
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
quoted
On Fri, 25 May 2007, Lars Hjemli wrote:
quoted
+ die "Unable to find current revision of submodule '$path'"
+
+ if test "$subsha1" != "$sha1"
+ then
+ $(cd "$path" && git-fetch && git-checkout -q
"$sha1") ||
This will make a detached HEAD, right? Do you want that? (I am not
really interested in submodules myself, so I haven't thought about it,
and I haven't followed that monster discussion.)
Well, we might want to be smarter about this, but on the other hand: if
the user cares, he can always do 'cd $path && git checkout $branch',
since 'git submodule -u' will skip submodules with the correct commit
checked out.
Fair enough, I guess...
The only alternative I can think of is to check if module.$path.branch
is specified in .gitmodules: if it is, and it's pointing at the wanted
sha1, the right thing would be to checkout that branch. Any other sort
of dwim is bound to get it wrong.
quoted
quoted
I'll let Junio comment on that command line parsing...
Heh, I'm a shell illiterate...
;-)
I guess Junio would like one of his famous
case ,"$init","$update",[...] in
*1*1) usage
esac
to prevent running with two actions...
Ahh, that's something I can handle
quoted
quoted
All in all, I like it: it is short, to the point, and it should do the
job (maybe with a few enhancements like "--update" without arguments
means _all_ submodules).
Well, it does (or should) update all initialized submodules, but maybe
that's not what you meant?
Oops. I meant "init".
Hmm, it does (or should) clone all submodules if you run 'git
submodule --init' (no paths specified). Did it fail for you?
--
larsh
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:12
Hi,
On Fri, 25 May 2007, Lars Hjemli wrote:
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
quoted
On Fri, 25 May 2007, Lars Hjemli wrote:
quoted
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
quoted
All in all, I like it: it is short, to the point, and it should do
the job (maybe with a few enhancements like "--update" without
arguments means _all_ submodules).
Well, it does (or should) update all initialized submodules, but
maybe that's not what you meant?
Oops. I meant "init".
Hmm, it does (or should) clone all submodules if you run 'git submodule
--init' (no paths specified). Did it fail for you?
I don't have any superproject to try with ;-)
Actually, I missed the "$@" in modules_init. You might want to change the
documentation, though, since it suggests (at least to yours truly) that
you _need_ to pass a path with "--init".
Even happier,
Dscho
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:12
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
Hi,
On Fri, 25 May 2007, Lars Hjemli wrote:
quoted
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
quoted
On Fri, 25 May 2007, Lars Hjemli wrote:
quoted
On 5/25/07, Johannes Schindelin [off-list ref] wrote:
quoted
All in all, I like it: it is short, to the point, and it should do
the job (maybe with a few enhancements like "--update" without
arguments means _all_ submodules).
Well, it does (or should) update all initialized submodules, but
maybe that's not what you meant?
Oops. I meant "init".
Hmm, it does (or should) clone all submodules if you run 'git submodule
--init' (no paths specified). Did it fail for you?
I don't have any superproject to try with ;-)
You could always try cgit ;-)
Actually, I missed the "$@" in modules_init. You might want to change the
documentation, though, since it suggests (at least to yours truly) that
you _need_ to pass a path with "--init".
From: Lars Hjemli <hidden> Date: 2016-06-15 22:43:12
This command can be used to initialize, update and inspect submodules. It
uses a .gitmodules file, readable by git-config, in the top level directory
of the 'superproject' to specify a mapping between submodule paths and
repository url. There is currently no way to override the mappings in the
.gitmodules file, except by manually creating the subproject repository.
Example .gitmodules layout:
[module "git"]
url = git://git.kernel.org/pub/scm/git/git.git
branch = maint
The branch-key in .gitmodules is optional. When specified, 'git-submodule -u'
will checkout the named branch if its tip matches the commit-sha1 in the
superprojects index. Otherwise, 'git-submodule -u' will create a detached
HEAD in the submodule.
Signed-off-by: Lars Hjemli <redacted>
---
This is an updated patch that hopefully deals with all the previous issues.
I've also added support for specifying module.$path.branch in .gitmodules,
but not support for general url rewriting based on local config. If that
is a wanted feature, it should be trivial to add later on.
Btw: testing this quickly becomes tedious, so I'll try to make a proper
testscript later tonight.
Documentation/git-submodule.txt | 63 ++++++++++++++
Makefile | 2 +-
git-submodule.sh | 178 +++++++++++++++++++++++++++++++++++++++
3 files changed, 242 insertions(+), 1 deletions(-)
create mode 100644 Documentation/git-submodule.txt
create mode 100755 git-submodule.sh
@@ -0,0 +1,63 @@+git-submodule(1)+================++NAME+----+git-submodule - Initialize, update or inspect submodules+++SYNOPSIS+--------+'git-submodule' [--init | --update | --cached] [--quiet] [--] [<path>...]+++DESCRIPTION+-----------+The command shows the status of each specified submodule path, or all+submodules if none is specified. Each submodule sha1 is prefixed with '-'+if the submodule is uninitialized and '+' if the checked out version of+the submodule is different from the commit sha1 stored in the index.+++OPTIONS+-------+<path>::+ Path to submodule(s)++-i, --init::+ Initialize the specified submodules, i.e. clone the git repository+ specified in .gitmodules and checkout the sha1 specified in the+ index.++-u, --update::+ Update the specified submodules, i.e. checkout the sha1 specified+ in the index++--cached::+ Display the sha1 stored in the index, not the currently checked+ out revsion.++-q, --quiet::+ Be quiet+++FILES+-----+When cloning submodules, a .gitmodules file in the top-level directory+of the containing work-tree is examined for the url of each submodule.+The url is the value of the key module.$path.url.++When updating submodules, the same .gitmodules file is examined for a key+named 'module.$path.branch'. If found, and if the named branch is currently+at the same revision as the commit-id in the containing repositories index,+the specified branch will be checked out in the submodule. If not found, or+if the branch isn't currently positioned at the wanted revision, a checkout+of the wanted sha1 will happen in the submodule, leaving its HEAD detached.++Author+------+Written by Lars Hjemli <hjemli@gmail.com>++GIT+---+Part of the gitlink:git[7] suite
@@ -0,0 +1,178 @@+#!/bin/sh+#+# git-submodules.sh: init, update or list git submodules+#+# Copyright (c) 2007 Lars Hjemli++USAGE='[--init | --update | --cached] [--quiet] [--] [<path>...]'+.git-sh-setup+require_work_tree++init=+update=+quiet=+cached=++#+# print stuff on stdout unless -q was specified+#+say()+{+iftest-z"$quiet"+then+echo-e"$@"+fi+}++#+# Run clone + checkout on missing submodules+#+# $@ = requested paths (default to all)+#+modules_init()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmodesha1stagepath+do+test-d"$path/.git"&&continue++iftest-d"$path"+then+rmdir"$path"2>/dev/null||+die"Directory '$path' exist, but not as a submodule"+fi++test-e"$path"&&+die"A file already exist at path '$path'"++url=$(GIT_CONFIG=.gitmodulesgit-configmodule."$path".url)+test-z"$url"&&+die"No url found for submodule '$path' in .gitmodules"++git-clone"$url""$path"||+die"Clone of submodule '$path' failed"++$(unsetGIT_DIR&&cd"$path"&&git-checkout-q"$sha1")||+die"Checkout of submodule '$path' failed"++say"Submodule '$path' initialized"+done+}++#+# Checkout correct revision of each initialized submodule+#+# $@ = requested paths (default to all)+#+modules_update()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmoderevstagepath+do+if!test-d"$path/.git"+then+say"Submodule '$path' not initialized"+continue;+fi+subsha1=$(unsetGIT_DIR&&cd"$path"&&git-rev-parse--verifyHEAD)||+die"Unable to find current revision of submodule '$path'"++iftest"$subsha1"!="$rev"+then+$(unsetGIT_DIR&&cd"$path"&&git-fetch)+branch=$(GIT_CONFIG=.gitmodulesgit-configmodule."$path".branch)+iftest"$branch"!=""+then+branch_sha1=$(unsetGIT_DIR&&cd"$path"&&+git-rev-parse--verify"$branch")+iftest"$branch_sha1"="$rev"+then+rev="$branch"+fi+fi+$(unsetGIT_DIR&&cd"$path"&&git-checkout-q"$rev")||+die"Unable to checkout '$rev' in submodule '$path'"++say"Submodule '$path': checked out '$rev'"+fi+done+}++#+# List all registered submodules, prefixed with:+# - submodule not initialized+# + different version checked out+#+# If --cached was specified the revision in the index will be printed+# instead of the currently checked out revision.+#+# $@ = requested paths (default to all)+#+modules_list()+{+gitls-files--stage--$@|grep-e'^160000 '|+whilereadmodesha1stagepath+do+if!test-d"$path/.git"+then+say"-$sha1$path"+continue;+fi+revname=$(unsetGIT_DIR&&cd"$path"&&git-describe$sha1)+ifgitdiff-files--quiet--"$path"+then+say" $sha1$path\t($revname)"+else+iftest-z"$cached"+then+sha1=$(unsetGIT_DIR&&cd"$path"&&git-rev-parse--verifyHEAD)+revname=$(unsetGIT_DIR&&cd"$path"&&git-describe$sha1)+fi+say"+$sha1$path\t($revname)"+fi+done+}+++whilecase"$#"in0)break;;esac+do+case"$1"in+-i|--init)+init=1+;;+-u|--update)+update=1+;;+-q|--quiet)+quiet=1+;;+--cached)+cached=1+;;+--)+break+;;+-*)+usage+;;+*)+break+;;+esac+shift+done++case"$init,$update,$cached"in+1,,)+modules_init$@+;;+,1,)+modules_update$@+;;+,,*)+modules_list$@+;;+*)+usage+;;+esac
I did not realize this earlier, but we seem to have more and more programs
where actions are specified without "--", i.e. "git-svn fetch", or
"git-bundle create".
I actually like that, to separate actions from options. Hmm?
+-i, --init::
+ Initialize the specified submodules, i.e. clone the git repository
+ specified in .gitmodules and checkout the sha1 specified in the
+ index.
How about "Initialize the submodules...", and then another sentence "If
you do not want to initialize all submodules, you can specify the subset
to initialize"?
+-u, --update::
+ Update the specified submodules, i.e. checkout the sha1 specified
+ in the index
The full stop is missing here. And again, I would add another sentence
"Submodules which have not been initialized are not touched by this
operation."
+FILES
+-----
+When cloning submodules, a .gitmodules file in the top-level directory
+of the containing work-tree is examined for the url of each submodule.
+The url is the value of the key module.$path.url.
IIRC Junio talked about a name for overriding. But I think it would be
even better to to override by mapping the URLs from .gitmodules to the
locally-wanted URLs.
Junio?
+When updating submodules, the same .gitmodules file is examined for a key
+named 'module.$path.branch'. If found, and if the named branch is currently
+at the same revision as the commit-id in the containing repositories index,
+the specified branch will be checked out in the submodule. If not found, or
+if the branch isn't currently positioned at the wanted revision, a checkout
+of the wanted sha1 will happen in the submodule, leaving its HEAD detached.
A very good description, and I think this is the only method to checkout
the submodule which makes sense. (Just maybe default the value of
module.<path>.branch to "master"?)
quoted hunk
+++ b/git-submodule.sh
@@ -0,0 +1,178 @@+#!/bin/sh+#+# git-submodules.sh: init, update or list git submodules+#+# Copyright (c) 2007 Lars Hjemli++USAGE='[--init | --update | --cached] [--quiet] [--] [<path>...]'+.git-sh-setup+require_work_tree
Maybe
test -f "$GIT_DIR"/.gitmodules || die "Not a superproject"
Hmm?
+ rmdir "$path" 2>/dev/null ||
Just out of curiousity: is rmdir portable? I always used "rm -r"...
+case "$init,$update,$cached" in
+1,,)
+ modules_init $@
+ ;;
I did not realize this earlier, but we seem to have more and more programs
where actions are specified without "--", i.e. "git-svn fetch", or
"git-bundle create".
Hey, don't forget "git bisect", the granddaddy of them all.
I actually like that, to separate actions from options. Hmm?
I agree. If something effectively always takes a separate command, it's
not an option, it's a subcommand.
Linus
From: Johannes Schindelin <hidden> Date: 2016-06-15 22:43:12
Hi,
On Fri, 25 May 2007, Linus Torvalds wrote:
On Fri, 25 May 2007, Johannes Schindelin wrote:
quoted
I did not realize this earlier, but we seem to have more and more programs
where actions are specified without "--", i.e. "git-svn fetch", or
"git-bundle create".
Hey, don't forget "git bisect", the granddaddy of them all.
Oh, sorry! How could I? Respect the elders. ;-)
Ciao,
Dscho
Maybe
test -f "$GIT_DIR"/.gitmodules || die "Not a superproject"
Hmm?
Yeah, maybe. But the command will only touch entries with mode 160000
anyway, so it might not be a big deal.
quoted
+ rmdir "$path" 2>/dev/null ||
Just out of curiousity: is rmdir portable? I always used "rm -r"...
I have no idea, really. But the reason for using rmdir was this
section of the man page:
NAME
rmdir - remove empty directories
I do not want to delete an unempty directory. But there is probably
some better way to do this?
--
larsh