Skip to content

Commit f52a289

Browse files
committed
read-cache: update submodule need --force given ignore=all configuration
Submodules configured with ignore=all are now skipped during add operations unless overridden by --force and the submodule path is explicitly specified. 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 states nothing and git add should not add either as a default behaviour. 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 simular to 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 2e5242e commit f52a289

File tree

1 file changed

+69
-45
lines changed

1 file changed

+69
-45
lines changed

read-cache.c

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#include "csum-file.h"
4949
#include "promisor-remote.h"
5050
#include "hook.h"
51+
#include "submodule.h"
52+
#include "submodule-config.h"
53+
#include "advice.h"
5154

5255
/* Mask for the name length in ce_flags in the on-disk index */
5356

@@ -3909,8 +3912,66 @@ static int fix_unmerged_status(struct diff_filepair *p,
39093912
return DIFF_STATUS_MODIFIED;
39103913
}
39113914

3915+
static int should_skip_submodule_with_ignore_all(const char *path,
3916+
struct repository *repo,
3917+
struct pathspec *pathspec,
3918+
int ignored_too)
3919+
{
3920+
struct stat st;
3921+
const struct submodule *sub;
3922+
int pathspec_matches = 0;
3923+
int ps_i;
3924+
char *norm_pathspec = NULL;
3925+
3926+
/* Only consider if path is a directory */
3927+
if (lstat(path, &st) || !S_ISDIR(st.st_mode))
3928+
return 0;
3929+
3930+
/* Check if it's a submodule with ignore=all */
3931+
sub = submodule_from_path(repo, null_oid(the_hash_algo), path);
3932+
if (!sub || !sub->name || !sub->ignore || strcmp(sub->ignore, "all"))
3933+
return 0;
3934+
3935+
trace_printf("ignore=all %s\n", path);
3936+
trace_printf("pathspec %s\n",
3937+
(pathspec && pathspec->nr) ? "has pathspec" : "no pathspec");
3938+
3939+
/* Check if submodule path is explicitly mentioned in pathspec */
3940+
if (pathspec) {
3941+
for (ps_i = 0; ps_i < pathspec->nr; ps_i++) {
3942+
const char *m = pathspec->items[ps_i].match;
3943+
if (!m)
3944+
continue;
3945+
norm_pathspec = xstrdup(m);
3946+
strip_dir_trailing_slashes(norm_pathspec);
3947+
if (!strcmp(path, norm_pathspec)) {
3948+
pathspec_matches = 1;
3949+
FREE_AND_NULL(norm_pathspec);
3950+
break;
3951+
}
3952+
FREE_AND_NULL(norm_pathspec);
3953+
}
3954+
}
3955+
3956+
/* If explicitly matched and forced, allow adding */
3957+
if (pathspec_matches) {
3958+
if (ignored_too && ignored_too > 0) {
3959+
trace_printf("Add submodule due to --force: %s\n", path);
3960+
return 0;
3961+
} else {advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
3962+
_("Skipping submodule due to ignore=all: %s\n"
3963+
"Use --force if you really want to add the submodule."), path);
3964+
return 1;
3965+
}
3966+
}
3967+
3968+
/* No explicit pathspec match -> skip silently */
3969+
trace_printf("Pathspec to submodule does not match explicitly: %s\n", path);
3970+
return 1;
3971+
}
3972+
39123973
static void update_callback(struct diff_queue_struct *q,
3913-
struct diff_options *opt UNUSED, void *cbdata)
3974+
struct diff_options *opt UNUSED, void *cbdata)
39143975
{
39153976
int i;
39163977
struct update_callback_data *data = cbdata;
@@ -3919,56 +3980,19 @@ static void update_callback(struct diff_queue_struct *q,
39193980
struct diff_filepair *p = q->queue[i];
39203981
const char *path = p->one->path;
39213982

3922-
if (!data->include_sparse &&
3923-
!path_in_sparse_checkout(path, data->index))
3983+
if (!data->include_sparse && !path_in_sparse_checkout(path, data->index))
39243984
continue;
39253985

39263986
switch (fix_unmerged_status(p, data)) {
39273987
default:
39283988
die(_("unexpected diff status %c"), p->status);
39293989
case DIFF_STATUS_MODIFIED:
3930-
case DIFF_STATUS_TYPE_CHANGED: {
3931-
struct stat st;
3932-
if (!lstat(path, &st) && S_ISDIR(st.st_mode)) { // only consider submodule if it is a directory
3933-
const struct submodule *sub = submodule_from_path(data->repo, null_oid(the_hash_algo), path);
3934-
if (sub && sub->name && sub->ignore && !strcmp(sub->ignore, "all")) {
3935-
int pathspec_matches = 0;
3936-
char *norm_pathspec = NULL;
3937-
int ps_i;
3938-
trace_printf("ignore=all %s\n", path);
3939-
trace_printf("pathspec %s\n",
3940-
(data->pathspec && data->pathspec->nr) ? "has pathspec" : "no pathspec");
3941-
/* Safely scan all pathspec items (q->nr may exceed pathspec->nr). */
3942-
if (data->pathspec) {
3943-
for (ps_i = 0; ps_i < data->pathspec->nr; ps_i++) {
3944-
const char *m = data->pathspec->items[ps_i].match;
3945-
if (!m)
3946-
continue;
3947-
norm_pathspec = xstrdup(m);
3948-
strip_dir_trailing_slashes(norm_pathspec);
3949-
if (!strcmp(path, norm_pathspec)) {
3950-
pathspec_matches = 1;
3951-
FREE_AND_NULL(norm_pathspec);
3952-
break;
3953-
}
3954-
FREE_AND_NULL(norm_pathspec);
3955-
}
3956-
}
3957-
if (pathspec_matches) {
3958-
if (data->include_ignored_submodules && data->include_ignored_submodules > 0) {
3959-
trace_printf("Add ignored=all submodule due to --include_ignored_submodules: %s\n", path);
3960-
} else {
3961-
printf(_("Skipping submodule due to ignore=all: %s"), path);
3962-
printf(_("Use --include_ignored_submodules, if you really want to add them.") );
3963-
continue;
3964-
}
3965-
} else {
3966-
/* No explicit pathspec match -> skip silently (or with trace). */
3967-
trace_printf("pathspec does not match %s\n", path);
3968-
continue;
3969-
}
3970-
}
3971-
}
3990+
case DIFF_STATUS_TYPE_CHANGED:
3991+
if (should_skip_submodule_with_ignore_all(path, data->repo,
3992+
data->pathspec,
3993+
data->ignored_too))
3994+
continue;
3995+
39723996
if (add_file_to_index(data->index, path, data->flags)) {
39733997
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
39743998
die(_("updating files failed"));

0 commit comments

Comments
 (0)