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

Revision v2 of 2 in this series.

Revisions (2)
  1. v1 [diff vs current]
  2. v2 current

[PATCH v2 9/9] git rm: remove submodule entries from .gitmodules

From: Peter Collingbourne <hidden>
Date: 2016-06-15 22:48:35
Subsystem: documentation, the rest · Maintainers: Jonathan Corbet, Linus Torvalds

This patch teaches "git rm" how to remove submodules from the
.gitmodules file.  The .gitmodules update is handled by an undocumented
subcommand to "git submodule" named "rmconfig".

Signed-off-by: Peter Collingbourne <redacted>
---
 Documentation/git-rm.txt   |    5 ++-
 builtin/rm.c               |   25 ++++++++++-
 git-submodule.sh           |   45 ++++++++++++++++++-
 t/t7409-submodule-mv-rm.sh |  105 ++++++++++++++++++++++++++++++++++++++++++++
 t/t7409-submodule-mv.sh    |   94 ---------------------------------------
 5 files changed, 177 insertions(+), 97 deletions(-)
 create mode 100755 t/t7409-submodule-mv-rm.sh
 delete mode 100755 t/t7409-submodule-mv.sh
diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index c21d19e..81c1bbd 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -7,7 +7,7 @@ git-rm - Remove files from the working tree and from the index
 
 SYNOPSIS
 --------
-'git rm' [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
+'git rm' [-f | --force] [-n] [-r] [-M] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
 
 DESCRIPTION
 -----------
@@ -49,6 +49,9 @@ OPTIONS
         Allow recursive removal when a leading directory name is
         given.
 
+-M::
+	Do not try to remove submodule entry in .gitmodules
+
 \--::
 	This option can be used to separate command-line options from
 	the list of files, (useful when filenames might be mistaken
diff --git a/builtin/rm.c b/builtin/rm.c
index 02ee259..3c26a43 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -9,6 +9,7 @@
 #include "cache-tree.h"
 #include "tree-walk.h"
 #include "parse-options.h"
+#include "run-command.h"
 
 static const char * const builtin_rm_usage[] = {
 	"git rm [options] [--] <file>...",
@@ -139,7 +140,7 @@ static int check_local_mod(unsigned char *head, int index_only)
 static struct lock_file lock_file;
 
 static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
-static int ignore_unmatch = 0;
+static int ignore_unmatch = 0, skip_module_update = 0;
 
 static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only),
@@ -149,6 +150,8 @@ static struct option builtin_rm_options[] = {
 	OPT_BOOLEAN('r', NULL,             &recursive,  "allow recursive removal"),
 	OPT_BOOLEAN( 0 , "ignore-unmatch", &ignore_unmatch,
 				"exit with a zero status even if nothing matched"),
+	OPT_BOOLEAN('M', NULL,             &skip_module_update,
+				"don't update submodule entries"),
 	OPT_END(),
 };
 
@@ -276,5 +279,25 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 			die("Unable to write new index file");
 	}
 
+	if (!skip_module_update)
+		for (i = 0; i < list.nr; i++) {
+			if (S_ISGITLINK(list.mode[i])) {
+				const char *path = list.name[i];
+
+				const char *argv_submodule[] = {
+					"submodule", "rmconfig", NULL, NULL, NULL, NULL
+				};
+				int argc = 2;
+
+				if (index_only)
+					argv_submodule[argc++] = "--cached";
+
+				argv_submodule[argc++] = "--";
+				argv_submodule[argc++] = path;
+
+				run_command_v_opt(argv_submodule, RUN_GIT_CMD);
+			}
+		}
+
 	return 0;
 }
diff --git a/git-submodule.sh b/git-submodule.sh
index 75c50b8..baadaa5 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -879,6 +879,49 @@ cmd_mvconfig()
 		die "Could not update .gitmodules entry for $name"
 	git add .gitmodules || die "Could not add .gitmodules to index"
 }
