When working in top-level project, it is useful to create a new submodule as a git repo in a subdirectory, then add that submodule to top-level in place. This allows "git submodule add <intended url> subdir" to add the existing subdir to the current project. The presumption is the user will later push / clone the subdir to the <intended url> so that future submodule init / updates will work. Absent this patch, "git submodule add" insists upon cloning the subdir from a repository at the given url, which is fine for adding an existing project in but less useful when adding a new submodule from scratch to an existing project. The former functionality remains, and the clone is attempted if the subdir does not already exist as a valid git repo. Signed-off-by: Mark Levedahl <mlevedahl@xxxxxxxxx> --- Documentation/git-submodule.txt | 21 +++++++++++++--- git-submodule.sh | 50 +++++++++++++++++++++++--------------- 2 files changed, 47 insertions(+), 24 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index e818e6e..85d7dd3 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,17 +9,18 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] -'git-submodule' [--quiet] add [-b branch] [--] <repository> [<path>] +'git-submodule' [--quiet] add [-b branch] [-r <remote>] [--] <repository> [<path>] 'git-submodule' [--quiet] status [--cached] [--] [<path>...] -'git-submodule' [--quiet] [init|update] [--] [<path>...] +'git-submodule' [--quiet] [init|update] [-r <remote>] [--] [<path>...] COMMANDS -------- add:: Add the given repository as a submodule at the given path - to the changeset to be committed next. In particular, the - repository is cloned at the specified path, added to the + to the changeset to be committed next. If path is a valid + repository within the project, it is added as is. Otherwise, + repository is cloned at the specified path. path is added to the changeset and registered in .gitmodules. If no path is specified, the path is deduced from the repository specification. If the repository url begins with ./ or ../, it is stored as @@ -55,6 +56,18 @@ OPTIONS -b, --branch:: Branch of repository to add as submodule. +-r remote:: + Name of remote to use or define when working with relative submodules + (i.e., submodules whose url is given relative to the top-level + project). If this value is undefined, the top-level project's + branch.<name>.remote is used, and if that is undefined the default + "origin" is used. The remote will be defined in each relative + submodule as needed by appending the relative url to the top level + project's url. This option has no effect upon submodules defined + using an absolute url: such project's are cloned using the default + "origin," and are updated using the submodule's branch.<name>.remote + machinery and defaulting to "origin." + --cached:: Display the SHA-1 stored in the index, not the SHA-1 of the currently checked out submodule commit. This option is only valid for the diff --git a/git-submodule.sh b/git-submodule.sh index 67d3224..7171cb6 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -153,20 +153,6 @@ cmd_add() usage fi - case "$repo" in - ./*|../*) - # dereference source url relative to parent's url - realrepo="$(resolve_relative_url $repo)" ;; - *) - # Turn the source into an absolute path if - # it is local - if base=$(get_repo_base "$repo"); then - repo="$base" - fi - realrepo=$repo - ;; - esac - # Guess path from repo if not specified or strip trailing slashes if test -z "$path"; then path=$(echo "$repo" | sed -e 's|/*$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g') @@ -174,15 +160,39 @@ cmd_add() path=$(echo "$path" | sed -e 's|/*$||') fi - test -e "$path" && - die "'$path' already exists" - git ls-files --error-unmatch "$path" > /dev/null 2>&1 && die "'$path' already exists in the index" - module_clone "$path" "$realrepo" || exit - (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || - die "Unable to checkout submodule '$path'" + # perhaps the path exists and is already a git repo, else clone it + if test -e "$path" + then + if test -d "$path/.git" && + test "$(unset GIT_DIR; cd $path; git rev-parse --git-dir)" = ".git" + then + echo "Adding existing repo at '$path' to the index" + else + die "'$path' already exists and is not a valid git repo" + fi + else + case "$repo" in + ./*|../*) + # dereference source url relative to parent's url + realrepo="$(resolve_relative_url $repo)" ;; + *) + # Turn the source into an absolute path if + # it is local + if base=$(get_repo_base "$repo"); then + repo="$base" + fi + realrepo=$repo + ;; + esac + + module_clone "$path" "$realrepo" || exit + (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || + die "Unable to checkout submodule '$path'" + fi + git add "$path" || die "Failed to add submodule '$path'" -- 1.5.4.3.438.g4c6f8 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html