@ -59,27 +59,9 @@ static void print_error_files(struct string_list *files_list,
}
}
}
}
static void error_removing_concrete_submodules(struct string_list *files, int *errs)
static void submodules_absorb_gitdir_if_needed(const char *prefix)
{
print_error_files(files,
Q_("the following submodule (or one of its nested "
"submodules)\n"
"uses a .git directory:",
"the following submodules (or one of their nested "
"submodules)\n"
"use a .git directory:", files->nr),
_("\n(use 'rm -rf' if you really want to remove "
"it including all of its history)"),
errs);
string_list_clear(files, 0);
}
static int check_submodules_use_gitfiles(void)
{
{
int i;
int i;
int errs = 0;
struct string_list files = STRING_LIST_INIT_NODUP;
for (i = 0; i < list.nr; i++) {
for (i = 0; i < list.nr; i++) {
const char *name = list.entry[i].name;
const char *name = list.entry[i].name;
int pos;
int pos;
@ -99,12 +81,9 @@ static int check_submodules_use_gitfiles(void)
continue;
continue;
if (!submodule_uses_gitfile(name))
if (!submodule_uses_gitfile(name))
string_list_append(&files, name);
absorb_git_dir_into_superproject(prefix, name,
ABSORB_GITDIR_RECURSE_SUBMODULES);
}
}
error_removing_concrete_submodules(&files, &errs);
return errs;
}
}
static int check_local_mod(struct object_id *head, int index_only)
static int check_local_mod(struct object_id *head, int index_only)
@ -120,7 +99,6 @@ static int check_local_mod(struct object_id *head, int index_only)
int errs = 0;
int errs = 0;
struct string_list files_staged = STRING_LIST_INIT_NODUP;
struct string_list files_staged = STRING_LIST_INIT_NODUP;
struct string_list files_cached = STRING_LIST_INIT_NODUP;
struct string_list files_cached = STRING_LIST_INIT_NODUP;
struct string_list files_submodule = STRING_LIST_INIT_NODUP;
struct string_list files_local = STRING_LIST_INIT_NODUP;
struct string_list files_local = STRING_LIST_INIT_NODUP;
no_head = is_null_oid(head);
no_head = is_null_oid(head);
@ -219,13 +197,8 @@ static int check_local_mod(struct object_id *head, int index_only)
else if (!index_only) {
else if (!index_only) {
if (staged_changes)
if (staged_changes)
string_list_append(&files_cached, name);
string_list_append(&files_cached, name);
if (local_changes) {
if (local_changes)
if (S_ISGITLINK(ce->ce_mode) &&
string_list_append(&files_local, name);
!submodule_uses_gitfile(name))
string_list_append(&files_submodule, name);
else
string_list_append(&files_local, name);
}
}
}
}
}
print_error_files(&files_staged,
print_error_files(&files_staged,
@ -247,8 +220,6 @@ static int check_local_mod(struct object_id *head, int index_only)
&errs);
&errs);
string_list_clear(&files_cached, 0);
string_list_clear(&files_cached, 0);
error_removing_concrete_submodules(&files_submodule, &errs);
print_error_files(&files_local,
print_error_files(&files_local,
Q_("the following file has local modifications:",
Q_("the following file has local modifications:",
"the following files have local modifications:",
"the following files have local modifications:",
@ -342,6 +313,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
exit(0);
exit(0);
}
}
if (!index_only)
submodules_absorb_gitdir_if_needed(prefix);
/*
/*
* If not forced, the file, the index and the HEAD (if exists)
* If not forced, the file, the index and the HEAD (if exists)
* must match; but the file can already been removed, since
* must match; but the file can already been removed, since
@ -358,9 +332,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
oidclr(&oid);
oidclr(&oid);
if (check_local_mod(&oid, index_only))
if (check_local_mod(&oid, index_only))
exit(1);
exit(1);
} else if (!index_only) {
if (check_submodules_use_gitfiles())
exit(1);
}
}
/*
/*
@ -389,32 +360,20 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
*/
*/
if (!index_only) {
if (!index_only) {
int removed = 0, gitmodules_modified = 0;
int removed = 0, gitmodules_modified = 0;
struct strbuf buf = STRBUF_INIT;
for (i = 0; i < list.nr; i++) {
for (i = 0; i < list.nr; i++) {
const char *path = list.entry[i].name;
const char *path = list.entry[i].name;
if (list.entry[i].is_submodule) {
if (list.entry[i].is_submodule) {
if (is_empty_dir(path)) {
struct strbuf buf = STRBUF_INIT;
if (!rmdir(path)) {
removed = 1;
strbuf_addstr(&buf, path);
if (!remove_path_from_gitmodules(path))
if (remove_dir_recursively(&buf, 0))
gitmodules_modified = 1;
die(_("could not remove '%s'"), path);
continue;
strbuf_release(&buf);
}
} else {
removed = 1;
strbuf_reset(&buf);
if (!remove_path_from_gitmodules(path))
strbuf_addstr(&buf, path);
gitmodules_modified = 1;
if (!remove_dir_recursively(&buf, 0)) {
continue;
removed = 1;
if (!remove_path_from_gitmodules(path))
gitmodules_modified = 1;
strbuf_release(&buf);
continue;
} else if (!file_exists(path))
/* Submodule was removed by user */
if (!remove_path_from_gitmodules(path))
gitmodules_modified = 1;
/* Fallthrough and let remove_path() fail. */
}
}
}
if (!remove_path(path)) {
if (!remove_path(path)) {
removed = 1;
removed = 1;
@ -423,7 +382,6 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!removed)
if (!removed)
die_errno("git rm: '%s'", path);
die_errno("git rm: '%s'", path);
}
}
strbuf_release(&buf);
if (gitmodules_modified)
if (gitmodules_modified)
stage_updated_gitmodules();
stage_updated_gitmodules();
}
}