+#
+# Removes the entry in .gitmodules to remove a submodule.
+# This command is called by "git rm" for each submodule it removes.
+#
+cmd_rmconfig()
+{
+	while test $# -ne 0
+	do
+		case "$1" in
+		--cached)
+			index_only=1
+			shift
+			;;
+		--)
+			shift
+			break
+			;;
+		*)
+			break
+			;;
+		esac
+	done
+	path="$1"
+
+	if test -z "$index_only"
+	then
+		name=$(module_name "$path") || exit
+		git config -f .gitmodules --remove-section submodule."$name" ||
+			die "Could not update .gitmodules entry for $name"
+		git add .gitmodules || die "Could not add .gitmodules to index"
+	else
+		git cat-file -p :0:.gitmodules > .git/gitmodules.index ||
+			{ rm .git/gitmodules.index; die "Could not extract .gitmodules from index"; }
+		name=$(module_name "$path" .git/gitmodules.index) || { rm .git/gitmodules.index; exit; }
+		git config -f .git/gitmodules.index --remove-section submodule."$name" ||
+			{ rm .git/gitmodules.index; die "Could not update .gitmodules entry for $name"; }
+		blob=$(git hash-object -w --stdin < .git/gitmodules.index) ||
+			{ rm .git/gitmodules.index; die "Could not create blob for .gitmodules"; }
+		rm .git/gitmodules.index || die "Could not remove temporary .gitmodules file"
+		git update-index --cacheinfo 100644 "$blob" .gitmodules ||
+			die "Could not add .gitmodules to index"
+	fi
+}
 
 # This loop parses the command line arguments to find the
 # subcommand name to dispatch.  Parsing of the subcommand specific
@@ -889,7 +932,7 @@ cmd_mvconfig()
 while test $# != 0 && test -z "$command"
 do
 	case "$1" in
-	add | foreach | init | update | status | summary | sync | mvconfig)
+	add | foreach | init | update | status | summary | sync | mvconfig | rmconfig)
 		command=$1
 		;;
 	-q|--quiet)
