Thread (9 messages) flat view 9 messages, 3 authors, 2016-06-15

Re: [PATCH 2/2] git-submodule: support 'rm' command.

From: Jens Lehmann <hidden>
Date: 2016-06-15 22:54:10

Am 25.06.2012 12:57, schrieb Michał Górny:
Add an 'rm' command to git-submodule which provides means to
(semi-)easily remove git submodules.

Signed-off-by: Michał Górny <redacted>
---
Right now, it requires the submodule checkout to be removed manually
first (so it does not remove unstaged commits), and just removes
the index entry and module information from config.

I based it on 'cmd_add' code trying to preserve the original coding
standards.
I really like the goal of this patch but would prefer that "git rm"
learns how to remove submodules instead of adding more code to the
git-submodule.sh script.

Also it shouldn't be necessary for the user to remove the directory
by hand before running "git rm". At least all files recorded in the
submodule can be removed (and if the submodule uses a gitfile that
can be removed too). Then all that is left are untracked files the
user has to decide what to do with (which might be removed too when
running "git rm --recurse-submodules=untracked").
quoted hunk ↗ jump to hunk
 Documentation/git-submodule.txt |   12 +++++++
 git-submodule.sh                |   68 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index fbbbcb2..293c1bf 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git submodule' [--quiet] add [-b branch] [-f|--force]
 	      [--reference <repository>] [--] <repository> [<path>]
+'git submodule' [--quiet] rm <path>...
 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
 'git submodule' [--quiet] init [--] [<path>...]
 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
@@ -104,6 +105,17 @@ together in the same relative location, and only the
 superproject's URL needs to be provided: git-submodule will correctly
 locate the submodule using the relative URL in .gitmodules.
 
+rm::
+	Remove and unregister the submodules at given paths.
++
+This requires at least one <path> argument. The repository checkout
+existing at that directory needs to be removed manually from
+the filesystem prior to calling this command. Note that all local
+changes will be lost.
Me thinks without -f a "git rm" should only then remove a submodule
if no local modifications exist and current HEAD is part of a remote
branch (so you can't loose unpushed commits by accident). If the
submodule uses a gitfile a local branch might be sufficient for that,
as the git directory lives on.
++
+This command removes the submodule from the current git index,
+the .gitmodules file and the local repository config.
It should not be removed from .git/config by default. The user may
have special settings there and the presence in .git/config shows
he cared about having the submodule checked out, which should not
be revoked by just removing the submodule from the work tree.
Unless he removes the config from there himself he should get back
a populated submodule when he checks out an earlier commit and says
"git submodule update".
quoted hunk ↗ jump to hunk
 status::
 	Show the status of the submodules. This will print the SHA-1 of the
 	currently checked out commit for each submodule, along with the
diff --git a/git-submodule.sh b/git-submodule.sh
index fbf2faf..88fd414 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -6,6 +6,7 @@
 
 dashless=$(basename "$0" | sed -e 's/-/ /')
 USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
+   or: $dashless [--quiet] rm [--] <path>...
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
@@ -308,6 +309,71 @@ Use -f if you really want to add it." >&2
 }
 
 #
+# Remove submodules from the working tree, .gitmodules and the index
+#
+# $@ = submodule paths
+#
+cmd_rm()
+{
+	# parse $args after "submodule ... rm".
+	while test $# -ne 0
+	do
+		case "$1" in
+		--)
+			shift
+			break
+			;;
+		-*)
+			usage
+			;;
+		*)
+			break
+			;;
+		esac
+		shift
+	done
+
+	if test -z "$1"; then
+		usage
+	fi
+
+	while test $# -ne 0
+	do
+		sm_path=$1
+		shift
+
+		# normalize path:
+		# multiple //; leading ./; /./; /../; trailing /
+		sm_path=$(printf '%s/\n' "$sm_path" |
+			sed -e '
+				s|//*|/|g
+				s|^\(\./\)*||
+				s|/\./|/|g
+				:start
+				s|\([^/]*\)/\.\./||
+				tstart
+				s|/*$||
+			')
+		git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 ||
+		die "$(eval_gettext "'\$sm_path' does not exist in the index")"
+
+		if test -e "$sm_path"
+		then
+			die "$(eval_gettext "'\$sm_path' needs to be removed manually first")"
+		fi
+
+		git rm --cached "$sm_path" ||
+		die "$(eval_gettext "Failed to remove submodule '\$sm_path'")"
+
+		git config -f .gitmodules --remove-section submodule."$sm_path" &&
+		git add --force .gitmodules ||
+		die "$(eval_gettext "Failed to unregister submodule '\$sm_path'")"
+
+		git config --remove-section submodule."$sm_path"
+	done
+}
+
+#
 # Execute an arbitrary command sequence in each checked out
 # submodule
 #
@@ -996,7 +1062,7 @@ cmd_sync()
 while test $# != 0 && test -z "$command"
 do
 	case "$1" in
-	add | foreach | init | update | status | summary | sync)
+	add | rm | foreach | init | update | status | summary | sync)
 		command=$1
 		;;
 	-q|--quiet)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help