Skip to content

Commit 83b7696

Browse files
stefanbellergitster
authored andcommitted
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 293ab15 (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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5a1c824 commit 83b7696

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

builtin/rm.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ static int check_local_mod(struct object_id *head, int index_only)
187187
*/
188188
if (ce_match_stat(ce, &st, 0) ||
189189
(S_ISGITLINK(ce->ce_mode) &&
190-
!ok_to_remove_submodule(ce->name)))
190+
bad_to_remove_submodule(ce->name,
191+
SUBMODULE_REMOVAL_DIE_ON_ERROR |
192+
SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED)))
191193
local_changes = 1;
192194

193195
/*

submodule.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,39 +1019,64 @@ int submodule_uses_gitfile(const char *path)
10191019
return 1;
10201020
}
10211021

1022-
int ok_to_remove_submodule(const char *path)
1022+
/*
1023+
* Check if it is a bad idea to remove a submodule, i.e. if we'd lose data
1024+
* when doing so.
1025+
*
1026+
* Return 1 if we'd lose data, return 0 if the removal is fine,
1027+
* and negative values for errors.
1028+
*/
1029+
int bad_to_remove_submodule(const char *path, unsigned flags)
10231030
{
10241031
ssize_t len;
10251032
struct child_process cp = CHILD_PROCESS_INIT;
10261033
struct strbuf buf = STRBUF_INIT;
1027-
int ok_to_remove = 1;
1034+
int ret = 0;
10281035

10291036
if (!file_exists(path) || is_empty_dir(path))
1030-
return 1;
1037+
return 0;
10311038

10321039
if (!submodule_uses_gitfile(path))
1033-
return 0;
1040+
return 1;
10341041

1035-
argv_array_pushl(&cp.args, "status", "--porcelain", "-u",
1042+
argv_array_pushl(&cp.args, "status", "--porcelain",
10361043
"--ignore-submodules=none", NULL);
1044+
1045+
if (flags & SUBMODULE_REMOVAL_IGNORE_UNTRACKED)
1046+
argv_array_push(&cp.args, "-uno");
1047+
else
1048+
argv_array_push(&cp.args, "-uall");
1049+
1050+
if (!(flags & SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED))
1051+
argv_array_push(&cp.args, "--ignored");
1052+
10371053
prepare_submodule_repo_env(&cp.env_array);
10381054
cp.git_cmd = 1;
10391055
cp.no_stdin = 1;
10401056
cp.out = -1;
10411057
cp.dir = path;
1042-
if (start_command(&cp))
1043-
die(_("could not run 'git status --porcelain -u --ignore-submodules=none' in submodule %s"), path);
1058+
if (start_command(&cp)) {
1059+
if (flags & SUBMODULE_REMOVAL_DIE_ON_ERROR)
1060+
die(_("could not start 'git status in submodule '%s'"),
1061+
path);
1062+
ret = -1;
1063+
goto out;
1064+
}
10441065

10451066
len = strbuf_read(&buf, cp.out, 1024);
10461067
if (len > 2)
1047-
ok_to_remove = 0;
1068+
ret = 1;
10481069
close(cp.out);
10491070

1050-
if (finish_command(&cp))
1051-
die(_("'git status --porcelain -u --ignore-submodules=none' failed in submodule %s"), path);
1052-
1071+
if (finish_command(&cp)) {
1072+
if (flags & SUBMODULE_REMOVAL_DIE_ON_ERROR)
1073+
die(_("could not run 'git status in submodule '%s'"),
1074+
path);
1075+
ret = -1;
1076+
}
1077+
out:
10531078
strbuf_release(&buf);
1054-
return ok_to_remove;
1079+
return ret;
10551080
}
10561081

10571082
static int find_first_merges(struct object_array *result, const char *path,

submodule.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,11 @@ extern int fetch_populated_submodules(const struct argv_array *options,
5959
int quiet, int max_parallel_jobs);
6060
extern unsigned is_submodule_modified(const char *path, int ignore_untracked);
6161
extern int submodule_uses_gitfile(const char *path);
62-
extern int ok_to_remove_submodule(const char *path);
62+
63+
#define SUBMODULE_REMOVAL_DIE_ON_ERROR (1<<0)
64+
#define SUBMODULE_REMOVAL_IGNORE_UNTRACKED (1<<1)
65+
#define SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED (1<<2)
66+
extern int bad_to_remove_submodule(const char *path, unsigned flags);
6367
extern int merge_submodule(unsigned char result[20], const char *path,
6468
const unsigned char base[20],
6569
const unsigned char a[20],

0 commit comments

Comments
 (0)