diff --git a/t/t7409-submodule-mv-rm.sh b/t/t7409-submodule-mv-rm.sh
new file mode 100755
index 0000000..91b7866
--- /dev/null
+++ b/t/t7409-submodule-mv-rm.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Peter Collingbourne
+#
+
+test_description='git submodule mv, rm
+
+These tests exercise the "git mv" and "git rm" commands for submodules.
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	echo file > file &&
+	git add file &&
+	test_tick &&
+	git commit -m upstream
+	git clone . super &&
+	git clone super submodule &&
+	(cd super &&
+	 git submodule add -n reg ../submodule reg &&
+	 git clone reg unreg &&
+	 git add unreg &&
+	 test_tick &&
+	 git commit -m "submodules"
+	)'
+
+test_expect_success 'move registered submodule' '
+	(cd super &&
+	 git mv reg reg2 &&
+	 test -z "$(git ls-files reg)" &&
+	 test -n "$(git ls-files reg2)" &&
+	 test ! -d reg &&
+	 test -d reg2 &&
+	 test -d reg2/.git &&
+	 test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
+	 test_tick &&
+	 git commit -a -m "move reg"
+	)
+'
+
+test_expect_success 'move unregistered submodule' '
+	(cd super &&
+	 git mv unreg unreg2 &&
+	 test ! -d unreg &&
+	 test -d unreg2 &&
+	 test -d unreg2/.git &&
+	 test_tick &&
+	 git commit -a -m "move unreg"
+	)
+'
+
+test_expect_success 'move unregistered uninitialised submodule' '
+	(cd super &&
+	 rm -rf unreg2 &&
+	 mkdir unreg2 &&
+	 git mv unreg2 unreg &&
+	 test -z "$(git ls-files unreg2)" &&
+	 test -n "$(git ls-files unreg)" &&
+	 test ! -d unreg2 &&
+	 test -d unreg &&
+	 test_tick &&
+	 git commit -a -m "move unreg2"
+	)
+'
+
+test_expect_success 'move registered submodule without changing .gitmodules' '
+	(cd super &&
+	 git mv -M reg2 reg &&
+	 test ! -d reg2 &&
+	 test -d reg &&
+	 test -d reg/.git &&
+	 test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
+	 git mv -M reg reg2
+	)
+'
+
+test_expect_success 'move multiple submodules at once' '
+	(cd super &&
+	 mkdir test\ dir &&
+	 git mv unreg reg2 test\ dir/ &&
+	 test ! -d unreg && 
+	 test ! -d reg2 && 
+	 test -d test\ dir/unreg && 
+	 test -d test\ dir/reg2 && 
+	 test -z "$(git ls-files unreg)" &&
+	 test -n "$(git ls-files test\ dir/unreg)" &&
+	 test -z "$(git ls-files reg2)" &&
+	 test -n "$(git ls-files test\ dir/reg2)" &&
+	 test "$(git config -f .gitmodules submodule.reg.path)" = "test dir/reg2"
+	)
+'
+
+test_expect_success 'remove multiple submodules at once' '
+	(cd super &&
+	 git rm -r test\ dir &&
+	 test ! -d test\ dir/unreg && 
+	 test -d test\ dir/reg2 && 
+	 test -z "$(git ls-files test\ dir/unreg)" &&
+	 test -z "$(git ls-files test\ dir/reg2)" &&
+	 test -z "$(git config -f .gitmodules submodule.reg.path)"
+	)
+'
+
+test_done
diff --git a/t/t7409-submodule-mv.sh b/t/t7409-submodule-mv.sh
deleted file mode 100755
index 9eb3fb1..0000000
--- a/t/t7409-submodule-mv.sh
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Peter Collingbourne
-#
-
-test_description='git submodule mv
-
-These tests exercise the "git mv" command for submodules.
-'
-
-. ./test-lib.sh
-
-test_expect_success setup '
-	echo file > file &&
-	git add file &&
-	test_tick &&
-	git commit -m upstream
-	git clone . super &&
-	git clone super submodule &&
-	(cd super &&
-	 git submodule add -n reg ../submodule reg &&
-	 git clone reg unreg &&
-	 git add unreg &&
-	 test_tick &&
-	 git commit -m "submodules"
-	)'
-
-test_expect_success 'move registered submodule' '
-	(cd super &&
-	 git mv reg reg2 &&
-	 test -z "$(git ls-files reg)" &&
-	 test -n "$(git ls-files reg2)" &&
-	 test ! -d reg &&
-	 test -d reg2 &&
-	 test -d reg2/.git &&
-	 test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
-	 test_tick &&
-	 git commit -a -m "move reg"
-	)
-'
-
-test_expect_success 'move unregistered submodule' '
-	(cd super &&
-	 git mv unreg unreg2 &&
-	 test ! -d unreg &&
-	 test -d unreg2 &&
-	 test -d unreg2/.git &&
-	 test_tick &&
-	 git commit -a -m "move unreg"
-	)
-'
-
-test_expect_success 'move unregistered uninitialised submodule' '
-	(cd super &&
-	 rm -rf unreg2 &&
-	 mkdir unreg2 &&
-	 git mv unreg2 unreg &&
-	 test -z "$(git ls-files unreg2)" &&
-	 test -n "$(git ls-files unreg)" &&
-	 test ! -d unreg2 &&
-	 test -d unreg &&
-	 test_tick &&
-	 git commit -a -m "move unreg2"
-	)
-'
-
-test_expect_success 'move registered submodule without changing .gitmodules' '
-	(cd super &&
-	 git mv -M reg2 reg &&
-	 test ! -d reg2 &&
-	 test -d reg &&
-	 test -d reg/.git &&
-	 test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
-	 git mv -M reg reg2
-	)
-'
-
-test_expect_success 'move multiple submodules at once' '
-	(cd super &&
-	 mkdir test\ dir &&
-	 git mv unreg reg2 test\ dir/ &&
-	 test ! -d unreg && 
-	 test ! -d reg2 && 
-	 test -d test\ dir/unreg && 
-	 test -d test\ dir/reg2 && 
-	 test -z "$(git ls-files unreg)" &&
-	 test -n "$(git ls-files test\ dir/unreg)" &&
-	 test -z "$(git ls-files reg2)" &&
-	 test -n "$(git ls-files test\ dir/reg2)" &&
-	 test "$(git config -f .gitmodules submodule.reg.path)" = "test dir/reg2"
-	)
-'
-
-test_done
-- 
1.6.5
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help