aboutsummaryrefslogtreecommitdiff
path: root/submodule.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-01-18 15:12:11 -0800
committerJunio C Hamano <gitster@pobox.com>2017-01-18 15:12:11 -0800
commit3ccd681c2ab11522591be8a7a3eddb1a85a43ab0 (patch)
treef876b1d4639222cdd7e8e2812807b093ba7b9538 /submodule.c
parent55d128ae06b7b82f867961b677984620612a201c (diff)
parent55856a35b20dae2499d4e0b23551c7ba9a33baf2 (diff)
downloadgit-3ccd681c2ab11522591be8a7a3eddb1a85a43ab0.tar.gz
git-3ccd681c2ab11522591be8a7a3eddb1a85a43ab0.tar.xz
Merge branch 'sb/submodule-rm-absorb'
"git rm" used to refuse to remove a submodule when it has its own git repository embedded in its working tree. It learned to move the repository away to $GIT_DIR/modules/ of the superproject instead, and allow the submodule to be deleted (as long as there will be no loss of local modifications, that is). * sb/submodule-rm-absorb: rm: absorb a submodules git dir before deletion submodule: rename and add flags to ok_to_remove_submodule submodule: modernize ok_to_remove_submodule to use argv_array submodule.h: add extern keyword to functions
Diffstat (limited to 'submodule.c')
-rw-r--r--submodule.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/submodule.c b/submodule.c
index f8fee3dfd..11ff11ed8 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1143,45 +1143,64 @@ int submodule_uses_gitfile(const char *path)
return 1;
}
-int ok_to_remove_submodule(const char *path)
+/*
+ * Check if it is a bad idea to remove a submodule, i.e. if we'd lose data
+ * when doing so.
+ *
+ * Return 1 if we'd lose data, return 0 if the removal is fine,
+ * and negative values for errors.
+ */
+int bad_to_remove_submodule(const char *path, unsigned flags)
{
ssize_t len;
struct child_process cp = CHILD_PROCESS_INIT;
- const char *argv[] = {
- "status",
- "--porcelain",
- "-u",
- "--ignore-submodules=none",
- NULL,
- };
struct strbuf buf = STRBUF_INIT;
- int ok_to_remove = 1;
+ int ret = 0;
if (!file_exists(path) || is_empty_dir(path))
- return 1;
+ return 0;
if (!submodule_uses_gitfile(path))
- return 0;
+ return 1;
+
+ argv_array_pushl(&cp.args, "status", "--porcelain",
+ "--ignore-submodules=none", NULL);
+
+ if (flags & SUBMODULE_REMOVAL_IGNORE_UNTRACKED)
+ argv_array_push(&cp.args, "-uno");
+ else
+ argv_array_push(&cp.args, "-uall");
+
+ if (!(flags & SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED))
+ argv_array_push(&cp.args, "--ignored");
- cp.argv = argv;
prepare_submodule_repo_env(&cp.env_array);
cp.git_cmd = 1;
cp.no_stdin = 1;
cp.out = -1;
cp.dir = path;
- if (start_command(&cp))
- die("Could not run 'git status --porcelain -uall --ignore-submodules=none' in submodule %s", path);
+ if (start_command(&cp)) {
+ if (flags & SUBMODULE_REMOVAL_DIE_ON_ERROR)
+ die(_("could not start 'git status in submodule '%s'"),
+ path);
+ ret = -1;
+ goto out;
+ }
len = strbuf_read(&buf, cp.out, 1024);
if (len > 2)
- ok_to_remove = 0;
+ ret = 1;
close(cp.out);
- if (finish_command(&cp))
- die("'git status --porcelain -uall --ignore-submodules=none' failed in submodule %s", path);
-
+ if (finish_command(&cp)) {
+ if (flags & SUBMODULE_REMOVAL_DIE_ON_ERROR)
+ die(_("could not run 'git status in submodule '%s'"),
+ path);
+ ret = -1;
+ }
+out:
strbuf_release(&buf);
- return ok_to_remove;
+ return ret;
}
static int find_first_merges(struct object_array *result, const char *path,