Skip to content

Commit 2d0e9c5

Browse files
bicschneidergitster
authored andcommitted
read-cache: submodule add 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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent bddef70 commit 2d0e9c5

1 file changed

Lines changed: 71 additions & 3 deletions

File tree

read-cache.c

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@
4747
#include "csum-file.h"
4848
#include "promisor-remote.h"
4949
#include "hook.h"
50+
#include "submodule.h"
51+
#include "submodule-config.h"
52+
#include "advice.h"
5053

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

@@ -3907,8 +3910,68 @@ static int fix_unmerged_status(struct diff_filepair *p,
39073910
return DIFF_STATUS_MODIFIED;
39083911
}
39093912

3913+
static int skip_submodule(const char *path,
3914+
struct repository *repo,
3915+
struct pathspec *pathspec,
3916+
int ignored_too)
3917+
{
3918+
struct stat st;
3919+
const struct submodule *sub;
3920+
int pathspec_matches = 0;
3921+
int ps_i;
3922+
char *norm_pathspec = NULL;
3923+
3924+
/* Only consider if path is a directory */
3925+
if (lstat(path, &st) || !S_ISDIR(st.st_mode))
3926+
return 0;
3927+
3928+
/* Check if it's a submodule with ignore=all */
3929+
sub = submodule_from_path(repo, null_oid(the_hash_algo), path);
3930+
if (!sub || !sub->name || !sub->ignore || strcmp(sub->ignore, "all"))
3931+
return 0;
3932+
3933+
trace_printf("ignore=all: %s\n", path);
3934+
trace_printf("pathspec %s\n", (pathspec && pathspec->nr)
3935+
? "has pathspec"
3936+
: "no pathspec");
3937+
3938+
/* Check if submodule path is explicitly mentioned in pathspec */
3939+
if (pathspec) {
3940+
for (ps_i = 0; ps_i < pathspec->nr; ps_i++) {
3941+
const char *m = pathspec->items[ps_i].match;
3942+
if (!m)
3943+
continue;
3944+
norm_pathspec = xstrdup(m);
3945+
strip_dir_trailing_slashes(norm_pathspec);
3946+
if (!strcmp(path, norm_pathspec)) {
3947+
pathspec_matches = 1;
3948+
FREE_AND_NULL(norm_pathspec);
3949+
break;
3950+
}
3951+
FREE_AND_NULL(norm_pathspec);
3952+
}
3953+
}
3954+
3955+
/* If explicitly matched and forced, allow adding */
3956+
if (pathspec_matches) {
3957+
if (ignored_too && ignored_too > 0) {
3958+
trace_printf("Add submodule due to --force: %s\n", path);
3959+
return 0;
3960+
} else {
3961+
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+
39103973
static void update_callback(struct diff_queue_struct *q,
3911-
struct diff_options *opt UNUSED, void *cbdata)
3974+
struct diff_options *opt UNUSED, void *cbdata)
39123975
{
39133976
int i;
39143977
struct update_callback_data *data = cbdata;
@@ -3918,14 +3981,19 @@ static void update_callback(struct diff_queue_struct *q,
39183981
const char *path = p->one->path;
39193982

39203983
if (!data->include_sparse &&
3921-
!path_in_sparse_checkout(path, data->index))
3984+
!path_in_sparse_checkout(path, data->index))
39223985
continue;
39233986

39243987
switch (fix_unmerged_status(p, data)) {
39253988
default:
39263989
die(_("unexpected diff status %c"), p->status);
39273990
case DIFF_STATUS_MODIFIED:
3928-
case DIFF_STATUS_TYPE_CHANGED: {
3991+
case DIFF_STATUS_TYPE_CHANGED:
3992+
if (skip_submodule(path, data->repo,
3993+
data->pathspec,
3994+
data->ignored_too))
3995+
continue;
3996+
39293997
if (add_file_to_index(data->index, path, data->flags)) {
39303998
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
39313999
die(_("updating files failed"));

0 commit comments

Comments
 (0)