Skip to content

Commit 0dc66d1

Browse files
committed
read-cache: let read-cache respect submodule ignore=all and --force
The submomodule path reference update is skipped if: - the ignore=all configuration is set on the submodule unless: - the --force option is also given and the submodule path is explicit given. A message is printed (like ignored files) guiding the user to use the --force flag if the user has explicitely want to update the submodule reference. Signed-off-by: Claus Schneider(Eficode) <claus.schneider@eficode.com>
1 parent 95a66a1 commit 0dc66d1

File tree

1 file changed

+47
-1
lines changed

1 file changed

+47
-1
lines changed

read-cache.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
#include "csum-file.h"
4949
#include "promisor-remote.h"
5050
#include "hook.h"
51+
#include "submodule.h"
52+
#include "submodule-config.h"
5153

5254
/* Mask for the name length in ce_flags in the on-disk index */
5355

@@ -3927,13 +3929,57 @@ static void update_callback(struct diff_queue_struct *q,
39273929
default:
39283930
die(_("unexpected diff status %c"), p->status);
39293931
case DIFF_STATUS_MODIFIED:
3930-
case DIFF_STATUS_TYPE_CHANGED:
3932+
case DIFF_STATUS_TYPE_CHANGED: {
3933+
struct stat st;
3934+
if (!lstat(path, &st) && S_ISDIR(st.st_mode)) { // only consider submodule if it is a directory
3935+
const struct submodule *sub = submodule_from_path(data->repo, null_oid(the_hash_algo), path);
3936+
if (sub && sub->name && sub->ignore && !strcmp(sub->ignore, "all")) {
3937+
int pathspec_matches = 0;
3938+
char *norm_pathspec = NULL;
3939+
int ps_i;
3940+
trace_printf("ignore=all %s\n", path);
3941+
trace_printf("pathspec %s\n",
3942+
(data->pathspec && data->pathspec->nr) ? "has pathspec" : "no pathspec");
3943+
/* Safely scan all pathspec items (q->nr may exceed pathspec->nr). */
3944+
if (data->pathspec) {
3945+
for (ps_i = 0; ps_i < data->pathspec->nr; ps_i++) {
3946+
const char *m = data->pathspec->items[ps_i].match;
3947+
if (!m)
3948+
continue;
3949+
norm_pathspec = xstrdup(m);
3950+
strip_dir_trailing_slashes(norm_pathspec);
3951+
if (!strcmp(path, norm_pathspec)) {
3952+
pathspec_matches = 1;
3953+
free(norm_pathspec);
3954+
norm_pathspec = NULL;
3955+
break;
3956+
}
3957+
free(norm_pathspec);
3958+
norm_pathspec = NULL;
3959+
}
3960+
}
3961+
if (pathspec_matches) {
3962+
if (data->ignored_too && data->ignored_too > 0) {
3963+
trace_printf("Forcing add of submodule ignored=all due to --force: %s\n", path);
3964+
} else {
3965+
printf(_("Skipping submodule due to ignore=all: %s"), path);
3966+
printf(_("Use -f if you really want to add them.") );
3967+
continue;
3968+
}
3969+
} else {
3970+
/* No explicit pathspec match -> skip silently (or with trace). */
3971+
trace_printf("pathspec does not match %s\n", path);
3972+
continue;
3973+
}
3974+
}
3975+
}
39313976
if (add_file_to_index(data->index, path, data->flags)) {
39323977
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
39333978
die(_("updating files failed"));
39343979
data->add_errors++;
39353980
}
39363981
break;
3982+
}
39373983
case DIFF_STATUS_DELETED:
39383984
if (data->flags & ADD_CACHE_IGNORE_REMOVAL)
39393985
break;

0 commit comments

Comments
 (0)