{"thread":{"id":"8311","subject":"[PATCH] Add git-submodule command","startedAt":"2007-05-25T09:51:04Z","lastAt":"2007-05-26T14:48:02Z","messageCount":26,"participants":["Lars Hjemli","Johannes Schindelin","Junio C Hamano","Linus Torvalds","Simon Hausmann"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"43224","messageId":"11800866643203-git-send-email-hjemli@gmail.com","threadId":"8311","inReplyTo":null,"subject":"[PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T09:51:04Z","receivedAt":"2007-05-25T09:51:04Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This command can be used to initialize, update and inspect submodules. It\nuses a .gitmodules file, readable by git-config, in the top level directory\nof the 'superproject' to specify a mapping between submodule paths and\nrepository url. There is currently no way to override the mappings in the\n.gitmodules file, except by manually creating the subproject repository.\n\nExample .gitmodules layout:\n\n[module \"git\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nOn 5/24/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> On Thu, 24 May 2007, Lars Hjemli wrote:\n> > What I think would be nice is some porcelain support to manually init,\n> > update and see the checked out version of selected subprojects, but as\n> > standalone commands.\n>\n> Yes, a la git-remote. I'd be much happier with that, too, especially since\n> I think that this can be a relatively small and easy-to-review script.\n\nSo, here it is. Please be kind :)\n\nBtw: I've never managed to get asciidoc working on my machine, so the doc\nisn't checked in any other format than plain text.\n\n\n Documentation/git-submodule.txt |   49 ++++++++++++\n Makefile                        |    2 +-\n git-submodule.sh                |  163 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 213 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-submodule.txt\n create mode 100755 git-submodule.sh\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nnew file mode 100644\nindex 0000000..6ec917c\n--- /dev/null\n+++ b/Documentation/git-submodule.txt\n@@ -0,0 +1,49 @@\n+git-submodule(1)\n+================\n+\n+NAME\n+----\n+git-submodule - Initialize, update or inspect submodules\n+\n+\n+SYNOPSIS\n+--------\n+'git-submodule' [--init | --update | --cached] [--quiet] <path>...\n+\n+DESCRIPTION\n+-----------\n+The command shows the status of each specified submodule path, or all\n+submodules if none is specified. Each submodule sha1 is prefixed with '-'\n+if the submodule is uninitialized and '+' if the checked out version of\n+the submodule is different from the commit sha1 stored in the index.\n+\n+\n+OPTIONS\n+-------\n+<path>::\n+\tPath to submodule\n+\n+-i, --init::\n+\tInitialize the specified submodules, i.e. clone the git repository\n+\tspecified in .gitmodules and checkout the sha1 specified in the\n+\tindex.\n+\n+-u, --update::\n+\tUpdate the specified submodules, i.e. checkout the sha1 specified\n+\tin the index\n+\n+--cached::\n+\tDisplay the sha1 stored in the index, not the currently checked\n+\tout revsion.\n+\n+-q, --quiet::\n+\tBe quiet\n+\n+\n+Author\n+------\n+Written by Lars Hjemli <hjemli@gmail.com>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\ndiff --git a/Makefile b/Makefile\nindex 29243c6..5cf2169 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -209,7 +209,7 @@ SCRIPT_SH = \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n-\tgit-lost-found.sh git-quiltimport.sh\n+\tgit-lost-found.sh git-quiltimport.sh git-submodule.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\ndiff --git a/git-submodule.sh b/git-submodule.sh\nnew file mode 100755\nindex 0000000..c4a1cc3\n--- /dev/null\n+++ b/git-submodule.sh\n@@ -0,0 +1,163 @@\n+#!/bin/sh\n+#\n+# git-submodule.sh: init, update or list git submodules\n+#\n+# Copyright (c) 2007 Lars Hjemli\n+\n+USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'\n+. git-sh-setup\n+require_work_tree\n+\n+init=\n+update=\n+quiet=\n+cached=\n+\n+#\n+# print stuff on stdout unless -q was specified\n+#\n+say()\n+{\n+\tif test -z \"$quiet\"\n+\tthen\n+\t\techo -e \"$@\"\n+\tfi\n+}\n+\n+#\n+# Find all (requested) submodules, run clone + checkout on missing paths\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_init()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\ttest -d \"$path/.git\" && continue\n+\n+\t\tif test -d \"$path\"\n+\t\tthen\n+\t\t\trmdir \"$path\" 2>/dev/null ||\n+\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n+\t\tfi\n+\n+\t\ttest -e \"$path\" &&\n+\t\tdie \"A file already exist at path '$path'\"\n+\n+\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n+\t\ttest -z \"$url\" &&\n+\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n+\n+\t\tgit-clone \"$url\" \"$path\" ||\n+\t\tdie \"Clone of submodule '$path' failed\"\n+\n+\t\t$(cd \"$path\" && git-checkout -q \"$sha1\") ||\n+\t\tdie \"Checkout of submodule '$path' failed\"\n+\n+\t\tsay \"Submodule '$path' initialized\"\n+\tdone\n+}\n+\n+#\n+# Checkout correct revision of each initialized submodule\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_update()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"Submodule '$path' not initialized\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\tsubsha1=$(cd \"$path\" && git-rev-parse --verify HEAD) ||\n+\t\tdie \"Unable to find current revision of submodule '$path'\"\n+\n+\t\tif test \"$subsha1\" != \"$sha1\"\n+\t\tthen\n+\t\t\t$(cd \"$path\" && git-fetch && git-checkout -q \"$sha1\") ||\n+\t\t\tdie \"Unable to checkout revision $sha1 of submodule '$path'\"\n+\n+\t\t\tsay \"Submodule '$path' reset to revision $sha1\"\n+\t\tfi\n+\tdone\n+}\n+\n+#\n+# List all registered submodules, prefixed with:\n+#  - submodule not initialized\n+#  + different version checked out\n+#\n+# If --cached was specified the revision in the index will be printed\n+# instead of the currently checked out revision.\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_list()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"-$sha1 $path\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\trevname=$(cd \"$path\" && git-describe $sha1)\n+\t\tif git diff-files --quiet -- \"$path\"\n+\t\tthen\n+\t\t\tsay \" $sha1 $path\\t($revname)\"\n+\t\telse\n+\t\t\tif test -z \"$cached\"\n+\t\t\tthen\n+\t\t\t\tsha1=$(cd \"$path\" && git-rev-parse --verify HEAD)\n+\t\t\t\trevname=$(cd \"$path\" && git-describe $sha1)\n+\t\t\tfi\n+\t\t\tsay \"+$sha1 $path\\t($revname)\"\n+\t\tfi\n+\tdone\n+}\n+\n+\n+while case \"$#\" in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\t-i|--init)\n+\t\tinit=1\n+\t\t;;\n+\t-u|--update)\n+\t\tupdate=1\n+\t\t;;\n+\t-q|--quiet)\n+\t\tquiet=1\n+\t\t;;\n+\t--cached)\n+\t\tcached=1\n+\t\t;;\n+\t--)\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+\n+\n+if test \"$init\" = \"1\"\n+then\n+\tmodules_init $@\n+elif test \"$update\" = \"1\"\n+then\n+\tmodules_update $@\n+else\n+\tmodules_list $@\n+fi\n-- \n1.5.2.73.g18bece-dirty\n"},{"id":"43232","messageId":"Pine.LNX.4.64.0705251155510.4648@racer.site","threadId":"8311","inReplyTo":"11800866643203-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T10:57:16Z","receivedAt":"2007-05-25T10:57:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Lars Hjemli wrote:\n\n> On 5/24/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > On Thu, 24 May 2007, Lars Hjemli wrote:\n> > > What I think would be nice is some porcelain support to manually init,\n> > > update and see the checked out version of selected subprojects, but as\n> > > standalone commands.\n> >\n> > Yes, a la git-remote. I'd be much happier with that, too, especially since\n> > I think that this can be a relatively small and easy-to-review script.\n> \n> So, here it is. Please be kind :)\n\nThank you very much! And it looks small enough that I will review it right \naway.\n\n> Btw: I've never managed to get asciidoc working on my machine, so the doc\n> isn't checked in any other format than plain text.\n\nNo problem, I will check that.\n\nCiao,\nDscho\n"},{"id":"43239","messageId":"Pine.LNX.4.64.0705251157450.4648@racer.site","threadId":"8311","inReplyTo":"11800866643203-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T12:24:55Z","receivedAt":"2007-05-25T12:24:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Lars Hjemli wrote:\n\n> There is currently no way to override the mappings in the .gitmodules \n> file, except by manually creating the subproject repository.\n\nI think that is okay. We can add that easily at a later stage, and the \nscript is much easier without that logic.\n\n> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n\nLooks good here, I checked with asciidoc.\n\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> new file mode 100755\n> index 0000000..c4a1cc3\n> --- /dev/null\n> +++ b/git-submodule.sh\n> @@ -0,0 +1,163 @@\n> +#!/bin/sh\n> +#\n> +# git-submodule.sh: init, update or list git submodules\n> +#\n> +# Copyright (c) 2007 Lars Hjemli\n> +\n> +USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'\n> +. git-sh-setup\n> +require_work_tree\n> +\n> +init=\n> +update=\n> +quiet=\n> +cached=\n> +\n> +#\n> +# print stuff on stdout unless -q was specified\n> +#\n> +say()\n> +{\n> +\tif test -z \"$quiet\"\n> +\tthen\n> +\t\techo -e \"$@\"\n> +\tfi\n> +}\n> +\n> +#\n> +# Find all (requested) submodules, run clone + checkout on missing paths\n> +#\n> +# $@ = requested paths (default to all)\n> +#\n> +modules_init()\n> +{\n> +\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n\nAny reason you read in the stage? It does not seem that you use it.\n\n> +\twhile read mode sha1 stage path\n> +\tdo\n> +\t\ttest -d \"$path/.git\" && continue\n> +\n> +\t\tif test -d \"$path\"\n> +\t\tthen\n> +\t\t\trmdir \"$path\" 2>/dev/null ||\n> +\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n> +\t\tfi\n> +\n> +\t\ttest -e \"$path\" &&\n> +\t\tdie \"A file already exist at path '$path'\"\n> +\n> +\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n\nI like that command ;-)\n\n> +\t\ttest -z \"$url\" &&\n> +\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n> +\n> +\t\tgit-clone \"$url\" \"$path\" ||\n> +\t\tdie \"Clone of submodule '$path' failed\"\n> +\n> +\t\t$(cd \"$path\" && git-checkout -q \"$sha1\") ||\n> +\t\tdie \"Checkout of submodule '$path' failed\"\n> +\n> +\t\tsay \"Submodule '$path' initialized\"\n> +\tdone\n> +}\n> +\n> +#\n> +# Checkout correct revision of each initialized submodule\n> +#\n> +# $@ = requested paths (default to all)\n> +#\n> +modules_update()\n> +{\n> +\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n\nSame here.\n\n> +\twhile read mode sha1 stage path\n> +\tdo\n> +\t\tif ! test -d \"$path/.git\"\n> +\t\tthen\n> +\t\t\tsay \"Submodule '$path' not initialized\"\n> +\t\t\tcontinue;\n> +\t\tfi\n> +\t\tsubsha1=$(cd \"$path\" && git-rev-parse --verify HEAD) ||\n\nMaybe it would be a better idea to use \"git --git-dir=\"$path\" rev-parse \n...\"? Just in case somebody calls this with GIT_DIR overridden...\n\nOr, unset GIT_DIR explicitely.\n\n> +\t\tdie \"Unable to find current revision of submodule '$path'\"\n> +\n> +\t\tif test \"$subsha1\" != \"$sha1\"\n> +\t\tthen\n> +\t\t\t$(cd \"$path\" && git-fetch && git-checkout -q \"$sha1\") ||\n\nThis will make a detached HEAD, right? Do you want that? (I am not really \ninterested in submodules myself, so I haven't thought about it, and I \nhaven't followed that monster discussion.)\n\n> +\t\t\tdie \"Unable to checkout revision $sha1 of submodule '$path'\"\n> +\n> +\t\t\tsay \"Submodule '$path' reset to revision $sha1\"\n\nI'd rather not say \"reset\", since this has a different meaning in Git, but \nrather \"set to revision $sha1\".\n\n> +\t\tfi\n> +\tdone\n> +}\n> +\n> +#\n> +# List all registered submodules, prefixed with:\n> +#  - submodule not initialized\n> +#  + different version checked out\n> +#\n> +# If --cached was specified the revision in the index will be printed\n> +# instead of the currently checked out revision.\n> +#\n> +# $@ = requested paths (default to all)\n> +#\n> +modules_list()\n> +{\n> +\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n> +\twhile read mode sha1 stage path\n> +\tdo\n> +\t\tif ! test -d \"$path/.git\"\n> +\t\tthen\n> +\t\t\tsay \"-$sha1 $path\"\n> +\t\t\tcontinue;\n> +\t\tfi\n> +\t\trevname=$(cd \"$path\" && git-describe $sha1)\n> +\t\tif git diff-files --quiet -- \"$path\"\n> +\t\tthen\n> +\t\t\tsay \" $sha1 $path\\t($revname)\"\n> +\t\telse\n> +\t\t\tif test -z \"$cached\"\n> +\t\t\tthen\n> +\t\t\t\tsha1=$(cd \"$path\" && git-rev-parse --verify HEAD)\n> +\t\t\t\trevname=$(cd \"$path\" && git-describe $sha1)\n> +\t\t\tfi\n> +\t\t\tsay \"+$sha1 $path\\t($revname)\"\n> +\t\tfi\n> +\tdone\n> +}\n> +\n> +\n> +while case \"$#\" in 0) break ;; esac\n> +do\n> +\tcase \"$1\" in\n> +\t-i|--init)\n> +\t\tinit=1\n> +\t\t;;\n> +\t-u|--update)\n> +\t\tupdate=1\n> +\t\t;;\n> +\t-q|--quiet)\n> +\t\tquiet=1\n> +\t\t;;\n> +\t--cached)\n> +\t\tcached=1\n> +\t\t;;\n> +\t--)\n> +\t\tbreak\n> +\t\t;;\n> +\t-*)\n> +\t\tusage\n> +\t\t;;\n> +\t*)\n> +\t\tbreak\n> +\t\t;;\n> +\tesac\n> +\tshift\n> +done\n> +\n> +\n> +if test \"$init\" = \"1\"\n> +then\n> +\tmodules_init $@\n> +elif test \"$update\" = \"1\"\n> +then\n> +\tmodules_update $@\n> +else\n> +\tmodules_list $@\n> +fi\n\nI'll let Junio comment on that command line parsing...\n\nAll in all, I like it: it is short, to the point, and it should do the job \n(maybe with a few enhancements like \"--update\" without arguments means \n_all_ submodules).\n\nCiao,\nDscho\n"},{"id":"43248","messageId":"8c5c35580705250646h12f4f30bt301f4c4bdc2ad530@mail.gmail.com","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251157450.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T13:46:15Z","receivedAt":"2007-05-25T13:46:15Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Fri, 25 May 2007, Lars Hjemli wrote:\n>\n> > There is currently no way to override the mappings in the .gitmodules\n> > file, except by manually creating the subproject repository.\n>\n> I think that is okay. We can add that easily at a later stage, and the\n> script is much easier without that logic.\n\nYes. And it is sort of a feature: if you've cloned the submodule using\na different (aka local) url, 'git submodule --init' will leave it\nalone.\n\n>\n> > diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n>\n> Looks good here, I checked with asciidoc.\n\nThanks.\n\n>\n> > diff --git a/git-submodule.sh b/git-submodule.sh\n> > new file mode 100755\n> > index 0000000..c4a1cc3\n> > --- /dev/null\n> > +++ b/git-submodule.sh\n> > @@ -0,0 +1,163 @@\n> > +#!/bin/sh\n> > +#\n> > +# git-submodule.sh: init, update or list git submodules\n> > +#\n> > +# Copyright (c) 2007 Lars Hjemli\n> > +\n> > +USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'\n> > +. git-sh-setup\n> > +require_work_tree\n> > +\n> > +init=\n> > +update=\n> > +quiet=\n> > +cached=\n> > +\n> > +#\n> > +# print stuff on stdout unless -q was specified\n> > +#\n> > +say()\n> > +{\n> > +     if test -z \"$quiet\"\n> > +     then\n> > +             echo -e \"$@\"\n> > +     fi\n> > +}\n> > +\n> > +#\n> > +# Find all (requested) submodules, run clone + checkout on missing paths\n> > +#\n> > +# $@ = requested paths (default to all)\n> > +#\n> > +modules_init()\n> > +{\n> > +     git ls-files --stage -- $@ | grep -e '^160000 ' |\n>\n> Any reason you read in the stage? It does not seem that you use it.\n\nAre there any other way to get the mode info?\n\n\n>\n> > +     while read mode sha1 stage path\n> > +     do\n> > +             test -d \"$path/.git\" && continue\n> > +\n> > +             if test -d \"$path\"\n> > +             then\n> > +                     rmdir \"$path\" 2>/dev/null ||\n> > +                     die \"Directory '$path' exist, but not as a submodule\"\n> > +             fi\n> > +\n> > +             test -e \"$path\" &&\n> > +             die \"A file already exist at path '$path'\"\n> > +\n> > +             url=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n>\n> I like that command ;-)\n>\n> > +             test -z \"$url\" &&\n> > +             die \"No url found for submodule '$path' in .gitmodules\"\n> > +\n> > +             git-clone \"$url\" \"$path\" ||\n> > +             die \"Clone of submodule '$path' failed\"\n> > +\n> > +             $(cd \"$path\" && git-checkout -q \"$sha1\") ||\n> > +             die \"Checkout of submodule '$path' failed\"\n> > +\n> > +             say \"Submodule '$path' initialized\"\n> > +     done\n> > +}\n> > +\n> > +#\n> > +# Checkout correct revision of each initialized submodule\n> > +#\n> > +# $@ = requested paths (default to all)\n> > +#\n> > +modules_update()\n> > +{\n> > +     git ls-files --stage -- $@ | grep -e '^160000 ' |\n>\n> Same here.\n>\n> > +     while read mode sha1 stage path\n> > +     do\n> > +             if ! test -d \"$path/.git\"\n> > +             then\n> > +                     say \"Submodule '$path' not initialized\"\n> > +                     continue;\n> > +             fi\n> > +             subsha1=$(cd \"$path\" && git-rev-parse --verify HEAD) ||\n>\n> Maybe it would be a better idea to use \"git --git-dir=\"$path\" rev-parse\n> ...\"? Just in case somebody calls this with GIT_DIR overridden...\n>\n> Or, unset GIT_DIR explicitely.\n\nHmm, that's annoying (overridden GIT_DIR). I guess 'git --git-dir\n$path/.git' would be the easiest solution.\n\n\n>\n> > +             die \"Unable to find current revision of submodule '$path'\"\n> > +\n> > +             if test \"$subsha1\" != \"$sha1\"\n> > +             then\n> > +                     $(cd \"$path\" && git-fetch && git-checkout -q \"$sha1\") ||\n>\n> This will make a detached HEAD, right? Do you want that? (I am not really\n> interested in submodules myself, so I haven't thought about it, and I\n> haven't followed that monster discussion.)\n\nWell, we might want to be smarter about this, but on the other hand:\nif the user cares, he can always do 'cd $path && git checkout\n$branch', since 'git submodule -u' will skip submodules with the\ncorrect commit checked out.\n\n>\n> > +                     die \"Unable to checkout revision $sha1 of submodule '$path'\"\n> > +\n> > +                     say \"Submodule '$path' reset to revision $sha1\"\n>\n> I'd rather not say \"reset\", since this has a different meaning in Git, but\n> rather \"set to revision $sha1\".\n\nOk.\n\n>\n> > +             fi\n> > +     done\n> > +}\n> > +\n> > +#\n> > +# List all registered submodules, prefixed with:\n> > +#  - submodule not initialized\n> > +#  + different version checked out\n> > +#\n> > +# If --cached was specified the revision in the index will be printed\n> > +# instead of the currently checked out revision.\n> > +#\n> > +# $@ = requested paths (default to all)\n> > +#\n> > +modules_list()\n> > +{\n> > +     git ls-files --stage -- $@ | grep -e '^160000 ' |\n> > +     while read mode sha1 stage path\n> > +     do\n> > +             if ! test -d \"$path/.git\"\n> > +             then\n> > +                     say \"-$sha1 $path\"\n> > +                     continue;\n> > +             fi\n> > +             revname=$(cd \"$path\" && git-describe $sha1)\n> > +             if git diff-files --quiet -- \"$path\"\n> > +             then\n> > +                     say \" $sha1 $path\\t($revname)\"\n> > +             else\n> > +                     if test -z \"$cached\"\n> > +                     then\n> > +                             sha1=$(cd \"$path\" && git-rev-parse --verify HEAD)\n> > +                             revname=$(cd \"$path\" && git-describe $sha1)\n> > +                     fi\n> > +                     say \"+$sha1 $path\\t($revname)\"\n> > +             fi\n> > +     done\n> > +}\n> > +\n> > +\n> > +while case \"$#\" in 0) break ;; esac\n> > +do\n> > +     case \"$1\" in\n> > +     -i|--init)\n> > +             init=1\n> > +             ;;\n> > +     -u|--update)\n> > +             update=1\n> > +             ;;\n> > +     -q|--quiet)\n> > +             quiet=1\n> > +             ;;\n> > +     --cached)\n> > +             cached=1\n> > +             ;;\n> > +     --)\n> > +             break\n> > +             ;;\n> > +     -*)\n> > +             usage\n> > +             ;;\n> > +     *)\n> > +             break\n> > +             ;;\n> > +     esac\n> > +     shift\n> > +done\n> > +\n> > +\n> > +if test \"$init\" = \"1\"\n> > +then\n> > +     modules_init $@\n> > +elif test \"$update\" = \"1\"\n> > +then\n> > +     modules_update $@\n> > +else\n> > +     modules_list $@\n> > +fi\n>\n> I'll let Junio comment on that command line parsing...\n\nHeh, I'm a shell illiterate...\n\n>\n> All in all, I like it: it is short, to the point, and it should do the job\n> (maybe with a few enhancements like \"--update\" without arguments means\n> _all_ submodules).\n\nWell, it does (or should) update all initialized submodules, but maybe\nthat's not what you meant?\n\nThanks for the review!\n\n--\nlarsh\n"},{"id":"43251","messageId":"Pine.LNX.4.64.0705251451530.4648@racer.site","threadId":"8311","inReplyTo":"8c5c35580705250646h12f4f30bt301f4c4bdc2ad530@mail.gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T13:58:37Z","receivedAt":"2007-05-25T13:58:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Lars Hjemli wrote:\n\n> On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > \n> > On Fri, 25 May 2007, Lars Hjemli wrote:\n> > \n> > > +modules_init()\n> > > +{\n> > > +     git ls-files --stage -- $@ | grep -e '^160000 ' |\n> > \n> > Any reason you read in the stage? It does not seem that you use it.\n> \n> Are there any other way to get the mode info?\n\nAh, I missed that. Right.\n\n> > > +             subsha1=$(cd \"$path\" && git-rev-parse --verify HEAD) ||\n> > \n> > Maybe it would be a better idea to use \"git --git-dir=\"$path\" \n> > rev-parse ...\"? Just in case somebody calls this with GIT_DIR \n> > overridden...\n> > \n> > Or, unset GIT_DIR explicitely.\n> \n> Hmm, that's annoying (overridden GIT_DIR). I guess 'git --git-dir \n> $path/.git' would be the easiest solution.\n\nBut you have to repeat it on every subsequent Git command. OTOH if you \nunset GIT_DIR, you can no longer be sure that you have the correct git dir \nfor Git calls in the superproject...\n\n> > > +             die \"Unable to find current revision of submodule '$path'\"\n> > > +\n> > > +             if test \"$subsha1\" != \"$sha1\"\n> > > +             then\n> > > +                     $(cd \"$path\" && git-fetch && git-checkout -q\n> > \"$sha1\") ||\n> > \n> > This will make a detached HEAD, right? Do you want that? (I am not \n> > really interested in submodules myself, so I haven't thought about it, \n> > and I haven't followed that monster discussion.)\n> \n> Well, we might want to be smarter about this, but on the other hand: if \n> the user cares, he can always do 'cd $path && git checkout $branch', \n> since 'git submodule -u' will skip submodules with the correct commit \n> checked out.\n\nFair enough, I guess...\n\n> > I'll let Junio comment on that command line parsing...\n> \n> Heh, I'm a shell illiterate...\n\n;-)\n\nI guess Junio would like one of his famous\n\n\tcase ,\"$init\",\"$update\",[...] in\n\t*1*1) usage\n\tesac\n\nto prevent running with two actions...\n\n> > All in all, I like it: it is short, to the point, and it should do the \n> > job (maybe with a few enhancements like \"--update\" without arguments \n> > means _all_ submodules).\n> \n> Well, it does (or should) update all initialized submodules, but maybe \n> that's not what you meant?\n\nOops. I meant \"init\". I mean, most people who want to clone a superproject \nwant the submodules being initialized without hassles, probably. But maybe \nthat should be another option: \"--clone-superproject\" or something. Dunno. \nThere's time for that after the initial git-submodule.\n\nCiao,\nDscho\n"},{"id":"43254","messageId":"8c5c35580705250716j27695a01kd1db222be6c7eac7@mail.gmail.com","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251451530.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T14:16:42Z","receivedAt":"2007-05-25T14:16:42Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> On Fri, 25 May 2007, Lars Hjemli wrote:\n> > On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > > On Fri, 25 May 2007, Lars Hjemli wrote:\n> > > > +             die \"Unable to find current revision of submodule '$path'\"\n> > > > +\n> > > > +             if test \"$subsha1\" != \"$sha1\"\n> > > > +             then\n> > > > +                     $(cd \"$path\" && git-fetch && git-checkout -q\n> > > \"$sha1\") ||\n> > >\n> > > This will make a detached HEAD, right? Do you want that? (I am not\n> > > really interested in submodules myself, so I haven't thought about it,\n> > > and I haven't followed that monster discussion.)\n> >\n> > Well, we might want to be smarter about this, but on the other hand: if\n> > the user cares, he can always do 'cd $path && git checkout $branch',\n> > since 'git submodule -u' will skip submodules with the correct commit\n> > checked out.\n>\n> Fair enough, I guess...\n\nThe only alternative I can think of is to check if module.$path.branch\nis specified in .gitmodules: if it is, and it's pointing at the wanted\nsha1, the right thing would be to checkout that branch. Any other sort\nof dwim is bound to get it wrong.\n\n\n>\n> > > I'll let Junio comment on that command line parsing...\n> >\n> > Heh, I'm a shell illiterate...\n>\n> ;-)\n>\n> I guess Junio would like one of his famous\n>\n>         case ,\"$init\",\"$update\",[...] in\n>         *1*1) usage\n>         esac\n>\n> to prevent running with two actions...\n\nAhh, that's something I can handle\n\n\n>\n> > > All in all, I like it: it is short, to the point, and it should do the\n> > > job (maybe with a few enhancements like \"--update\" without arguments\n> > > means _all_ submodules).\n> >\n> > Well, it does (or should) update all initialized submodules, but maybe\n> > that's not what you meant?\n>\n> Oops. I meant \"init\".\n\nHmm, it does (or should) clone all submodules if you run 'git\nsubmodule --init' (no paths specified). Did it fail for you?\n\n\n-- \nlarsh\n"},{"id":"43259","messageId":"Pine.LNX.4.64.0705251539260.4648@racer.site","threadId":"8311","inReplyTo":"8c5c35580705250716j27695a01kd1db222be6c7eac7@mail.gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T14:47:49Z","receivedAt":"2007-05-25T14:47:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Lars Hjemli wrote:\n\n> On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > On Fri, 25 May 2007, Lars Hjemli wrote:\n> > > On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > >\n> > > > All in all, I like it: it is short, to the point, and it should do \n> > > > the job (maybe with a few enhancements like \"--update\" without \n> > > > arguments means _all_ submodules).\n> > >\n> > > Well, it does (or should) update all initialized submodules, but \n> > > maybe that's not what you meant?\n> > \n> > Oops. I meant \"init\".\n> \n> Hmm, it does (or should) clone all submodules if you run 'git submodule \n> --init' (no paths specified). Did it fail for you?\n\nI don't have any superproject to try with ;-)\n\nActually, I missed the \"$@\" in modules_init. You might want to change the \ndocumentation, though, since it suggests (at least to yours truly) that \nyou _need_ to pass a path with \"--init\".\n\nEven happier,\nDscho\n"},{"id":"43262","messageId":"8c5c35580705250752k2021f02dv804d87da5c0d5da7@mail.gmail.com","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251539260.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T14:52:27Z","receivedAt":"2007-05-25T14:52:27Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Fri, 25 May 2007, Lars Hjemli wrote:\n>\n> > On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > > On Fri, 25 May 2007, Lars Hjemli wrote:\n> > > > On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> > > >\n> > > > > All in all, I like it: it is short, to the point, and it should do\n> > > > > the job (maybe with a few enhancements like \"--update\" without\n> > > > > arguments means _all_ submodules).\n> > > >\n> > > > Well, it does (or should) update all initialized submodules, but\n> > > > maybe that's not what you meant?\n> > >\n> > > Oops. I meant \"init\".\n> >\n> > Hmm, it does (or should) clone all submodules if you run 'git submodule\n> > --init' (no paths specified). Did it fail for you?\n>\n> I don't have any superproject to try with ;-)\n\nYou could always try cgit ;-)\n\n>\n> Actually, I missed the \"$@\" in modules_init. You might want to change the\n> documentation, though, since it suggests (at least to yours truly) that\n> you _need_ to pass a path with \"--init\".\n\nOk, will do.\n\n--\nlarsh\n"},{"id":"43273","messageId":"11801165433267-git-send-email-hjemli@gmail.com","threadId":"8311","inReplyTo":"8c5c35580705250752k2021f02dv804d87da5c0d5da7@mail.gmail.com","subject":"[PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T18:09:03Z","receivedAt":"2007-05-25T18:09:03Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This command can be used to initialize, update and inspect submodules. It\nuses a .gitmodules file, readable by git-config, in the top level directory\nof the 'superproject' to specify a mapping between submodule paths and\nrepository url. There is currently no way to override the mappings in the\n.gitmodules file, except by manually creating the subproject repository.\n\nExample .gitmodules layout:\n\n[module \"git\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\tbranch = maint\n\nThe branch-key in .gitmodules is optional. When specified, 'git-submodule -u'\nwill checkout the named branch if its tip matches the commit-sha1 in the\nsuperprojects index. Otherwise, 'git-submodule -u' will create a detached\nHEAD in the submodule.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nThis is an updated patch that hopefully deals with all the previous issues.\n\nI've also added support for specifying module.$path.branch in .gitmodules,\nbut not support for general url rewriting based on local config. If that\nis a wanted feature, it should be trivial to add later on.\n\nBtw: testing this quickly becomes tedious, so I'll try to make a proper\ntestscript later tonight.\n\n\n Documentation/git-submodule.txt |   63 ++++++++++++++\n Makefile                        |    2 +-\n git-submodule.sh                |  178 +++++++++++++++++++++++++++++++++++++++\n 3 files changed, 242 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-submodule.txt\n create mode 100755 git-submodule.sh\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nnew file mode 100644\nindex 0000000..81236aa\n--- /dev/null\n+++ b/Documentation/git-submodule.txt\n@@ -0,0 +1,63 @@\n+git-submodule(1)\n+================\n+\n+NAME\n+----\n+git-submodule - Initialize, update or inspect submodules\n+\n+\n+SYNOPSIS\n+--------\n+'git-submodule' [--init | --update | --cached] [--quiet] [--] [<path>...]\n+\n+\n+DESCRIPTION\n+-----------\n+The command shows the status of each specified submodule path, or all\n+submodules if none is specified. Each submodule sha1 is prefixed with '-'\n+if the submodule is uninitialized and '+' if the checked out version of\n+the submodule is different from the commit sha1 stored in the index.\n+\n+\n+OPTIONS\n+-------\n+<path>::\n+\tPath to submodule(s)\n+\n+-i, --init::\n+\tInitialize the specified submodules, i.e. clone the git repository\n+\tspecified in .gitmodules and checkout the sha1 specified in the\n+\tindex.\n+\n+-u, --update::\n+\tUpdate the specified submodules, i.e. checkout the sha1 specified\n+\tin the index\n+\n+--cached::\n+\tDisplay the sha1 stored in the index, not the currently checked\n+\tout revsion.\n+\n+-q, --quiet::\n+\tBe quiet\n+\n+\n+FILES\n+-----\n+When cloning submodules, a .gitmodules file in the top-level directory\n+of the containing work-tree is examined for the url of each submodule.\n+The url is the value of the key module.$path.url.\n+\n+When updating submodules, the same .gitmodules file is examined for a key\n+named 'module.$path.branch'. If found, and if the named branch is currently\n+at the same revision as the commit-id in the containing repositories index,\n+the specified branch will be checked out in the submodule. If not found, or\n+if the branch isn't currently positioned at the wanted revision, a checkout\n+of the wanted sha1 will happen in the submodule, leaving its HEAD detached.\n+\n+Author\n+------\n+Written by Lars Hjemli <hjemli@gmail.com>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\ndiff --git a/Makefile b/Makefile\nindex 29243c6..5cf2169 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -209,7 +209,7 @@ SCRIPT_SH = \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n-\tgit-lost-found.sh git-quiltimport.sh\n+\tgit-lost-found.sh git-quiltimport.sh git-submodule.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\ndiff --git a/git-submodule.sh b/git-submodule.sh\nnew file mode 100755\nindex 0000000..51a0f47\n--- /dev/null\n+++ b/git-submodule.sh\n@@ -0,0 +1,178 @@\n+#!/bin/sh\n+#\n+# git-submodules.sh: init, update or list git submodules\n+#\n+# Copyright (c) 2007 Lars Hjemli\n+\n+USAGE='[--init | --update | --cached] [--quiet] [--] [<path>...]'\n+. git-sh-setup\n+require_work_tree\n+\n+init=\n+update=\n+quiet=\n+cached=\n+\n+#\n+# print stuff on stdout unless -q was specified\n+#\n+say()\n+{\n+\tif test -z \"$quiet\"\n+\tthen\n+\t\techo -e \"$@\"\n+\tfi\n+}\n+\n+#\n+# Run clone + checkout on missing submodules\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_init()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\ttest -d \"$path/.git\" && continue\n+\n+\t\tif test -d \"$path\"\n+\t\tthen\n+\t\t\trmdir \"$path\" 2>/dev/null ||\n+\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n+\t\tfi\n+\n+\t\ttest -e \"$path\" &&\n+\t\tdie \"A file already exist at path '$path'\"\n+\n+\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n+\t\ttest -z \"$url\" &&\n+\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n+\n+\t\tgit-clone \"$url\" \"$path\" ||\n+\t\tdie \"Clone of submodule '$path' failed\"\n+\n+\t\t$(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n+\t\tdie \"Checkout of submodule '$path' failed\"\n+\n+\t\tsay \"Submodule '$path' initialized\"\n+\tdone\n+}\n+\n+#\n+# Checkout correct revision of each initialized submodule\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_update()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode rev stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"Submodule '$path' not initialized\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\tsubsha1=$(unset GIT_DIR && cd \"$path\" && git-rev-parse --verify HEAD) ||\n+\t\tdie \"Unable to find current revision of submodule '$path'\"\n+\n+\t\tif test \"$subsha1\" != \"$rev\"\n+\t\tthen\n+\t\t\t$(unset GIT_DIR && cd \"$path\" && git-fetch)\n+\t\t\tbranch=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".branch)\n+\t\t\tif test \"$branch\" != \"\"\n+\t\t\tthen\n+\t\t\t\tbranch_sha1=$(unset GIT_DIR && cd \"$path\" &&\n+\t\t\t\t\tgit-rev-parse --verify \"$branch\")\n+\t\t\t\tif test \"$branch_sha1\" = \"$rev\"\n+\t\t\t\tthen\n+\t\t\t\t\trev=\"$branch\"\n+\t\t\t\tfi\n+\t\t\tfi\n+\t\t\t$(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$rev\") ||\n+\t\t\tdie \"Unable to checkout '$rev' in submodule '$path'\"\n+\n+\t\t\tsay \"Submodule '$path': checked out '$rev'\"\n+\t\tfi\n+\tdone\n+}\n+\n+#\n+# List all registered submodules, prefixed with:\n+#  - submodule not initialized\n+#  + different version checked out\n+#\n+# If --cached was specified the revision in the index will be printed\n+# instead of the currently checked out revision.\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_list()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"-$sha1 $path\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\tif git diff-files --quiet -- \"$path\"\n+\t\tthen\n+\t\t\tsay \" $sha1 $path\\t($revname)\"\n+\t\telse\n+\t\t\tif test -z \"$cached\"\n+\t\t\tthen\n+\t\t\t\tsha1=$(unset GIT_DIR && cd \"$path\" && git-rev-parse --verify HEAD)\n+\t\t\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\t\tfi\n+\t\t\tsay \"+$sha1 $path\\t($revname)\"\n+\t\tfi\n+\tdone\n+}\n+\n+\n+while case \"$#\" in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\t-i|--init)\n+\t\tinit=1\n+\t\t;;\n+\t-u|--update)\n+\t\tupdate=1\n+\t\t;;\n+\t-q|--quiet)\n+\t\tquiet=1\n+\t\t;;\n+\t--cached)\n+\t\tcached=1\n+\t\t;;\n+\t--)\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+\n+case \"$init,$update,$cached\" in\n+1,,)\n+\tmodules_init $@\n+\t;;\n+,1,)\n+\tmodules_update $@\n+\t;;\n+,,*)\n+\tmodules_list $@\n+\t;;\n+*)\n+\tusage\n+\t;;\n+esac\n-- \n1.5.2.74.gea9f\n"},{"id":"43274","messageId":"Pine.LNX.4.64.0705251924280.4648@racer.site","threadId":"8311","inReplyTo":"11801165433267-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T18:41:38Z","receivedAt":"2007-05-25T18:41:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Lars Hjemli wrote:\n\n> Btw: testing this quickly becomes tedious, so I'll try to make a proper \n> testscript later tonight.\n\nVery good.\n\n> +'git-submodule' [--init | --update | --cached] [--quiet] [--] [<path>...]\n\nI did not realize this earlier, but we seem to have more and more programs \nwhere actions are specified without \"--\", i.e. \"git-svn fetch\", or \n\"git-bundle create\".\n\nI actually like that, to separate actions from options. Hmm?\n\n> +-i, --init::\n> +\tInitialize the specified submodules, i.e. clone the git repository\n> +\tspecified in .gitmodules and checkout the sha1 specified in the\n> +\tindex.\n\nHow about \"Initialize the submodules...\", and then another sentence \"If \nyou do not want to initialize all submodules, you can specify the subset \nto initialize\"?\n\n> +-u, --update::\n> +\tUpdate the specified submodules, i.e. checkout the sha1 specified\n> +\tin the index\n\nThe full stop is missing here. And again, I would add another sentence \n\"Submodules which have not been initialized are not touched by this \noperation.\"\n\n> +FILES\n> +-----\n> +When cloning submodules, a .gitmodules file in the top-level directory\n> +of the containing work-tree is examined for the url of each submodule.\n> +The url is the value of the key module.$path.url.\n\nIIRC Junio talked about a name for overriding. But I think it would be \neven better to to override by mapping the URLs from .gitmodules to the \nlocally-wanted URLs.\n\nJunio?\n\n> +When updating submodules, the same .gitmodules file is examined for a key\n> +named 'module.$path.branch'. If found, and if the named branch is currently \n> +at the same revision as the commit-id in the containing repositories index, \n> +the specified branch will be checked out in the submodule. If not found, or \n> +if the branch isn't currently positioned at the wanted revision, a checkout\n> +of the wanted sha1 will happen in the submodule, leaving its HEAD detached.\n\nA very good description, and I think this is the only method to checkout \nthe submodule which makes sense. (Just maybe default the value of \nmodule.<path>.branch to \"master\"?)\n\n> +++ b/git-submodule.sh\n> @@ -0,0 +1,178 @@\n> +#!/bin/sh\n> +#\n> +# git-submodules.sh: init, update or list git submodules\n> +#\n> +# Copyright (c) 2007 Lars Hjemli\n> +\n> +USAGE='[--init | --update | --cached] [--quiet] [--] [<path>...]'\n> +. git-sh-setup\n> +require_work_tree\n\nMaybe\n\n\ttest -f \"$GIT_DIR\"/.gitmodules || die \"Not a superproject\"\n\nHmm?\n\n> +\t\t\trmdir \"$path\" 2>/dev/null ||\n\nJust out of curiousity: is rmdir portable? I always used \"rm -r\"...\n\n> +case \"$init,$update,$cached\" in\n> +1,,)\n> +\tmodules_init $@\n> +\t;;\n\n:-)\n\nNow I run out of comments...\n\nCiao,\nDscho\n"},{"id":"43276","messageId":"7vodk8r97s.fsf@assigned-by-dhcp.cox.net","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251924280.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-25T19:31:35Z","receivedAt":"2007-05-25T19:31:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Fri, 25 May 2007, Lars Hjemli wrote:\n>\n>> Btw: testing this quickly becomes tedious, so I'll try to make a proper \n>> testscript later tonight.\n>\n> Very good.\n>\n>> +'git-submodule' [--init | --update | --cached] [--quiet] [--] [<path>...]\n>\n> I did not realize this earlier, but we seem to have more and more programs \n> where actions are specified without \"--\", i.e. \"git-svn fetch\", or \n> \"git-bundle create\".\n>\n> I actually like that, to separate actions from options. Hmm?\n\nI think it is a sensible thing to do for this kind of \"wrapper\nof different functionalities related to one area\".\n\n>> +-i, --init::\n>> +\tInitialize the specified submodules, i.e. clone the git repository\n>> +\tspecified in .gitmodules and checkout the sha1 specified in the\n>> +\tindex.\n>\n> How about \"Initialize the submodules...\", and then another sentence \"If \n> you do not want to initialize all submodules, you can specify the subset \n> to initialize\"?\n\n\n>> +FILES\n>> +-----\n>> +When cloning submodules, a .gitmodules file in the top-level directory\n>> +of the containing work-tree is examined for the url of each submodule.\n>> +The url is the value of the key module.$path.url.\n>\n> IIRC Junio talked about a name for overriding. But I think it would be \n> even better to to override by mapping the URLs from .gitmodules to the \n> locally-wanted URLs.\n>\n> Junio?\n\nI really do not want that (mis)conception that .gitmodules\nspecify the default and .git/config the override.  I really\nthink we should use the .git/config as _the_ only authority to\nget URL, but keyed with the three-level scheme, with URL in\n.gitmodules used _solely_ as a hint when setting up the URL in\nthe .git/config file.\n\n\tcf. $gmane/47502, 47548, 47621\n\n>> +When updating submodules, the same .gitmodules file is examined for a key\n>> +named 'module.$path.branch'. If found, and if the named branch is currently \n>> +at the same revision as the commit-id in the containing repositories index, \n>> +the specified branch will be checked out in the submodule. If not found, or \n>> +if the branch isn't currently positioned at the wanted revision, a checkout\n>> +of the wanted sha1 will happen in the submodule, leaving its HEAD detached.\n>\n> A very good description, and I think this is the only method to checkout \n> the submodule which makes sense. (Just maybe default the value of \n> module.<path>.branch to \"master\"?)\n\nI suspect leaving the HEAD always detached if the superproject\ntree names a concrete commit object name would be less confusing\nand consistent.  When the name of the commit object in the\nsuperproject tree and/or index is 0{40}, it would be a good\nextension to use \"whatever commit that happens to be at the tip\nof this branch\" taken from the .gitmodules file.\n"},{"id":"43279","messageId":"alpine.LFD.0.98.0705251256250.26602@woody.linux-foundation.org","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251924280.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-05-25T19:57:49Z","receivedAt":"2007-05-25T19:57:49Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 25 May 2007, Johannes Schindelin wrote:\n>\n> I did not realize this earlier, but we seem to have more and more programs \n> where actions are specified without \"--\", i.e. \"git-svn fetch\", or \n> \"git-bundle create\".\n\nHey, don't forget \"git bisect\", the granddaddy of them all.\n\n> I actually like that, to separate actions from options. Hmm?\n\nI agree. If something effectively always takes a separate command, it's \nnot an option, it's a subcommand.\n\n\t\tLinus\n"},{"id":"43282","messageId":"Pine.LNX.4.64.0705252127440.4648@racer.site","threadId":"8311","inReplyTo":"alpine.LFD.0.98.0705251256250.26602@woody.linux-foundation.org","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T20:28:15Z","receivedAt":"2007-05-25T20:28:15Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Linus Torvalds wrote:\n\n> On Fri, 25 May 2007, Johannes Schindelin wrote:\n> >\n> > I did not realize this earlier, but we seem to have more and more programs \n> > where actions are specified without \"--\", i.e. \"git-svn fetch\", or \n> > \"git-bundle create\".\n> \n> Hey, don't forget \"git bisect\", the granddaddy of them all.\n\nOh, sorry! How could I? Respect the elders. ;-)\n\nCiao,\nDscho\n"},{"id":"43283","messageId":"8c5c35580705251329u33ac1462m9db35cac0c37e3a9@mail.gmail.com","threadId":"8311","inReplyTo":"7vodk8r97s.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T20:29:41Z","receivedAt":"2007-05-25T20:29:41Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/25/07, Junio C Hamano <junkio@cox.net> wrote:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n> > On Fri, 25 May 2007, Lars Hjemli wrote:\n> >\n> >> Btw: testing this quickly becomes tedious, so I'll try to make a proper\n> >> testscript later tonight.\n> >\n> > Very good.\n> >\n> >> +'git-submodule' [--init | --update | --cached] [--quiet] [--] [<path>...]\n> >\n> > I did not realize this earlier, but we seem to have more and more programs\n> > where actions are specified without \"--\", i.e. \"git-svn fetch\", or\n> > \"git-bundle create\".\n> >\n> > I actually like that, to separate actions from options. Hmm?\n>\n> I think it is a sensible thing to do for this kind of \"wrapper\n> of different functionalities related to one area\".\n\nOk, there seems to be general agreement on this, so how about\nsomething like this instead:\n\n  git-submodule [--quiet] [--cached] [init | update] [--] [<path>...]\n\nor would you rather have\n\n  git-submodule [--quiet] [--cached] <cmd> [<path>...]\n\nwith cmd being one of init, update, status?\n\n> >> +FILES\n> >> +-----\n> >> +When cloning submodules, a .gitmodules file in the top-level directory\n> >> +of the containing work-tree is examined for the url of each submodule.\n> >> +The url is the value of the key module.$path.url.\n> >\n> > IIRC Junio talked about a name for overriding. But I think it would be\n> > even better to to override by mapping the URLs from .gitmodules to the\n> > locally-wanted URLs.\n> >\n> > Junio?\n>\n> I really do not want that (mis)conception that .gitmodules\n> specify the default and .git/config the override.  I really\n> think we should use the .git/config as _the_ only authority to\n> get URL, but keyed with the three-level scheme, with URL in\n> .gitmodules used _solely_ as a hint when setting up the URL in\n> the .git/config file.\n>\n>         cf. $gmane/47502, 47548, 47621\n>\n\nI've read these articles, but I think much of the concerns about\ntrusting the url supplied by upstream goes away when the submodule\nclone/checkout isn't an integrated part of the superproject\nclone/checkout. Besides, if you trust your upstream enough to clone\ntheir repository (the superproject), why wouldn't you trust the data\n(.gitmodules) in that very repository?\n\nStill, a way to locally override the suggested url is probably needed.\n This can be easily achieved by either yours or Linus' suggestion\nabout 'url rewriting'. And if clone/checkout doesn't touch the\nsubmodules at all, the downstream user can look at/override the\n.gitmodules file in his local tree before deciding to do the submodule\n clone or checkout. I don't think there is any need for an interactive\ntool here.\n\nAnother possibility is simply doing the submodule clone/checkout by\nhand (i.e. do 'git clone preferred-url path', don't do 'git submodule\ninit path').\n\n\n> >> +When updating submodules, the same .gitmodules file is examined for a key\n> >> +named 'module.$path.branch'. If found, and if the named branch is currently\n> >> +at the same revision as the commit-id in the containing repositories index,\n> >> +the specified branch will be checked out in the submodule. If not found, or\n> >> +if the branch isn't currently positioned at the wanted revision, a checkout\n> >> +of the wanted sha1 will happen in the submodule, leaving its HEAD detached.\n> >\n> > A very good description, and I think this is the only method to checkout\n> > the submodule which makes sense. (Just maybe default the value of\n> > module.<path>.branch to \"master\"?)\n>\n> I suspect leaving the HEAD always detached if the superproject\n> tree names a concrete commit object name would be less confusing\n> and consistent.\n\nAnd easier to explain :)\n\n\n>When the name of the commit object in the\n> superproject tree and/or index is 0{40}, it would be a good\n> extension to use \"whatever commit that happens to be at the tip\n> of this branch\" taken from the .gitmodules file.\n>\n\nI really can't imagine what kind of superproject would have such a\nsetup. Why would this be needed?\n\n-- \nlarsh\n"},{"id":"43284","messageId":"Pine.LNX.4.64.0705252128200.4648@racer.site","threadId":"8311","inReplyTo":"7vodk8r97s.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-25T20:30:13Z","receivedAt":"2007-05-25T20:30:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Fri, 25 May 2007, Lars Hjemli wrote:\n> >\n> >> +FILES\n> >> +-----\n> >> +When cloning submodules, a .gitmodules file in the top-level directory\n> >> +of the containing work-tree is examined for the url of each submodule.\n> >> +The url is the value of the key module.$path.url.\n> >\n> > IIRC Junio talked about a name for overriding. But I think it would be \n> > even better to to override by mapping the URLs from .gitmodules to the \n> > locally-wanted URLs.\n> >\n> > Junio?\n> \n> I really do not want that (mis)conception that .gitmodules\n> specify the default and .git/config the override.  I really\n> think we should use the .git/config as _the_ only authority to\n> get URL, but keyed with the three-level scheme, with URL in\n> .gitmodules used _solely_ as a hint when setting up the URL in\n> the .git/config file.\n> \n> \tcf. $gmane/47502, 47548, 47621\n\nYes, I skipped over the first two, and concentrated on the third. If \n.gitmodules are used to initialize what is in .git/config, I agree.\n\nHowever, could we have that as a separate commit, to keep things simple \nenough so that I can understand them?\n\n> >> +When updating submodules, the same .gitmodules file is examined for a key\n> >> +named 'module.$path.branch'. If found, and if the named branch is currently \n> >> +at the same revision as the commit-id in the containing repositories index, \n> >> +the specified branch will be checked out in the submodule. If not found, or \n> >> +if the branch isn't currently positioned at the wanted revision, a checkout\n> >> +of the wanted sha1 will happen in the submodule, leaving its HEAD detached.\n> >\n> > A very good description, and I think this is the only method to checkout \n> > the submodule which makes sense. (Just maybe default the value of \n> > module.<path>.branch to \"master\"?)\n> \n> I suspect leaving the HEAD always detached if the superproject\n> tree names a concrete commit object name would be less confusing\n> and consistent.  When the name of the commit object in the\n> superproject tree and/or index is 0{40}, it would be a good\n> extension to use \"whatever commit that happens to be at the tip\n> of this branch\" taken from the .gitmodules file.\n\nYes, that's a much better idea.\n\nCiao,\nDscho\n"},{"id":"43288","messageId":"7v4pm0r5ga.fsf@assigned-by-dhcp.cox.net","threadId":"8311","inReplyTo":"8c5c35580705251329u33ac1462m9db35cac0c37e3a9@mail.gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-25T20:52:53Z","receivedAt":"2007-05-25T20:52:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Lars Hjemli\" <hjemli@gmail.com> writes:\n\n> On 5/25/07, Junio C Hamano <junkio@cox.net> wrote:\n> ...\n>> I really do not want that (mis)conception that .gitmodules\n>> specify the default and .git/config the override.  I really\n>> think we should use the .git/config as _the_ only authority to\n>> get URL, but keyed with the three-level scheme, with URL in\n>> .gitmodules used _solely_ as a hint when setting up the URL in\n>> the .git/config file.\n>>\n>>         cf. $gmane/47502, 47548, 47621\n>>\n>\n> I've read these articles, but I think much of the concerns about\n> trusting the url supplied by upstream goes away when the submodule\n> clone/checkout isn't an integrated part of the superproject\n> clone/checkout. Besides, if you trust your upstream enough to clone\n> their repository (the superproject), why wouldn't you trust the data\n> (.gitmodules) in that very repository?\n\nIt's not about trusting.  You would need to support the mapping\nfor network connectivity reasons, and you would also need to\nnotice and reconfirm when the suggested URL in .gitmodules\nchanges (perhaps because the upstream relocated from sf.net to\nrepo.or.cz ;-), you would need something like what I described\nin order to keep track of user preference for each submodule in\n.git/config anyway.  If that \"mapping\" ends up to be ident\nmapping for most people, that is fine.  At least by always doing\nthe three-level mapping we would not have any special case in\nthe code, and this is not the performance critical part of the\nsystem.\n\nI think the response to the case when upstream repository\nrelocates from the \".gitmodule for default, .git/config for\noverride\" camp would be \"you asked to override in .git/config,\nso it is your job to notice the change in .gitmodules and adjust\nyour override URL\".  That is a serious mistake in usability\npoint of view.  Repository relocation would (hopefully) seldom\nhappen, but when it does happen, things either would break\n(which is easier to diagnose and manually fix up), or things\nclone fine but we reach a wrong repository (which is harder to\nnotice, as \"fetch\" may succeed -- it just would not fetch the\nright commit).  Being able to notice when upstream repository\nrelocates and to ask for confirmation when that happens would\neliminate a lot of confusion from that.\n\n> Another possibility is simply doing the submodule clone/checkout by\n> hand (i.e. do 'git clone preferred-url path', don't do 'git submodule\n> init path').\n\nBut that is what this patch is trying to help the users, isn't\nit?  It reduces the attractiveness of this new tool greatly if\nyou give up there.\n\n>>When the name of the commit object in the\n>> superproject tree and/or index is 0{40}, it would be a good\n>> extension to use \"whatever commit that happens to be at the tip\n>> of this branch\" taken from the .gitmodules file.\n>\n> I really can't imagine what kind of superproject would have such a\n> setup. Why would this be needed?\n\n\"We would work with any working version of Linux 2.6 kernel\"\nwould be a sensible thing to say, I would think.\n\nIt's purely optional, and as you seem to agree always detaching\nHEAD is easier to explain, you do not need \"module.$path.branch\"\nat all.  I just mentioned 0{40} as a possible use case for that\nconfiguration variable.\n"},{"id":"43299","messageId":"8c5c35580705251501u6346c27by1d133efc3d157bf2@mail.gmail.com","threadId":"8311","inReplyTo":"7v4pm0r5ga.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T22:01:50Z","receivedAt":"2007-05-25T22:01:50Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"[This thread is starting to get long, sorry for even more noise about\nthe submodule stuff]\n\nOn 5/25/07, Junio C Hamano <junkio@cox.net> wrote:\n> \"Lars Hjemli\" <hjemli@gmail.com> writes:\n>\n> > On 5/25/07, Junio C Hamano <junkio@cox.net> wrote:\n> > ...\n> >> I really do not want that (mis)conception that .gitmodules\n> >> specify the default and .git/config the override.  I really\n> >> think we should use the .git/config as _the_ only authority to\n> >> get URL, but keyed with the three-level scheme, with URL in\n> >> .gitmodules used _solely_ as a hint when setting up the URL in\n> >> the .git/config file.\n> >>\n> >>         cf. $gmane/47502, 47548, 47621\n> >>\n> >\n> > I've read these articles, but I think much of the concerns about\n> > trusting the url supplied by upstream goes away when the submodule\n> > clone/checkout isn't an integrated part of the superproject\n> > clone/checkout. Besides, if you trust your upstream enough to clone\n> > their repository (the superproject), why wouldn't you trust the data\n> > (.gitmodules) in that very repository?\n>\n> It's not about trusting.  You would need to support the mapping\n> for network connectivity reasons, and you would also need to\n> notice and reconfirm when the suggested URL in .gitmodules\n> changes (perhaps because the upstream relocated from sf.net to\n> repo.or.cz ;-), you would need something like what I described\n> in order to keep track of user preference for each submodule in\n> .git/config anyway.  If that \"mapping\" ends up to be ident\n> mapping for most people, that is fine.  At least by always doing\n> the three-level mapping we would not have any special case in\n> the code, and this is not the performance critical part of the\n> system.\n>\n> I think the response to the case when upstream repository\n> relocates from the \".gitmodule for default, .git/config for\n> override\" camp would be \"you asked to override in .git/config,\n> so it is your job to notice the change in .gitmodules and adjust\n> your override URL\".  That is a serious mistake in usability\n> point of view.  Repository relocation would (hopefully) seldom\n> happen, but when it does happen, things either would break\n> (which is easier to diagnose and manually fix up), or things\n> clone fine but we reach a wrong repository (which is harder to\n> notice, as \"fetch\" may succeed -- it just would not fetch the\n> right commit).  Being able to notice when upstream repository\n> relocates and to ask for confirmation when that happens would\n> eliminate a lot of confusion from that.\n\nBasically, I'd say that as long as the superproject names the sha1 of\nthe submodule commit, nothing else matters.\n\nIf you track a submodule, you would easily notice it if the submodule\nhas the 'wrong' commit checked out (git diff, git status, git\nsubmodule status). And 'git submodule update' would synchronize the\nsubmodules you have decided to track, or error out with a message like\n\"Unable to checkout '$sha1' in submodule '$path'\".\n\nThis is when the ugly sides of submodules raises its head (the\n'official' repo has moved, my local repo is out of date, whatever). I\njust don't see the need for solving those problems now. The 'git\nsubmodule' command would make the common cases easier. Hopefully(?)\nthat would encourage more people to test/use submodules, and the\nproblems that actually _needs_ solving will then show up in due time.\n\n> > Another possibility is simply doing the submodule clone/checkout by\n> > hand (i.e. do 'git clone preferred-url path', don't do 'git submodule\n> > init path').\n>\n> But that is what this patch is trying to help the users, isn't\n> it?  It reduces the attractiveness of this new tool greatly if\n> you give up there.\n\nWell, I happen to think that the average user of submodules wouldn't\ncare the slightest bit where the submodule was cloned from, as long as\nthe sha1 matches. So no, the patch was more about the lack of\nsubmodule porcelain and less about completeness.\n\n\n> >>When the name of the commit object in the\n> >> superproject tree and/or index is 0{40}, it would be a good\n> >> extension to use \"whatever commit that happens to be at the tip\n> >> of this branch\" taken from the .gitmodules file.\n> >\n> > I really can't imagine what kind of superproject would have such a\n> > setup. Why would this be needed?\n>\n> \"We would work with any working version of Linux 2.6 kernel\"\n> would be a sensible thing to say, I would think.\n\nMaybe. I wouldn't want to automatically track the tip of _any_ branch,\nsince I would have no way of knowing if what works today will also\nwork tomorrow (or even compile).\n\n> It's purely optional, and as you seem to agree always detaching\n> HEAD is easier to explain, you do not need \"module.$path.branch\"\n> at all.  I just mentioned 0{40} as a possible use case for that\n> configuration variable.\n\nOk.\n\nI'll redo the patch, removing the branch-specific things, and try to shut up :)\n\n-- \nlarsh\n"},{"id":"43305","messageId":"8c5c35580705251533r21a3dea5w5d263fad9f8bbfa7@mail.gmail.com","threadId":"8311","inReplyTo":"Pine.LNX.4.64.0705251924280.4648@racer.site","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-25T22:33:25Z","receivedAt":"2007-05-25T22:33:25Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/25/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n> [* many usefull comments about the docs *]\n\nThanks, will fix\n\n> > +USAGE='[--init | --update | --cached] [--quiet] [--] [<path>...]'\n> > +. git-sh-setup\n> > +require_work_tree\n>\n> Maybe\n>\n>         test -f \"$GIT_DIR\"/.gitmodules || die \"Not a superproject\"\n>\n> Hmm?\n\nYeah, maybe. But the command will only touch entries with mode 160000\nanyway, so it might not be a big deal.\n\n>\n> > +                     rmdir \"$path\" 2>/dev/null ||\n>\n> Just out of curiousity: is rmdir portable? I always used \"rm -r\"...\n\nI have no idea, really. But the reason for using rmdir was this\nsection of the man page:\n\nNAME\n       rmdir - remove empty directories\n\nI do not want to delete an unempty directory. But there is probably\nsome better way to do this?\n\n--\nlarsh\n"},{"id":"43309","messageId":"11801386283399-git-send-email-hjemli@gmail.com","threadId":"8311","inReplyTo":"8c5c35580705251501u6346c27by1d133efc3d157bf2@mail.gmail.com","subject":"[PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-26T00:17:08Z","receivedAt":"2007-05-26T00:17:08Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This command can be used to initialize, update and inspect submodules. It\nuses a .gitmodules file, readable by git-config, in the top level directory\nof the 'superproject' to specify a mapping between submodule paths and\nrepository url. There is currently no way to override the mappings in the\n.gitmodules file, except by manually creating the subproject repository.\n\nExample .gitmodules layout:\n\n[module \"git\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\nWith this entry in .gitmodules (and a commit reference in the index entry for\nthe path \"git\"), the command 'git submodule init' will clone the repository\nat kernel.org into the directory \"git\".\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nOn 5/26/07, Lars Hjemli <hjemli@gmail.com> wrote:\n> I'll redo the patch, removing the branch-specific things, and try to\n> shut up :)\n\nThis is my final uttering ;-)\n\n\n .gitignore                      |    1 +\n Documentation/git-submodule.txt |   65 +++++++++++++++\n Makefile                        |    2 +-\n git-submodule.sh                |  172 +++++++++++++++++++++++++++++++++++++++\n 4 files changed, 239 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-submodule.txt\n create mode 100755 git-submodule.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 4dc0c39..8fc4923 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -126,6 +126,7 @@ git-ssh-push\n git-ssh-upload\n git-status\n git-stripspace\n+git-submodule\n git-svn\n git-svnimport\n git-symbolic-ref\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nnew file mode 100644\nindex 0000000..2135331\n--- /dev/null\n+++ b/Documentation/git-submodule.txt\n@@ -0,0 +1,65 @@\n+git-submodule(1)\n+================\n+\n+NAME\n+----\n+git-submodule - Initialize, update or inspect submodules\n+\n+\n+SYNOPSIS\n+--------\n+'git-submodule' [--quiet] [--cached] [status|init|update] [--] [<path>...]\n+\n+\n+COMMANDS\n+--------\n+status::\n+\tShow the status of the submodules. This will print the sha1 of the\n+\tcurrently checked out commit for each submodule, along with the\n+\tsubmodule path and the output of gitlink:git-describe[1] for the\n+\tsha1. Each sha1 will be prefixed with '-' if the submodule is not\n+\tinitialized and '+' if the currently checked out submodule commit\n+\tdoes not match the sha1 found in the index of the containing\n+\trepository. This command is the default command for git-submodule.\n+\n+init::\n+\tInitialize the submodules, i.e. clone the git repositories specified\n+\tin the .gitmodules file and checkout the submodule commits specified\n+\tin the index of the containing repository. This will make the\n+\tsubmodules HEAD be detached.\n+\n+update::\n+\tUpdate the initialized submodules, i.e. checkout the submodule commits\n+\tspecified in the index of the containing repository. This will make\n+\tthe submodules HEAD be detached.\n+\n+\n+OPTIONS\n+-------\n+-q, --quiet::\n+\tOnly print error messages.\n+\n+--cached::\n+\tDisplay the sha1 stored in the index, not the sha1 of the currently\n+\tchecked out submodule commit. This option is only valid for the\n+\tstatus command.\n+\n+<path>::\n+\tPath to submodule(s). When specified this will restrict the command\n+\tto only operate on the submodules found at the specified paths.\n+\n+FILES\n+-----\n+When cloning submodules, a .gitmodules file in the top-level directory\n+of the containing repository is used to find the url of each submodule.\n+This file should be formatted in the same way as $GIR_DIR/config. The key\n+to each submodule url is \"module.$path.url\".\n+\n+\n+AUTHOR\n+------\n+Written by Lars Hjemli <hjemli@gmail.com>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\ndiff --git a/Makefile b/Makefile\nindex 29243c6..5cf2169 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -209,7 +209,7 @@ SCRIPT_SH = \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n-\tgit-lost-found.sh git-quiltimport.sh\n+\tgit-lost-found.sh git-quiltimport.sh git-submodule.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\ndiff --git a/git-submodule.sh b/git-submodule.sh\nnew file mode 100755\nindex 0000000..247b1ee\n--- /dev/null\n+++ b/git-submodule.sh\n@@ -0,0 +1,172 @@\n+#!/bin/sh\n+#\n+# git-submodules.sh: init, update or list git submodules\n+#\n+# Copyright (c) 2007 Lars Hjemli\n+\n+USAGE='[--quiet] [--cached] [status|init|update] [--] [<path>...]'\n+. git-sh-setup\n+require_work_tree\n+\n+init=\n+update=\n+status=\n+quiet=\n+cached=\n+\n+#\n+# print stuff on stdout unless -q was specified\n+#\n+say()\n+{\n+\tif test -z \"$quiet\"\n+\tthen\n+\t\techo -e \"$@\"\n+\tfi\n+}\n+\n+#\n+# Run clone + checkout on missing submodules\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_init()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\ttest -d \"$path/.git\" && continue\n+\n+\t\tif test -d \"$path\"\n+\t\tthen\n+\t\t\trmdir \"$path\" 2>/dev/null ||\n+\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n+\t\tfi\n+\n+\t\ttest -e \"$path\" &&\n+\t\tdie \"A file already exist at path '$path'\"\n+\n+\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n+\t\ttest -z \"$url\" &&\n+\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n+\n+\t\tgit-clone \"$url\" \"$path\" ||\n+\t\tdie \"Clone of submodule '$path' failed\"\n+\n+\t\t$(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n+\t\tdie \"Checkout of submodule '$path' failed\"\n+\n+\t\tsay \"Submodule '$path' initialized\"\n+\tdone\n+}\n+\n+#\n+# Checkout correct revision of each initialized submodule\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_update()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"Submodule '$path' not initialized\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\tsubsha1=$(unset GIT_DIR && cd \"$path\" &&\n+\t\t\tgit-rev-parse --verify HEAD) ||\n+\t\tdie \"Unable to find current revision of submodule '$path'\"\n+\n+\t\tif test \"$subsha1\" != \"$sha1\"\n+\t\tthen\n+\t\t\t$(unset GIT_DIR && cd \"$path\" && git-fetch &&\n+\t\t\t\tgit-checkout -q \"$sha1\") ||\n+\t\t\tdie \"Unable to checkout '$sha1' in submodule '$path'\"\n+\n+\t\t\tsay \"Submodule '$path': checked out '$sha1'\"\n+\t\tfi\n+\tdone\n+}\n+\n+#\n+# List all registered submodules, prefixed with:\n+#  - submodule not initialized\n+#  + different revision checked out\n+#\n+# If --cached was specified the revision in the index will be printed\n+# instead of the currently checked out revision.\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_list()\n+{\n+\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path/.git\"\n+\t\tthen\n+\t\t\tsay \"-$sha1 $path\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\tif git diff-files --quiet -- \"$path\"\n+\t\tthen\n+\t\t\tsay \" $sha1 $path\\t($revname)\"\n+\t\telse\n+\t\t\tif test -z \"$cached\"\n+\t\t\tthen\n+\t\t\t\tsha1=$(unset GIT_DIR && cd \"$path\" && git-rev-parse --verify HEAD)\n+\t\t\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\t\tfi\n+\t\t\tsay \"+$sha1 $path\\t($revname)\"\n+\t\tfi\n+\tdone\n+}\n+\n+while case \"$#\" in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\tinit)\n+\t\tinit=1\n+\t\t;;\n+\tupdate)\n+\t\tupdate=1\n+\t\t;;\n+\tstatus)\n+\t\tstatus=1\n+\t\t;;\n+\t-q|--quiet)\n+\t\tquiet=1\n+\t\t;;\n+\t--cached)\n+\t\tcached=1\n+\t\t;;\n+\t--)\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+\n+case \"$init,$update,$status,$cached\" in\n+1,,,)\n+\tmodules_init $@\n+\t;;\n+,1,,)\n+\tmodules_update $@\n+\t;;\n+,,*,*)\n+\tmodules_list $@\n+\t;;\n+*)\n+\tusage\n+\t;;\n+esac\n-- \n1.5.2.74.ga303\n"},{"id":"43312","messageId":"Pine.LNX.4.64.0705260146280.4648@racer.site","threadId":"8311","inReplyTo":"11801386283399-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-26T00:48:10Z","receivedAt":"2007-05-26T00:48:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sat, 26 May 2007, Lars Hjemli wrote:\n\n> On 5/26/07, Lars Hjemli <hjemli@gmail.com> wrote:\n> > I'll redo the patch, removing the branch-specific things, and try to\n> > shut up :)\n> \n> This is my final uttering ;-)\n\nDon't be so shy. We're really making progress here, methinks.\n\nYour version looks good to me.\n\nCiao,\nDscho \"awaiting with impatience the test cases\"\n"},{"id":"43316","messageId":"7v1wh4ped4.fsf@assigned-by-dhcp.cox.net","threadId":"8311","inReplyTo":"11801386283399-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-26T01:23:19Z","receivedAt":"2007-05-26T01:23:19Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Lars Hjemli <hjemli@gmail.com> writes:\n\n> With this entry in .gitmodules (and a commit reference in the index entry for\n> the path \"git\"), the command 'git submodule init' will clone the repository\n> at kernel.org into the directory \"git\".\n>\n> Signed-off-by: Lars Hjemli <hjemli@gmail.com>\n> ---\n>\n> On 5/26/07, Lars Hjemli <hjemli@gmail.com> wrote:\n>> I'll redo the patch, removing the branch-specific things, and try to\n>> shut up :)\n\nHey, don't shut up.  Starting small and covering corner cases\nincrementally is really the right approach.\n\n> +status::\n> +\tShow the status of the submodules. This will print the sha1 of the\n> +\tcurrently checked out commit for each submodule, along with the\n> +\tsubmodule path and the output of gitlink:git-describe[1] for the\n> +\tsha1. Each sha1 will be prefixed with '-' if the submodule is not\n> +\tinitialized and '+' if the currently checked out submodule commit\n> +\tdoes not match the sha1 found in the index of the containing\n> +\trepository. This command is the default command for git-submodule.\n\n(markup) probably you would want `` there for typewriter face.\n\n(wording) didn't we have \"the name of the hash function is\nSHA-1\" patch earlier?  I'd personally prefer calling them\n\"object names\", though...\n\nOther than that, the command description is very nicely done,\nwhich means the design of the command set hence the semantics is\ncleanly done.  Good job.\n\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> new file mode 100755\n> index 0000000..247b1ee\n> --- /dev/null\n> +++ b/git-submodule.sh\n> @@ -0,0 +1,172 @@\n> ...\n> +#\n> +# print stuff on stdout unless -q was specified\n> +#\n> +say()\n> +{\n> +\tif test -z \"$quiet\"\n> +\tthen\n> +\t\techo -e \"$@\"\n> +\tfi\n> +}\n\nWe tend to avoid \"echo -e\" (not POSIX).  I do not see any string\nyou feed to this function that you would _want_ backslash\nescaped sequences (actually I would suspect you would not want\nthem).\n\n> +\n> +#\n> +# Run clone + checkout on missing submodules\n> +#\n> +# $@ = requested paths (default to all)\n> +#\n> +modules_init()\n> +{\n> +\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n\nDid you mean \"$@\", i.e. inside double-quotes?\n\nBecause this pattern would appear a lot in superproject support,\nit might be a good idea to give a new option, --subprojects, to\ngit-ls-files to limit its output to 160000 entries, but that is\na minor detail.\n\n> +\twhile read mode sha1 stage path\n> +\tdo\n\nWe would need to undo the shell-safety \"quoted\" output of paths\nhere.  I suspect it would be much easier to code this in Perl or\nPython, do the \"grep -e\" part above in the script, when we start\ncaring about unwrapping c-quoting of path (or \"ls-files -z\").\n\nBut that is a minor detail we could fix up later.\n\n> +\t\ttest -d \"$path/.git\" && continue\n> +\n> +\t\tif test -d \"$path\"\n> +\t\tthen\n> +\t\t\trmdir \"$path\" 2>/dev/null ||\n> +\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n> +\t\tfi\n\nCould the currently checked-out $path be a symlink to another\ndirectory, and what does the code do in such a case?\n\n> +\n> +\t\ttest -e \"$path\" &&\n> +\t\tdie \"A file already exist at path '$path'\"\n\n\"test -e\" is a relatively new invention and I tended to stay\naway from it, but it should be safe to use these days...\n\n> +\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n> +\t\ttest -z \"$url\" &&\n> +\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n> +\n> +\t\tgit-clone \"$url\" \"$path\" ||\n> +\t\tdie \"Clone of submodule '$path' failed\"\n\n\"git-clone -n\" please, as you will checkout something different\nin the next step anyway.\n\n> +\n> +\t\t$(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n> +\t\tdie \"Checkout of submodule '$path' failed\"\n\nLose $() around this, as it is not producing a string which is\nthe name of the command to run.  You do want a subshell here\nbecause of chdir, so instead of losing $(), replace them with\n().\n\n> ...\n> +modules_update()\n> +{\n>...\n> +\t\tif test \"$subsha1\" != \"$sha1\"\n> +\t\tthen\n> +\t\t\t$(unset GIT_DIR && cd \"$path\" && git-fetch &&\n> +\t\t\t\tgit-checkout -q \"$sha1\") ||\n> +\t\t\tdie \"Unable to checkout '$sha1' in submodule '$path'\"\n\nLikewise.\n"},{"id":"43341","messageId":"8c5c35580705260239x4acf0318vfda3651fb315f8c5@mail.gmail.com","threadId":"8311","inReplyTo":"7v1wh4ped4.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-26T09:39:22Z","receivedAt":"2007-05-26T09:39:22Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/26/07, Junio C Hamano <junkio@cox.net> wrote:\n> Lars Hjemli <hjemli@gmail.com> writes:\n>\n> > With this entry in .gitmodules (and a commit reference in the index entry for\n> > the path \"git\"), the command 'git submodule init' will clone the repository\n> > at kernel.org into the directory \"git\".\n> >\n> > Signed-off-by: Lars Hjemli <hjemli@gmail.com>\n> > ---\n> >\n> > On 5/26/07, Lars Hjemli <hjemli@gmail.com> wrote:\n> >> I'll redo the patch, removing the branch-specific things, and try to\n> >> shut up :)\n>\n> Hey, don't shut up.  Starting small and covering corner cases\n> incrementally is really the right approach.\n\nOk, my meds have kicked in and I'm ready for more ;-)\n\n>\n> > +status::\n> > +     Show the status of the submodules. This will print the sha1 of the\n> > +     currently checked out commit for each submodule, along with the\n> > +     submodule path and the output of gitlink:git-describe[1] for the\n> > +     sha1. Each sha1 will be prefixed with '-' if the submodule is not\n> > +     initialized and '+' if the currently checked out submodule commit\n> > +     does not match the sha1 found in the index of the containing\n> > +     repository. This command is the default command for git-submodule.\n>\n> (markup) probably you would want `` there for typewriter face.\n\nOk, will fix\n\n>\n> (wording) didn't we have \"the name of the hash function is\n> SHA-1\" patch earlier?  I'd personally prefer calling them\n> \"object names\", though...\n\nSome quick grepping wasn't helpfull:\n\n~/src/git/Documentation$ git grep sha1 | wc -l\n98\n~/src/git/Documentation$ git grep SHA1 | wc -l\n80\n~/src/git/Documentation$ git grep SHA-1 | wc -l\n22\n\nWould you prefer SHA-1?\n\n>\n> Other than that, the command description is very nicely done,\n> which means the design of the command set hence the semantics is\n> cleanly done.  Good job.\n\nThanks!\n\n>\n> > diff --git a/git-submodule.sh b/git-submodule.sh\n> > new file mode 100755\n> > index 0000000..247b1ee\n> > --- /dev/null\n> > +++ b/git-submodule.sh\n> > @@ -0,0 +1,172 @@\n> > ...\n> > +#\n> > +# print stuff on stdout unless -q was specified\n> > +#\n> > +say()\n> > +{\n> > +     if test -z \"$quiet\"\n> > +     then\n> > +             echo -e \"$@\"\n> > +     fi\n> > +}\n>\n> We tend to avoid \"echo -e\" (not POSIX).  I do not see any string\n> you feed to this function that you would _want_ backslash\n> escaped sequences (actually I would suspect you would not want\n> them).\n\nI do use \\t between submodule path and the result of git-describe, but\nit's not really needed. I'll drop it.\n\n>\n> > +\n> > +#\n> > +# Run clone + checkout on missing submodules\n> > +#\n> > +# $@ = requested paths (default to all)\n> > +#\n> > +modules_init()\n> > +{\n> > +     git ls-files --stage -- $@ | grep -e '^160000 ' |\n>\n> Did you mean \"$@\", i.e. inside double-quotes?\n\nThat looks right, yes\n\n\n> > +             test -d \"$path/.git\" && continue\n> > +\n> > +             if test -d \"$path\"\n> > +             then\n> > +                     rmdir \"$path\" 2>/dev/null ||\n> > +                     die \"Directory '$path' exist, but not as a submodule\"\n> > +             fi\n>\n> Could the currently checked-out $path be a symlink to another\n> directory, and what does the code do in such a case?\n\nThis I will have to test, but I _suspect_ it would fail on \"test -e\npath\" _unless_ the \"test -d $path/.git\" kicks in.\n\n>\n> > +\n> > +             test -e \"$path\" &&\n> > +             die \"A file already exist at path '$path'\"\n>\n> \"test -e\" is a relatively new invention and I tended to stay\n> away from it, but it should be safe to use these days...\n\nWould you prefer separate -f and -l instead? Hmm, that would match up\nnicely with your concern about symlinks ;-)\n\n>\n> > +             url=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n> > +             test -z \"$url\" &&\n> > +             die \"No url found for submodule '$path' in .gitmodules\"\n> > +\n> > +             git-clone \"$url\" \"$path\" ||\n> > +             die \"Clone of submodule '$path' failed\"\n>\n> \"git-clone -n\" please, as you will checkout something different\n> in the next step anyway.\n\nNice, I hadn't noticed -n, will fix\n\n>\n> > +\n> > +             $(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n> > +             die \"Checkout of submodule '$path' failed\"\n>\n> Lose $() around this, as it is not producing a string which is\n> the name of the command to run.  You do want a subshell here\n> because of chdir, so instead of losing $(), replace them with\n> ().\n\nHeh, there's always something new to learn on this list, thanks.\n\n--\nlarsh\n"},{"id":"43343","messageId":"Pine.LNX.4.64.0705261136590.4648@racer.site","threadId":"8311","inReplyTo":"7v1wh4ped4.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-submodule command","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2007-05-26T10:42:01Z","receivedAt":"2007-05-26T10:42:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 25 May 2007, Junio C Hamano wrote:\n\n> Lars Hjemli <hjemli@gmail.com> writes:\n> \n> > +\n> > +#\n> > +# Run clone + checkout on missing submodules\n> > +#\n> > +# $@ = requested paths (default to all)\n> > +#\n> > +modules_init()\n> > +{\n> > +\tgit ls-files --stage -- $@ | grep -e '^160000 ' |\n> \n> Did you mean \"$@\", i.e. inside double-quotes?\n> \n> Because this pattern would appear a lot in superproject support,\n> it might be a good idea to give a new option, --subprojects, to\n> git-ls-files to limit its output to 160000 entries, but that is\n> a minor detail.\n\nI think that makes sense. It would also help the next one:\n\n> \n> > +\twhile read mode sha1 stage path\n> > +\tdo\n> \n> We would need to undo the shell-safety \"quoted\" output of paths\n> here.  I suspect it would be much easier to code this in Perl or\n> Python, do the \"grep -e\" part above in the script, when we start\n> caring about unwrapping c-quoting of path (or \"ls-files -z\").\n\nI would prefer this to be in shell... so to be easier make it a builtin \nlater, when the script has evolved into a stable state. By introducing \n--subprojects to git-ls-files, you can roll your own quoting just for \ngit-submodule, as needed.\n\n> But that is a minor detail we could fix up later.\n\nI agree. It makes for a nice incremental patch.\n\n> > +\t\ttest -d \"$path/.git\" && continue\n> > +\n> > +\t\tif test -d \"$path\"\n> > +\t\tthen\n> > +\t\t\trmdir \"$path\" 2>/dev/null ||\n> > +\t\t\tdie \"Directory '$path' exist, but not as a submodule\"\n> > +\t\tfi\n> \n> Could the currently checked-out $path be a symlink to another\n> directory, and what does the code do in such a case?\n\nI am not quite sure if you should allow that... So, IMHO this is stuff to \ndiscuss after the initial revision (and after we have a test case, so we \ncan play around with symlinks safely).\n\nCiao,\nDscho\n"},{"id":"43347","messageId":"11801878003599-git-send-email-hjemli@gmail.com","threadId":"8311","inReplyTo":"7v1wh4ped4.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-26T13:56:40Z","receivedAt":"2007-05-26T13:56:40Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"This command can be used to initialize, update and inspect submodules. It\nuses a .gitmodules file, readable by git-config, in the top level directory\nof the 'superproject' to specify a mapping between submodule paths and\nrepository url.\n\nExample .gitmodules layout:\n\n[module \"git\"]\n\turl = git://git.kernel.org/pub/scm/git/git.git\n\nWith this entry in .gitmodules (and a commit reference in the index entry for\nthe path \"git\"), the command 'git submodule init' will clone the repository\nat kernel.org into the directory \"git\".\n\nKnown issues\n============\nThere is currently no way to override the url found in the .gitmodules file,\nexcept by manually creating the subproject repository. The place to fix this\nin the script has a rather long comment about a possible plan.\n\nFunny paths will be quoted in the output from git-ls-files, but git-submodule\ndoes not attempt to unquote (or even detect the presence of) such paths.\n\nSigned-off-by: Lars Hjemli <hjemli@gmail.com>\n---\n\nSo here is another attempt on initial submodule porcelain, still trying to\nkeep it simple. A proper test-script hasn't materialized yet, sorry about\nthat.\n\n .gitignore                      |    1 +\n Documentation/cmd-list.perl     |    1 +\n Documentation/git-submodule.txt |   65 +++++++++++++\n Makefile                        |    2 +-\n git-submodule.sh                |  195 +++++++++++++++++++++++++++++++++++++++\n 5 files changed, 263 insertions(+), 1 deletions(-)\n create mode 100644 Documentation/git-submodule.txt\n create mode 100755 git-submodule.sh\n\ndiff --git a/.gitignore b/.gitignore\nindex 4dc0c39..8fc4923 100644\n--- a/.gitignore\n+++ b/.gitignore\n@@ -126,6 +126,7 @@ git-ssh-push\n git-ssh-upload\n git-status\n git-stripspace\n+git-submodule\n git-svn\n git-svnimport\n git-symbolic-ref\ndiff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl\nindex 443802a..51dc6b4 100755\n--- a/Documentation/cmd-list.perl\n+++ b/Documentation/cmd-list.perl\n@@ -180,6 +180,7 @@ git-ssh-fetch                           synchingrepositories\n git-ssh-upload                          synchingrepositories\n git-status                              mainporcelain\n git-stripspace                          purehelpers\n+git-submodule                           mainporcelain\n git-svn                                 foreignscminterface\n git-svnimport                           foreignscminterface\n git-symbolic-ref                        plumbingmanipulators\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nnew file mode 100644\nindex 0000000..02932a7\n--- /dev/null\n+++ b/Documentation/git-submodule.txt\n@@ -0,0 +1,65 @@\n+git-submodule(1)\n+================\n+\n+NAME\n+----\n+git-submodule - Initialize, update or inspect submodules\n+\n+\n+SYNOPSIS\n+--------\n+'git-submodule' [--quiet] [--cached] [status|init|update] [--] [<path>...]\n+\n+\n+COMMANDS\n+--------\n+status::\n+\tShow the status of the submodules. This will print the SHA-1 of the\n+\tcurrently checked out commit for each submodule, along with the\n+\tsubmodule path and the output of gitlink:git-describe[1] for the\n+\tSHA-1. Each SHA-1 will be prefixed with \"-\" if the submodule is not\n+\tinitialized and \"+\" if the currently checked out submodule commit\n+\tdoes not match the SHA-1 found in the index of the containing\n+\trepository. This command is the default command for git-submodule.\n+\n+init::\n+\tInitialize the submodules, i.e. clone the git repositories specified\n+\tin the .gitmodules file and checkout the submodule commits specified\n+\tin the index of the containing repository. This will make the\n+\tsubmodules HEAD be detached.\n+\n+update::\n+\tUpdate the initialized submodules, i.e. checkout the submodule commits\n+\tspecified in the index of the containing repository. This will make\n+\tthe submodules HEAD be detached.\n+\n+\n+OPTIONS\n+-------\n+-q, --quiet::\n+\tOnly print error messages.\n+\n+--cached::\n+\tDisplay the SHA-1 stored in the index, not the SHA-1 of the currently\n+\tchecked out submodule commit. This option is only valid for the\n+\tstatus command.\n+\n+<path>::\n+\tPath to submodule(s). When specified this will restrict the command\n+\tto only operate on the submodules found at the specified paths.\n+\n+FILES\n+-----\n+When cloning submodules, a .gitmodules file in the top-level directory\n+of the containing repository is used to find the url of each submodule.\n+This file should be formatted in the same way as $GIR_DIR/config. The key\n+to each submodule url is \"module.$path.url\".\n+\n+\n+AUTHOR\n+------\n+Written by Lars Hjemli <hjemli@gmail.com>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\ndiff --git a/Makefile b/Makefile\nindex 29243c6..5cf2169 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -209,7 +209,7 @@ SCRIPT_SH = \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n-\tgit-lost-found.sh git-quiltimport.sh\n+\tgit-lost-found.sh git-quiltimport.sh git-submodule.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\ndiff --git a/git-submodule.sh b/git-submodule.sh\nnew file mode 100755\nindex 0000000..1601bca\n--- /dev/null\n+++ b/git-submodule.sh\n@@ -0,0 +1,195 @@\n+#!/bin/sh\n+#\n+# git-submodules.sh: init, update or list git submodules\n+#\n+# Copyright (c) 2007 Lars Hjemli\n+\n+USAGE='[--quiet] [--cached] [status|init|update] [--] [<path>...]'\n+. git-sh-setup\n+require_work_tree\n+\n+init=\n+update=\n+status=\n+quiet=\n+cached=\n+\n+#\n+# print stuff on stdout unless -q was specified\n+#\n+say()\n+{\n+\tif test -z \"$quiet\"\n+\tthen\n+\t\techo \"$@\"\n+\tfi\n+}\n+\n+#\n+# Run clone + checkout on missing submodules\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_init()\n+{\n+\tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\t# Skip submodule paths that already contain a .git directory.\n+\t\t# This will also trigger if $path is a symlink to a git\n+\t\t# repository\n+\t\ttest -d \"$path\"/.git && continue\n+\n+\t\t# If there already is a directory at the submodule path,\n+\t\t# expect it to be empty (since that is the default checkout\n+\t\t# action) and try to remove it.\n+\t\t# Note: if $path is a symlink to a directory the test will\n+\t\t# succeed but the rmdir will fail. We might want to fix this.\n+\t\tif test -d \"$path\"\n+\t\tthen\n+\t\t\trmdir \"$path\" 2>/dev/null ||\n+\t\t\tdie \"Directory '$path' exist, but is neither empty \"\n+\t\t\t    \"nor a git repository\"\n+\t\tfi\n+\n+\t\ttest -e \"$path\"\n+\t\tdie \"A file already exist at path '$path'\"\n+\n+\t\turl=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".url)\n+\t\ttest -z \"$url\" &&\n+\t\tdie \"No url found for submodule '$path' in .gitmodules\"\n+\n+\t\t# MAYBE FIXME: this would be the place to check GIT_CONFIG\n+\t\t# for a preferred url for this submodule, possibly like this:\n+\t\t#\n+\t\t# modname=$(GIT_CONFIG=.gitmodules git-config module.\"$path\".name)\n+\t\t# alturl=$(git-config module.\"$modname\".url)\n+\t\t#\n+\t\t# This would let the versioned .gitmodules file use the submodule\n+\t\t# path as key, while the unversioned GIT_CONFIG would use the\n+\t\t# logical modulename (if present) as key. But this would need\n+\t\t# another fallback mechanism if the module wasn't named.\n+\n+\t\tgit-clone -n \"$url\" \"$path\" ||\n+\t\tdie \"Clone of submodule '$path' failed\"\n+\n+\t\t(unset GIT_DIR && cd \"$path\" && git-checkout -q \"$sha1\") ||\n+\t\tdie \"Checkout of submodule '$path' failed\"\n+\n+\t\tsay \"Submodule '$path' initialized\"\n+\tdone\n+}\n+\n+#\n+# Checkout correct revision of each initialized submodule\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_update()\n+{\n+\tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path\"/.git\n+\t\tthen\n+\t\t\t# Only mention uninitialized submodules when its\n+\t\t\t# path have been specified\n+\t\t\ttest \"$#\" != \"0\" &&\n+\t\t\tsay \"Submodule '$path' not initialized\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\tsubsha1=$(unset GIT_DIR && cd \"$path\" &&\n+\t\t\tgit-rev-parse --verify HEAD) ||\n+\t\tdie \"Unable to find current revision of submodule '$path'\"\n+\n+\t\tif test \"$subsha1\" != \"$sha1\"\n+\t\tthen\n+\t\t\t(unset GIT_DIR && cd \"$path\" && git-fetch &&\n+\t\t\t\tgit-checkout -q \"$sha1\") ||\n+\t\t\tdie \"Unable to checkout '$sha1' in submodule '$path'\"\n+\n+\t\t\tsay \"Submodule '$path': checked out '$sha1'\"\n+\t\tfi\n+\tdone\n+}\n+\n+#\n+# List all registered submodules, prefixed with:\n+#  - submodule not initialized\n+#  + different revision checked out\n+#\n+# If --cached was specified the revision in the index will be printed\n+# instead of the currently checked out revision.\n+#\n+# $@ = requested paths (default to all)\n+#\n+modules_list()\n+{\n+\tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n+\twhile read mode sha1 stage path\n+\tdo\n+\t\tif ! test -d \"$path\"/.git\n+\t\tthen\n+\t\t\tsay \"-$sha1 $path\"\n+\t\t\tcontinue;\n+\t\tfi\n+\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\tif git diff-files --quiet -- \"$path\"\n+\t\tthen\n+\t\t\tsay \" $sha1 $path ($revname)\"\n+\t\telse\n+\t\t\tif test -z \"$cached\"\n+\t\t\tthen\n+\t\t\t\tsha1=$(unset GIT_DIR && cd \"$path\" && git-rev-parse --verify HEAD)\n+\t\t\t\trevname=$(unset GIT_DIR && cd \"$path\" && git-describe $sha1)\n+\t\t\tfi\n+\t\t\tsay \"+$sha1 $path ($revname)\"\n+\t\tfi\n+\tdone\n+}\n+\n+while case \"$#\" in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\tinit)\n+\t\tinit=1\n+\t\t;;\n+\tupdate)\n+\t\tupdate=1\n+\t\t;;\n+\tstatus)\n+\t\tstatus=1\n+\t\t;;\n+\t-q|--quiet)\n+\t\tquiet=1\n+\t\t;;\n+\t--cached)\n+\t\tcached=1\n+\t\t;;\n+\t--)\n+\t\tbreak\n+\t\t;;\n+\t-*)\n+\t\tusage\n+\t\t;;\n+\t*)\n+\t\tbreak\n+\t\t;;\n+\tesac\n+\tshift\n+done\n+\n+case \"$init,$update,$status,$cached\" in\n+1,,,)\n+\tmodules_init \"$@\"\n+\t;;\n+,1,,)\n+\tmodules_update \"$@\"\n+\t;;\n+,,*,*)\n+\tmodules_list \"$@\"\n+\t;;\n+*)\n+\tusage\n+\t;;\n+esac\n-- \n1.5.2.74.ga303-dirty\n"},{"id":"43348","messageId":"200705261638.00302.simon@lst.de","threadId":"8311","inReplyTo":"11801878003599-git-send-email-hjemli@gmail.com","subject":"Re: [PATCH] Add git-submodule command","fromName":"Simon Hausmann","fromEmail":"simon@lst.de","sentAt":"2007-05-26T14:37:56Z","receivedAt":"2007-05-26T14:37:56Z","isPatch":true,"sender":{"key":"hausmann@kde.org","avatar":"https://gravatar.com/avatar/bc9aad4fb31dce17eb66e690e7b51fe980c62da3c225c785da35dd806b8da778?d=mp&s=160"},"body":"On Saturday 26 May 2007 15:56:40 Lars Hjemli wrote:\n[...]\n> +modules_init()\n> +{\n> +\tgit ls-files --stage -- \"$@\" | grep -e '^160000 ' |\n> +\twhile read mode sha1 stage path\n> +\tdo\n> +\t\t# Skip submodule paths that already contain a .git directory.\n> +\t\t# This will also trigger if $path is a symlink to a git\n> +\t\t# repository\n> +\t\ttest -d \"$path\"/.git && continue\n> +\n> +\t\t# If there already is a directory at the submodule path,\n> +\t\t# expect it to be empty (since that is the default checkout\n> +\t\t# action) and try to remove it.\n> +\t\t# Note: if $path is a symlink to a directory the test will\n> +\t\t# succeed but the rmdir will fail. We might want to fix this.\n> +\t\tif test -d \"$path\"\n> +\t\tthen\n> +\t\t\trmdir \"$path\" 2>/dev/null ||\n> +\t\t\tdie \"Directory '$path' exist, but is neither empty \"\n> +\t\t\t    \"nor a git repository\"\n> +\t\tfi\n> +\n> +\t\ttest -e \"$path\"\n> +\t\tdie \"A file already exist at path '$path'\"\n\nIsn't there a && missing at the end of the test line? :)\n\n\nSimon\n"},{"id":"43349","messageId":"8c5c35580705260748k635c5893w66c735dfce9c2af0@mail.gmail.com","threadId":"8311","inReplyTo":"200705261638.00302.simon@lst.de","subject":"Re: [PATCH] Add git-submodule command","fromName":"Lars Hjemli","fromEmail":"hjemli@gmail.com","sentAt":"2007-05-26T14:48:02Z","receivedAt":"2007-05-26T14:48:02Z","isPatch":true,"sender":{"key":"hjemli@gmail.com","avatar":null},"body":"On 5/26/07, Simon Hausmann <simon@lst.de> wrote:\n> On Saturday 26 May 2007 15:56:40 Lars Hjemli wrote:\n> > +             test -e \"$path\"\n> > +             die \"A file already exist at path '$path'\"\n>\n> Isn't there a && missing at the end of the test line? :)\n>\n\nHmph. There's always something slipping through, thanks for noticing.\nI will make the testscript now....\n\n-- \nlarsh\n"}]}