Skip to content

Commit d1a863b

Browse files
committed
read-cache: let read-cache respect submodule ignore=all and --force
Given the submdule configuration is ignore=all then only update the submdule if the --force option is given and the submodule is explicit given in the pathspec. 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. The reason for the change is support submodule branch tracking or similar and git status state nothing and git add should not add either. The workflow is more logic and similar to regular ignored files even the submodule is already tracked. The change opens up a lot of possibilities for submodules to be used more freely and a like the repo tool. A submodule can be added for many more reason and loosely coupled dependencies to the super repo which often gives the friction of handle the explicit commits and updates without the need for tracking the submodule sha1 by sha1. Signed-off-by: Claus Schneider(Eficode) <claus.schneider@eficode.com>
1 parent d98cca6 commit d1a863b

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

read-cache.c

Lines changed: 43 additions & 0 deletions
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

@@ -3928,6 +3930,47 @@ static void update_callback(struct diff_queue_struct *q,
39283930
die(_("unexpected diff status %c"), p->status);
39293931
case DIFF_STATUS_MODIFIED:
39303932
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_AND_NULL(norm_pathspec);
3954+
break;
3955+
}
3956+
FREE_AND_NULL(norm_pathspec);
3957+
}
3958+
}
3959+
if (pathspec_matches) {
3960+
if (data->ignored_too && data->ignored_too > 0) {
3961+
trace_printf("Forcing add of submodule ignored=all due to --force: %s\n", path);
3962+
} else {
3963+
printf(_("Skipping submodule due to ignore=all: %s"), path);
3964+
printf(_("Use -f if you really want to add them.") );
3965+
continue;
3966+
}
3967+
} else {
3968+
/* No explicit pathspec match -> skip silently (or with trace). */
3969+
trace_printf("pathspec does not match %s\n", path);
3970+
continue;
3971+
}
3972+
}
3973+
}
39313974
if (add_file_to_index(data->index, path, data->flags)) {
39323975
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
39333976
die(_("updating files failed"));

0 commit comments

Comments
 (0)