aboutsummaryrefslogtreecommitdiff
path: root/submodule.c
diff options
context:
space:
mode:
authorStefan Beller <sbeller@google.com>2016-12-20 15:20:11 -0800
committerJunio C Hamano <gitster@pobox.com>2016-12-27 14:19:35 -0800
commit83b7696605dbea3eb4e878cf904159f398345aa9 (patch)
treed1fe20f8be9d48bf1f37289339d4d571d87fdb1a /submodule.c
parent5a1c824f70ec261f8f9e5e039555fc80301dee0b (diff)
downloadgit-83b7696605dbea3eb4e878cf904159f398345aa9.tar.gz
git-83b7696605dbea3eb4e878cf904159f398345aa9.tar.xz
submodule: rename and add flags to ok_to_remove_submodule
In different contexts the question "Is it ok to delete a submodule?" may be answered differently. In 293ab15eea (submodule: teach rm to remove submodules unless they contain a git directory, 2012-09-26) a case was made that we can safely ignore ignored untracked files for removal as we explicitely ask for the removal of the submodule. In a later patch we want to remove submodules even when the user doesn't explicitly ask for it (e.g. checking out a tree-ish in which the submodule doesn't exist). In that case we want to be more careful when it comes to deletion of untracked files. As of this patch it is unclear how this will be implemented exactly, so we'll offer flags in which the caller can specify how the different untracked files ought to be handled. As the flags allow the function to not die on an error when spawning a child process, we need to find an appropriate return code for the case when the child process could not be started. As in that case we cannot tell if the submodule is ok to remove, we'd want to return 'false'. As only 0 is understood as false, rename the function to invert the meaning, i.e. the return code of 0 signals the removal of the submodule is fine, and other values can be used to return a more precise answer what went wrong. Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'submodule.c')
-rw-r--r--submodule.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/submodule.c b/submodule.c
index 9f0b544eb..1cc04d24e 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1019,39 +1019,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;
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", "-u",
+ 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");
+
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 -u --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 -u --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,