{"thread":{"id":"12474","subject":"[PATCH] git-submodule - Allow adding a submodule in-place","startedAt":"2008-03-04T02:06:23Z","lastAt":"2008-03-05T01:15:02Z","messageCount":6,"participants":["Mark Levedahl","Ping Yin","Junio C Hamano","Sven Verdoolaege"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"70867","messageId":"1204596383-4040-1-git-send-email-mlevedahl@gmail.com","threadId":"12474","inReplyTo":null,"subject":"[PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2008-03-04T02:06:23Z","receivedAt":"2008-03-04T02:06:23Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"When working in top-level project, it is useful to create a new submodule\nas a git repo in a subdirectory, then add that submodule to top-level in\nplace.  This allows \"git submodule add <intended url> subdir\" to add the\nexisting subdir to the current project.  The presumption is the user will\nlater push / clone the subdir to the <intended url> so that future\nsubmodule init / updates will work.\n\nAbsent this patch, \"git submodule add\" insists upon cloning the subdir\nfrom a repository at the given url, which is fine for adding an existing\nproject in but less useful when adding a new submodule from scratch to an\nexisting project.  The former functionality remains, and the clone is\nattempted if the subdir does not already exist as a valid git repo.\n\nSigned-off-by: Mark Levedahl <mlevedahl@gmail.com>\n---\n Documentation/git-submodule.txt |   21 +++++++++++++---\n git-submodule.sh                |   50 +++++++++++++++++++++++---------------\n 2 files changed, 47 insertions(+), 24 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex e818e6e..85d7dd3 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -9,17 +9,18 @@ git-submodule - Initialize, update or inspect submodules\n SYNOPSIS\n --------\n [verse]\n-'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]\n+'git-submodule' [--quiet] add [-b branch] [-r <remote>] [--] <repository> [<path>]\n 'git-submodule' [--quiet] status [--cached] [--] [<path>...]\n-'git-submodule' [--quiet] [init|update] [--] [<path>...]\n+'git-submodule' [--quiet] [init|update] [-r <remote>] [--] [<path>...]\n \n \n COMMANDS\n --------\n add::\n \tAdd the given repository as a submodule at the given path\n-\tto the changeset to be committed next.  In particular, the\n-\trepository is cloned at the specified path, added to the\n+\tto the changeset to be committed next.  If path is a valid\n+\trepository within the project, it is added as is. Otherwise,\n+\trepository is cloned at the specified path. path is added to the\n \tchangeset and registered in .gitmodules.   If no path is\n \tspecified, the path is deduced from the repository specification.\n \tIf the repository url begins with ./ or ../, it is stored as\n@@ -55,6 +56,18 @@ OPTIONS\n -b, --branch::\n \tBranch of repository to add as submodule.\n \n+-r remote::\n+\tName of remote to use or define when working with relative submodules\n+\t(i.e., submodules whose url is given relative to the top-level\n+\tproject). If this value is undefined, the top-level project's\n+\tbranch.<name>.remote is used, and if that is undefined the default\n+\t\"origin\" is used. The remote will be defined in each relative\n+\tsubmodule as needed by appending the relative url to the top level\n+\tproject's url. This option has no effect upon submodules defined\n+\tusing an absolute url: such project's are cloned using the default\n+\t\"origin,\" and are updated using the submodule's branch.<name>.remote\n+\tmachinery and defaulting to \"origin.\"\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\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 67d3224..7171cb6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -153,20 +153,6 @@ cmd_add()\n \t\tusage\n \tfi\n \n-\tcase \"$repo\" in\n-\t./*|../*)\n-\t\t# dereference source url relative to parent's url\n-\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n-\t*)\n-\t\t# Turn the source into an absolute path if\n-\t\t# it is local\n-\t\tif base=$(get_repo_base \"$repo\"); then\n-\t\t\trepo=\"$base\"\n-\t\tfi\n-\t\trealrepo=$repo\n-\t\t;;\n-\tesac\n-\n \t# Guess path from repo if not specified or strip trailing slashes\n \tif test -z \"$path\"; then\n \t\tpath=$(echo \"$repo\" | sed -e 's|/*$||' -e 's|:*/*\\.git$||' -e 's|.*[/:]||g')\n@@ -174,15 +160,39 @@ cmd_add()\n \t\tpath=$(echo \"$path\" | sed -e 's|/*$||')\n \tfi\n \n-\ttest -e \"$path\" &&\n-\tdie \"'$path' already exists\"\n-\n \tgit ls-files --error-unmatch \"$path\" > /dev/null 2>&1 &&\n \tdie \"'$path' already exists in the index\"\n \n-\tmodule_clone \"$path\" \"$realrepo\" || exit\n-\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n-\tdie \"Unable to checkout submodule '$path'\"\n+\t# perhaps the path exists and is already a git repo, else clone it\n+\tif test -e \"$path\"\n+\tthen\n+\t\tif test -d \"$path/.git\" &&\n+\t\ttest \"$(unset GIT_DIR; cd $path; git rev-parse --git-dir)\" = \".git\"\n+\t\tthen\n+\t\t\techo \"Adding existing repo at '$path' to the index\"\n+\t\telse\n+\t\t\tdie \"'$path' already exists and is not a valid git repo\"\n+\t\tfi\n+\telse\n+\t\tcase \"$repo\" in\n+\t\t./*|../*)\n+\t\t\t# dereference source url relative to parent's url\n+\t\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n+\t\t*)\n+\t\t\t# Turn the source into an absolute path if\n+\t\t\t# it is local\n+\t\t\tif base=$(get_repo_base \"$repo\"); then\n+\t\t\t\trepo=\"$base\"\n+\t\t\tfi\n+\t\t\trealrepo=$repo\n+\t\t\t;;\n+\t\tesac\n+\n+\t\tmodule_clone \"$path\" \"$realrepo\" || exit\n+\t\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n+\t\tdie \"Unable to checkout submodule '$path'\"\n+\tfi\n+\n \tgit add \"$path\" ||\n \tdie \"Failed to add submodule '$path'\"\n \n-- \n1.5.4.3.438.g4c6f8\n\n"},{"id":"70890","messageId":"46dff0320803032116t63327fe6u3e9be269b0cec347@mail.gmail.com","threadId":"12474","inReplyTo":"1204596383-4040-1-git-send-email-mlevedahl@gmail.com","subject":"Re: [PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Ping Yin","fromEmail":"pkufranky@gmail.com","sentAt":"2008-03-04T05:16:41Z","receivedAt":"2008-03-04T05:16:41Z","isPatch":true,"sender":{"key":"pkufranky@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5346?v=4"},"body":"On Tue, Mar 4, 2008 at 10:06 AM, Mark Levedahl <mlevedahl@gmail.com> wrote:\n>\n>  +-r remote::\n>  +       Name of remote to use or define when working with relative submodules\n>  +       (i.e., submodules whose url is given relative to the top-level\n>  +       project). If this value is undefined, the top-level project's\n>  +       branch.<name>.remote is used, and if that is undefined the default\n>  +       \"origin\" is used. The remote will be defined in each relative\n>  +       submodule as needed by appending the relative url to the top level\n>  +       project's url. This option has no effect upon submodules defined\n>  +       using an absolute url: such project's are cloned using the default\n>  +       \"origin,\" and are updated using the submodule's branch.<name>.remote\n>  +       machinery and defaulting to \"origin.\"\n>  +\n\nIs this part necessary?\n>  --\n>  1.5.4.3.438.g4c6f8\n>\n>\n\n\n\n-- \nPing Yin\n"},{"id":"70895","messageId":"7vod9v9d9b.fsf@gitster.siamese.dyndns.org","threadId":"12474","inReplyTo":"1204596383-4040-1-git-send-email-mlevedahl@gmail.com","subject":"Re: [PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-04T07:09:20Z","receivedAt":"2008-03-04T07:09:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Levedahl <mlevedahl@gmail.com> writes:\n\n> When working in top-level project, it is useful to create a new submodule\n> as a git repo in a subdirectory, then add that submodule to top-level in\n> place.  This allows \"git submodule add <intended url> subdir\" to add the\n> existing subdir to the current project.  The presumption is the user will\n> later push / clone the subdir to the <intended url> so that future\n> submodule init / updates will work.\n>\n> Absent this patch, \"git submodule add\" insists upon cloning the subdir\n> from a repository at the given url, which is fine for adding an existing\n> project in but less useful when adding a new submodule from scratch to an\n> existing project.  The former functionality remains, and the clone is\n> attempted if the subdir does not already exist as a valid git repo.\n>\n> Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>\n\nThis is a very well written commit log message with an appropriate title,\nand a convincing justification why this is a good idea.  Even I (who does\nnot heavily use submodules himself) can look at the patch and tell that\nthe existing check and die was too limiting to the users after reading\nthese two paragraphs.\n\nI wish everybody wrote his commit log message like this.\n\n> +-r remote::\n> +\tName of remote to use or define when working with relative submodules\n> +\t(i.e., submodules whose url is given relative to the top-level\n> +\tproject). If this value is undefined, the top-level project's\n> +\tbranch.<name>.remote is used, and if that is undefined the default\n> +\t\"origin\" is used. The remote will be defined in each relative\n> +\tsubmodule as needed by appending the relative url to the top level\n> +\tproject's url. This option has no effect upon submodules defined\n> +\tusing an absolute url: such project's are cloned using the default\n> +\t\"origin,\" and are updated using the submodule's branch.<name>.remote\n> +\tmachinery and defaulting to \"origin.\"\n> +\n\nHowever, this part is not mentioned in the commit log message at all.\n\nIs the enhancement advertised on the title line be useful _without_ this?\n\nIf so, this is a commit with two unrelated changes, and needs to be split\ninto two patches.  Also the other change that adds \"-r remote\" needs to be\nexplained and defended separately.\n\nIf not, the additional option should be described (what it does) justified\n(why it is needed), and also there needs an explanation why this is an\nintegral part of the addition of this \"add existing subdirectory\" feature.\n\nYes, I _can_ guess that this option is related to your earlier f31a522\n(git-submodule - allow a relative path as the subproject url).  Because\n\"submodule add\" is used for setting up the initial .gitmodules entry for\nthe new submodule, you would need to give a clue to the command if you\nwant to set it up as a relative thing or an absolute thing, and you use\nthe relativeness of the URL parameter for that.  If you give a relative\npath to the URL, however, you would need a way to pass in another piece of\ninformation to let the command determine what it is relative to, and that\nis the reason why this parameter exists.\n\nBut you _shouldn't_ be making me (or others, for that matter) wonder why\nand justify it for you.  It should be explained in the commit log message.\n\n\n"},{"id":"70922","messageId":"20080304112259.GM4703MdfPADPa@greensroom.kotnet.org","threadId":"12474","inReplyTo":"1204596383-4040-1-git-send-email-mlevedahl@gmail.com","subject":"Re: [PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Sven Verdoolaege","fromEmail":"skimo@kotnet.org","sentAt":"2008-03-04T11:22:59Z","receivedAt":"2008-03-04T11:22:59Z","isPatch":true,"sender":{"key":"skimo@kotnet.org","avatar":null},"body":"On Mon, Mar 03, 2008 at 09:06:23PM -0500, Mark Levedahl wrote:\n> @@ -9,17 +9,18 @@ git-submodule - Initialize, update or inspect submodules\n>  SYNOPSIS\n>  --------\n>  [verse]\n> -'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>]\n> +'git-submodule' [--quiet] add [-b branch] [-r <remote>] [--] <repository> [<path>]\n>  'git-submodule' [--quiet] status [--cached] [--] [<path>...]\n> -'git-submodule' [--quiet] [init|update] [--] [<path>...]\n> +'git-submodule' [--quiet] [init|update] [-r <remote>] [--] [<path>...]\n>  \n> @@ -55,6 +56,18 @@ OPTIONS\n>  -b, --branch::\n>  \tBranch of repository to add as submodule.\n>  \n> +-r remote::\n> +\tName of remote to use or define when working with relative submodules\n> +\t(i.e., submodules whose url is given relative to the top-level\n> +\tproject). If this value is undefined, the top-level project's\n> +\tbranch.<name>.remote is used, and if that is undefined the default\n> +\t\"origin\" is used. The remote will be defined in each relative\n> +\tsubmodule as needed by appending the relative url to the top level\n> +\tproject's url. This option has no effect upon submodules defined\n> +\tusing an absolute url: such project's are cloned using the default\n> +\t\"origin,\" and are updated using the submodule's branch.<name>.remote\n> +\tmachinery and defaulting to \"origin.\"\n> +\n\nAs has been noted by others, these changes don't belong in this commit.\n\nAs to the functionality actually provided by this patch,\nI'm somewhat concerned with encouraging this kind of setup,\nwhere the main (and only) copy of your subproject repo\nis stored inside the working tree.\n\nIdeally (for some at least), switching back to a commit\nof the superproject from before the subproject was added\nshould remove the subproject from the working tree.\nThis means that the GIT_DIR of the subproject should be\nstored somewhere under the GIT_DIR of the superproject.\nThere was some talk about doing this about a year ago,\nbut AFAIK, it hasn't gotten implemented yet.\nIt's easier to handle this when adding a subproject that\ndoes not already exist in the tree.\n\nOf course, if this feature would ever get implemented, then\nit would also have to provide an upgrade path from the\ncurrent setup and that upgrade path would also handle your\ncase.  So this is not really an objection, but just a concern.\n\nskimo\n"},{"id":"70937","messageId":"30e4a070803040439o7b3453c9ta3f00a6d1115af86@mail.gmail.com","threadId":"12474","inReplyTo":"7vod9v9d9b.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2008-03-04T12:39:44Z","receivedAt":"2008-03-04T12:39:44Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"On Tue, Mar 4, 2008 at 2:09 AM, Junio C Hamano <gitster@pobox.com> wrote:\n\n>\n>  However, this part is not mentioned in the commit log message at all.\n\n...because the code to do the latter part is not a part of the patch,\nand I failed to edit the documentation patch to remove that other\ncruft. Will resend tonight when I have a connection that lets me send\npatches.\n\nMark\n"},{"id":"71020","messageId":"1204679702-304-1-git-send-email-mlevedahl@gmail.com","threadId":"12474","inReplyTo":"1204596383-4040-1-git-send-email-mlevedahl@gmail.com","subject":"[PATCH] git-submodule - Allow adding a submodule in-place","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2008-03-05T01:15:02Z","receivedAt":"2008-03-05T01:15:02Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"When working in top-level project, it is useful to create a new submodule\nas a git repo in a subdirectory, then add that submodule to top-level in\nplace.  This allows \"git submodule add <intended url> subdir\" to add the\nexisting subdir to the current project.  The presumption is the user will\nlater push / clone the subdir to the <intended url> so that future\nsubmodule init / updates will work.\n\nAbsent this patch, \"git submodule add\" insists upon cloning the subdir\nfrom a repository at the given url, which is fine for adding an existing\nproject in but less useful when adding a new submodule from scratch to an\nexisting project.  The former functionality remains, and the clone is\nattempted if the subdir does not already exist as a valid git repo.\n\nSigned-off-by: Mark Levedahl <mlevedahl@gmail.com>\n---\n\nThis eliminates the extraneous documentation of the previous patch that\nwas for functionality unrelated to this topic.\n\n Documentation/git-submodule.txt |    5 ++-\n git-submodule.sh                |   50 +++++++++++++++++++++++---------------\n 2 files changed, 33 insertions(+), 22 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex e818e6e..b4d0160 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -18,8 +18,9 @@ COMMANDS\n --------\n add::\n \tAdd the given repository as a submodule at the given path\n-\tto the changeset to be committed next.  In particular, the\n-\trepository is cloned at the specified path, added to the\n+\tto the changeset to be committed next.  If path is a valid\n+\trepository within the project, it is added as is. Otherwise,\n+\trepository is cloned at the specified path. path is added to the\n \tchangeset and registered in .gitmodules.   If no path is\n \tspecified, the path is deduced from the repository specification.\n \tIf the repository url begins with ./ or ../, it is stored as\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 67d3224..7171cb6 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -153,20 +153,6 @@ cmd_add()\n \t\tusage\n \tfi\n\n-\tcase \"$repo\" in\n-\t./*|../*)\n-\t\t# dereference source url relative to parent's url\n-\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n-\t*)\n-\t\t# Turn the source into an absolute path if\n-\t\t# it is local\n-\t\tif base=$(get_repo_base \"$repo\"); then\n-\t\t\trepo=\"$base\"\n-\t\tfi\n-\t\trealrepo=$repo\n-\t\t;;\n-\tesac\n-\n \t# Guess path from repo if not specified or strip trailing slashes\n \tif test -z \"$path\"; then\n \t\tpath=$(echo \"$repo\" | sed -e 's|/*$||' -e 's|:*/*\\.git$||' -e 's|.*[/:]||g')\n@@ -174,15 +160,39 @@ cmd_add()\n \t\tpath=$(echo \"$path\" | sed -e 's|/*$||')\n \tfi\n\n-\ttest -e \"$path\" &&\n-\tdie \"'$path' already exists\"\n-\n \tgit ls-files --error-unmatch \"$path\" > /dev/null 2>&1 &&\n \tdie \"'$path' already exists in the index\"\n\n-\tmodule_clone \"$path\" \"$realrepo\" || exit\n-\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n-\tdie \"Unable to checkout submodule '$path'\"\n+\t# perhaps the path exists and is already a git repo, else clone it\n+\tif test -e \"$path\"\n+\tthen\n+\t\tif test -d \"$path/.git\" &&\n+\t\ttest \"$(unset GIT_DIR; cd $path; git rev-parse --git-dir)\" = \".git\"\n+\t\tthen\n+\t\t\techo \"Adding existing repo at '$path' to the index\"\n+\t\telse\n+\t\t\tdie \"'$path' already exists and is not a valid git repo\"\n+\t\tfi\n+\telse\n+\t\tcase \"$repo\" in\n+\t\t./*|../*)\n+\t\t\t# dereference source url relative to parent's url\n+\t\t\trealrepo=\"$(resolve_relative_url $repo)\" ;;\n+\t\t*)\n+\t\t\t# Turn the source into an absolute path if\n+\t\t\t# it is local\n+\t\t\tif base=$(get_repo_base \"$repo\"); then\n+\t\t\t\trepo=\"$base\"\n+\t\t\tfi\n+\t\t\trealrepo=$repo\n+\t\t\t;;\n+\t\tesac\n+\n+\t\tmodule_clone \"$path\" \"$realrepo\" || exit\n+\t\t(unset GIT_DIR; cd \"$path\" && git checkout -q ${branch:+-b \"$branch\" \"origin/$branch\"}) ||\n+\t\tdie \"Unable to checkout submodule '$path'\"\n+\tfi\n+\n \tgit add \"$path\" ||\n \tdie \"Failed to add submodule '$path'\"\n\n--\n1.5.4.3.438.g4c6f8\n\n"}]}