@matheusbsbs / matheus-bagliano / commits / ec05df353c
Fork 0

git-submodule - make "submodule add" more strict, and document it

This change makes "submodule add" much more strict in the arguments it takes, and is intended to address confusion as recently noted on the git-list. With this change, the required syntax is: $ git submodule add URL path Specifically, this eliminates the form $ git submodule add URL which was confused by more than one person as $ git submodule add path With this patch, the URL locating the submodule's origin repository can be either an absolute URL, or (if it begins with ./ or ../) can express the submodule's repository location relative to the superproject's origin. This patch also eliminates a third form of URL, which was relative to the superproject's top-level directory (not its repository). Any URL that was neither absolute nor matched ./*|../* was assumed to point to a subdirectory of the superproject as the location of the submodule's origin repository. This URL form was confusing and does not seem to correspond to an important use-case. Specifically, no-one has identified the need to clone from a repository already in the superproject's tree, but if this is needed it is easily done using an absolute URL: $(pwd)/relative-path. So, no functionality is lost with this patch. (t6008-rev-list-submodule.sh did rely upon this relative URL, fixed by using $(pwd).) Following this change, there are exactly four variants of submodule-add, as both arguments have two flavors: URL can be absolute, or can begin with ./|../ and thus names the submodule's origin relative to the superproject's origin. Note: With this patch, "submodule add" discerns an absolute URL as matching /*|*:*: e.g., URL begins with /, or it contains a :. This works for all valid URLs, an absolute path in POSIX, as well as an absolute path on Windows). path can either already exist as a valid git repo, or will be cloned from the given URL. The first form here eases creation of a new submodule in an existing superproject as the submodule can be added and tested in-tree before pushing to the public repository. However, the more usual form is the second, where the repo is cloned from the given URL. This specifically addresses the issue of $ git submodule add a/b/c attempting to clone from a repository at "a/b/c" to create a new module in "c". This also simplifies description of "relative URL" as there is now exactly *one* form: a URL relative to the parent's origin repo. Signed-off-by: Mark Levedahl <mlevedahl@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Mark Levedahl committed Jul 9, 2008 at 21:05 UTC ec05df353c594f2afc6509831d3ce145856b0b89
3 files changed +48 -45
Documentation/git-submodule.txt
+27 -9
@@ -9,7 +9,7 @@ git-submodule - Initialize, update or inspect submodules
9 SYNOPSIS
10 --------
11 [verse]
12 -'git submodule' [--quiet] add [-b branch] [--] <repository> [<path>]
12 +'git submodule' [--quiet] add [-b branch] [--] <repository> <path>
13 'git submodule' [--quiet] status [--cached] [--] [<path>...]
14 'git submodule' [--quiet] init [--] [<path>...]
15 'git submodule' [--quiet] update [--init] [--] [<path>...]
@@ -20,14 +20,31 @@ COMMANDS
20 --------
21 add::
22 Add the given repository as a submodule at the given path
23 - to the changeset to be committed next. If path is a valid
24 - repository within the project, it is added as is. Otherwise,
25 - repository is cloned at the specified path. path is added to the
26 - changeset and registered in .gitmodules. If no path is
27 - specified, the path is deduced from the repository specification.
28 - If the repository url begins with ./ or ../, it is stored as
29 - given but resolved as a relative path from the main project's
30 - url when cloning.
23 + to the changeset to be committed next to the current
24 + project: the current project is termed termed the "superproject".
25 ++
26 +This requires two arguments: <repository> and <path>.
27 ++
28 +<repository> is the URL of the new submodule's origin repository.
29 +This may be either an absolute URL, or (if it begins with ./
30 +or ../), the location relative to the superproject's origin
31 +repository.
32 ++
33 +<path> is the relative location for the cloned submodule to
34 +exist in the superproject. If <path> does not exist, then the
35 +submodule is created by cloning from the named URL. If <path> does
36 +exist and is already a valid git repository, then this is added
37 +to the changeset without cloning. This second form is provided
38 +to ease creating a new submodule from scratch, and presumes
39 +the user will later push the submodule to the given URL.
40 ++
41 +In either case, the given URL is recorded into .gitmodules for
42 +use by subsequent users cloning the superproject. If the URL is
43 +given relative to the superproject's repository, the presumption
44 +is the superproject and submodule repositories will be kept
45 +together in the same relative location, and only the
46 +superproject's URL need be provided: git-submodule will correctly
47 +locate the submodule using the relative URL in .gitmodules.
48
49 status::
50 Show the status of the submodules. This will print the SHA-1 of the
@@ -85,6 +102,7 @@ OPTIONS
102 <path>::
103 Path to submodule(s). When specified this will restrict the command
104 to only operate on the submodules found at the specified paths.
105 + (This argument is required with add).
106
107 FILES
108 -----
git-submodule.sh
+20 -35
@@ -5,7 +5,7 @@
5 # Copyright (c) 2007 Lars Hjemli
6
7 USAGE="[--quiet] [--cached] \
8 -[add <repo> [-b branch]|status|init|update [-i|--init]|summary [-n|--summary-limit <n>] [<commit>]] \
8 +[add <repo> [-b branch] <path>]|[status|init|update [-i|--init]|summary [-n|--summary-limit <n>] [<commit>]] \
9 [--] [<path>...]"
10 OPTIONS_SPEC=
11 . git-sh-setup
@@ -27,18 +27,6 @@ say()
27 fi
28 }
29
30 -# NEEDSWORK: identical function exists in get_repo_base in clone.sh
31 -get_repo_base() {
32 - (
33 - cd "`/bin/pwd`" &&
34 - cd "$1" || cd "$1.git" &&
35 - {
36 - cd .git
37 - pwd
38 - }
39 - ) 2>/dev/null
40 -}
41 -
30 # Resolve relative url by appending to parent's url
31 resolve_relative_url ()
32 {
@@ -115,7 +103,7 @@ module_clone()
103 #
104 # Add a new submodule to the working tree, .gitmodules and the index
105 #
118 -# $@ = repo [path]
106 +# $@ = repo path
107 #
108 # optional branch is stored in global branch variable
109 #
@@ -150,16 +138,27 @@ cmd_add()
138 repo=$1
139 path=$2
140
153 - if test -z "$repo"; then
141 + if test -z "$repo" -o -z "$path"; then
142 usage
143 fi
144
157 - # Guess path from repo if not specified or strip trailing slashes
158 - if test -z "$path"; then
159 - path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
160 - else
161 - path=$(echo "$path" | sed -e 's|/*$||')
162 - fi
145 + # assure repo is absolute or relative to parent
146 + case "$repo" in
147 + ./*|../*)
148 + # dereference source url relative to parent's url
149 + realrepo=$(resolve_relative_url "$repo") || exit
150 + ;;
151 + *:*|/*)
152 + # absolute url
153 + realrepo=$repo
154 + ;;
155 + *)
156 + die "repo URL: '$repo' must be absolute or begin with ./|../"
157 + ;;
158 + esac
159 +
160 + # strip trailing slashes from path
161 + path=$(echo "$path" | sed -e 's|/*$||')
162
163 git ls-files --error-unmatch "$path" > /dev/null 2>&1 &&
164 die "'$path' already exists in the index"
@@ -174,20 +173,6 @@ cmd_add()
173 die "'$path' already exists and is not a valid git repo"
174 fi
175 else
177 - case "$repo" in
178 - ./*|../*)
179 - # dereference source url relative to parent's url
180 - realrepo=$(resolve_relative_url "$repo") || exit
181 - ;;
182 - *)
183 - # Turn the source into an absolute path if
184 - # it is local
185 - if base=$(get_repo_base "$repo"); then
186 - repo="$base"
187 - fi
188 - realrepo=$repo
189 - ;;
190 - esac
176
177 module_clone "$path" "$realrepo" || exit
178 (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) ||
t/t6008-rev-list-submodule.sh
+1 -1
@@ -23,7 +23,7 @@ test_expect_success 'setup' '
23
24 : > super-file &&
25 git add super-file &&
26 - git submodule add . sub &&
26 + git submodule add "$(pwd)" sub &&
27 git symbolic-ref HEAD refs/heads/super &&
28 test_tick &&
29 git commit -m super-initial &&