git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Beller <sbeller@google.com>
To: bmwill@google.com, David.Turner@twosigma.com
Cc: git@vger.kernel.org, sandals@crustytoothpaste.net,
	hvoigt@hvoigt.net, gitster@pobox.com,
	Stefan Beller <sbeller@google.com>
Subject: [RFC PATCHv2 08/17] update submodules: add depopulate_submodule
Date: Fri,  2 Dec 2016 16:30:13 -0800	[thread overview]
Message-ID: <20161203003022.29797-9-sbeller@google.com> (raw)
In-Reply-To: <20161203003022.29797-1-sbeller@google.com>

Implement the functionality needed to enable work tree manipulating
commands so 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).

To do so, we need an equivalent of "rm -rf", which is already found in
entry.c, so expose that and for clarity add a suffix "_or_dir" to it.

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).

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 cache.h     |  2 ++
 entry.c     |  5 +++++
 submodule.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 submodule.h |  1 +
 4 files changed, 54 insertions(+)

diff --git a/cache.h b/cache.h
index a50a61a197..b645ca2f9a 100644
--- a/cache.h
+++ b/cache.h
@@ -2018,4 +2018,6 @@ void sleep_millisec(int millisec);
  */
 void safe_create_dir(const char *dir, int share);
 
+extern void remove_directory_or_die(struct strbuf *path);
+
 #endif /* CACHE_H */
diff --git a/entry.c b/entry.c
index c6eea240b6..02c4ac9f22 100644
--- a/entry.c
+++ b/entry.c
@@ -73,6 +73,11 @@ static void remove_subtree(struct strbuf *path)
 		die_errno("cannot rmdir '%s'", path->buf);
 }
 
+void remove_directory_or_die(struct strbuf *path)
+{
+	remove_subtree(path);
+}
+
 static int create_file(const char *path, unsigned int mode)
 {
 	mode = (mode & 0100) ? 0777 : 0666;
diff --git a/submodule.c b/submodule.c
index 62e9ef3872..7bb64d6c69 100644
--- a/submodule.c
+++ b/submodule.c
@@ -324,6 +324,52 @@ void prepare_submodule_repo_env(struct argv_array *out)
 	argv_array_push(out, "GIT_DIR=.git");
 }
 
+int depopulate_submodule(const char *path)
+{
+	int ret = 0;
+	struct strbuf pathbuf = STRBUF_INIT;
+	char *dot_git = xstrfmt("%s/.git", path);
+
+	/* Is it populated? */
+	if (!resolve_gitdir(dot_git))
+		goto out;
+
+	/* Does it have a .git directory? */
+	if (!submodule_uses_gitfile(path)) {
+		struct child_process cp = CHILD_PROCESS_INIT;
+
+		prepare_submodule_repo_env(&cp.env_array);
+		argv_array_pushl(&cp.args, "submodule--helper",
+				 "embed-git-dirs", path, NULL);
+		cp.git_cmd = 1;
+		if (run_command(&cp)) {
+			warning(_("Cannot remove submodule '%s'\n"
+				  "because it (or one of its nested submodules) has a git \n"
+				  "directory in the working tree, which could not be embedded\n"
+				  "the superprojects git directory automatically."), path);
+			ret = -1;
+			goto out;
+		}
+
+		if (!submodule_uses_gitfile(path)) {
+			/*
+			 * We should be using a gitfile by now, let's double
+			 * check as loosing the git dir would be fatal.
+			 */
+			die("BUG: \"git submodule--helper embed git-dirs '%s'\" "
+			    "did not embed the git-dirs recursively for '%s'",
+			    path, path);
+		}
+	}
+
+	strbuf_addstr(&pathbuf, path);
+	remove_directory_or_die(&pathbuf);
+out:
+	strbuf_release(&pathbuf);
+	free(dot_git);
+	return ret;
+}
+
 /* Helper function to display the submodule header line prior to the full
  * summary output. If it can locate the submodule objects directory it will
  * attempt to lookup both the left and right commits and put them into the
diff --git a/submodule.h b/submodule.h
index 7d890e0464..d8bb1d4baf 100644
--- a/submodule.h
+++ b/submodule.h
@@ -63,6 +63,7 @@ extern void set_config_update_recurse_submodules(int value);
  */
 extern int submodule_is_interesting(const char *path);
 extern int submodules_interesting_for_update(void);
+extern int depopulate_submodule(const char *path);
 extern void check_for_new_submodule_commits(unsigned char new_sha1[20]);
 extern int fetch_populated_submodules(const struct argv_array *options,
 			       const char *prefix, int command_line_option,
-- 
2.11.0.rc2.28.g2673dad


  parent reply	other threads:[~2016-12-03  0:31 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-03  0:30 [RFC PATCHv2 00/17] Checkout aware of Submodules! Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 01/17] submodule.h: add extern keyword to functions Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 02/17] submodule: modernize ok_to_remove_submodule to use argv_array Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 03/17] update submodules: move up prepare_submodule_repo_env Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 04/17] update submodules: add is_submodule_populated Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 05/17] update submodules: add submodule config parsing Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 06/17] update submodules: add a config option to determine if submodules are updated Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 07/17] update submodules: introduce submodule_is_interesting Stefan Beller
2016-12-03  0:30 ` Stefan Beller [this message]
2016-12-05 23:37   ` [RFC PATCHv2 08/17] update submodules: add depopulate_submodule David Turner
2016-12-06  0:18     ` Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 09/17] update submodules: add scheduling to update submodules Stefan Beller
2016-12-05 23:37   ` David Turner
2016-12-05 23:54     ` Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 10/17] update submodules: is_submodule_checkout_safe Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 11/17] unpack-trees: teach verify_clean_submodule to inspect submodules Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 12/17] unpack-trees: remove submodule contents if interesting Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 13/17] entry: write_entry to write populate submodules Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 14/17] submodule: teach unpack_trees() to update submodules Stefan Beller
2016-12-05 23:37   ` David Turner
2016-12-03  0:30 ` [RFC PATCHv2 15/17] checkout: recurse into submodules if asked to Stefan Beller
2016-12-05 19:25   ` Brandon Williams
2016-12-05 19:30     ` Stefan Beller
2016-12-05 19:31       ` Brandon Williams
2016-12-05 23:36   ` David Turner
2016-12-03  0:30 ` [RFC PATCHv2 16/17] completion: add '--recurse-submodules' to checkout Stefan Beller
2016-12-03  0:30 ` [RFC PATCHv2 17/17] checkout: add config option to recurse into submodules by default Stefan Beller
2016-12-05 19:29   ` Brandon Williams
2016-12-05 22:23     ` Stefan Beller
2016-12-05 22:26       ` Brandon Williams

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20161203003022.29797-9-sbeller@google.com \
    --to=sbeller@google.com \
    --cc=David.Turner@twosigma.com \
    --cc=bmwill@google.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hvoigt@hvoigt.net \
    --cc=sandals@crustytoothpaste.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).