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
This commit is contained in:
59
submodule.c
59
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;
|
||||
|
||||
if (!submodule_uses_gitfile(path))
|
||||
return 0;
|
||||
|
||||
cp.argv = argv;
|
||||
if (!submodule_uses_gitfile(path))
|
||||
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");
|
||||
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user