git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[WIP/PATCH 7/9] submodule: teach unpack_trees() to remove submodule contents

From
Jens Lehmann <jens.lehmann@web.de>
Date
Feb 3, 2014, 19:52 UTC
Message-ID
<52EFF391.7040503@web.de>
In-Reply-To
<52EFF25E.6080306@web.de>

Implement the functionality needed to enable work tree manipulating commands to that a deleted submodule should not only affect the index (leaving all the files of the submodule in the work tree) but also to remove the work tree of the superproject (including any untracked files).

That will only work properly when the submodule uses a gitfile instead of a .git directory and no untracked files are present. Otherwise the removal will fail with a warning (which is just what happened until now).

Extend rmdir_or_warn() to remove the directories of those submodules which are scheduled for removal. Also teach verify_clean_submodule() to check that a submodule configured to be removed is not modified before scheduling it for removal.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---
 submodule.c    | 37 +++++++++++++++++++++++++++++++++++++
 submodule.h    |  1 +
 unpack-trees.c |  7 ++++---
 wrapper.c      |  3 +++
 4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/submodule.c b/submodule.c
index 448b645..f292e9e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -447,6 +447,43 @@ int submodule_needs_update(const char *path)
 	return config_update_recurse_submodules != RECURSE_SUBMODULES_OFF;
 }

+int depopulate_submodule(const char *path)
+{
+	struct strbuf dot_git = STRBUF_INIT;
+	struct child_process cp;
+	const char *argv[] = {"rm", "-rf", path, NULL};
+
+	/* Is it populated? */
+	strbuf_addf(&dot_git, "%s/.git", path);
+	if (!resolve_gitdir(dot_git.buf)) {
+		strbuf_release(&dot_git);
+		return 0;
+	}
+	strbuf_release(&dot_git);
+
+	/* Does it have a .git directory? */
+	if (!submodule_uses_gitfile(path)) {
+		warning(_("cannot remove submodule '%s' because it (or one of "
+			  "its nested submodules) uses a .git directory"),
+			  path);
+		return -1;
+	}
+
+	/* Remove the whole submodule directory */
+	memset(&cp, 0, sizeof(cp));
+	cp.argv = argv;
+	cp.env = local_repo_env;
+	cp.git_cmd = 0;
+	cp.no_stdin = 1;
+	if (run_command(&cp)) {
+		warning("Could not remove submodule %s", path);
+		strbuf_release(&dot_git);
+		return -1;
+	}
+
+	return 0;
+}
+
 void show_submodule_summary(FILE *f, const char *path,
 		const char *line_prefix,
 		unsigned char one[20], unsigned char two[20],
diff --git a/submodule.h b/submodule.h
index 5958010..2139e08 100644
--- a/submodule.h
+++ b/submodule.h
@@ -28,6 +28,7 @@ int parse_update_recurse_submodules_arg(const char *opt, const char *arg);
 int option_parse_update_submodules(const struct option *opt,
 		const char *arg, int unset);
 int submodule_needs_update(const char *path);
+int depopulate_submodule(const char *path);
 void show_submodule_summary(FILE *f, const char *path,
 		const char *line_prefix,
 		unsigned char one[20], unsigned char two[20],
diff --git a/unpack-trees.c b/unpack-trees.c
index 164354d..82c99eb 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -8,6 +8,7 @@
 #include "progress.h"
 #include "refs.h"
 #include "attr.h"
+#include "submodule.h"

 /*
  * Error messages expected by scripts out of plumbing commands such as
@@ -1266,14 +1267,14 @@ static void invalidate_ce_path(const struct cache_entry *ce,
 /*
  * Check that checking out ce->sha1 in subdir ce->name is not
  * going to overwrite any working files.
- *
- * Currently, git does not checkout subprojects during a superproject
- * checkout, so it is not going to overwrite anything.
  */
 static int verify_clean_submodule(const struct cache_entry *ce,
 				  enum unpack_trees_error_types error_type,
 				  struct unpack_trees_options *o)
 {
+	if (submodule_needs_update(ce->name) &&
+	    is_submodule_modified(ce->name, 0))
+		return 1;
 	return 0;
 }

diff --git a/wrapper.c b/wrapper.c
index 0cc5636..425a3fd 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -2,6 +2,7 @@
  * Various trivial helper wrappers around standard functions
  */
 #include "cache.h"
+#include "submodule.h"

 static void do_nothing(size_t size)
 {
@@ -409,6 +410,8 @@ int unlink_or_warn(const char *file)

 int rmdir_or_warn(const char *file)
 {
+	if (submodule_needs_update(file) && depopulate_submodule(file))
+		return -1;
 	return warn_if_unremovable("rmdir", file, rmdir(file));
 }
-- 
1.9.rc0.28.ge3363ff
Previous: Jens LehmannNext: W. Trevor King
Message 27 of 35 in “What's cooking in git.git (Jan 2014, #01; Mon, 6)”
  1. Junio C HamanoJan 6, 2014
  2. Francesco PrettoJan 6, 2014
  3. Junio C HamanoJan 6, 2014
  4. Francesco PrettoJan 6, 2014
  5. Jens LehmannJan 7, 2014
  6. 0/9 v2 submodule recursive checkout]Jens Lehmann, Feb 3, 2014
  7. 1/9 submodule: prepare for recursive checkout of submodulesJens Lehmann, Feb 3, 2014
  8. Junio C HamanoFeb 3, 2014
  9. Jens LehmannFeb 7, 2014
  10. Jonathan NiederFeb 4, 2014
  11. Jens LehmannFeb 7, 2014
  12. 2/9 Teach reset the --[no-]recurse-submodules optionJens Lehmann, Feb 3, 2014
  13. Junio C HamanoFeb 3, 2014
  14. Jens LehmannFeb 7, 2014
  15. 3/9 Teach checkout the --[no-]recurse-submodules optionJens Lehmann, Feb 3, 2014
  16. Junio C HamanoFeb 3, 2014
  17. Jens LehmannFeb 7, 2014
  18. 4/9 Teach merge the --[no-]recurse-submodules optionJens Lehmann, Feb 3, 2014
  19. Junio C HamanoFeb 3, 2014
  20. Jens LehmannFeb 7, 2014
  21. Junio C HamanoFeb 7, 2014
  22. W. Trevor KingFeb 7, 2014
  23. 5/9 Teach bisect--helper the --[no-]recurse-submodules optionJens Lehmann, Feb 3, 2014
  24. 6/9 Teach bisect the --[no-]recurse-submodules optionJens Lehmann, Feb 3, 2014
  25. W. Trevor KingFeb 3, 2014
  26. Jens LehmannFeb 3, 2014
  27. 7/9 submodule: teach unpack_trees() to remove submodule contentsJens Lehmann, Feb 3, 2014
  28. W. Trevor KingFeb 3, 2014
  29. Jens LehmannFeb 7, 2014
  30. 8/9 submodule: teach unpack_trees() to repopulate submodulesJens Lehmann, Feb 3, 2014
  31. 9/9 submodule: teach unpack_trees() to update submodulesJens Lehmann, Feb 3, 2014
  32. W. Trevor KingFeb 3, 2014
  33. Jens LehmannFeb 7, 2014
  34. Duy NguyenFeb 4, 2014
  35. Jens LehmannFeb 7, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.