From: "Claus Schneider(Eficode) via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Junio C Hamano" <gitster@pobox.com>,
"Brandon Williams" <bwilliams.eng@gmail.com>,
"Phillip Wood" <phillip.wood123@gmail.com>,
"Claus Schneider" <claus.schneider@eficode.com>,
"Ben Knoble" <ben.knoble@gmail.com>,
"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>,
"Claus Schneider" <claus.schneider@eficode.com>,
"Claus Schneider(Eficode)" <claus.schneider@eficode.com>
Subject: [PATCH v4 2/5] read-cache: submodule add need --force given ignore=all configuration
Date: Fri, 06 Feb 2026 13:22:57 +0000 [thread overview]
Message-ID: <504edcb0f522f18cb5586bb47bd2bbaf7c3adffb.1770384180.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1987.v4.git.1770384180.gitgitgadget@gmail.com>
From: "Claus Schneider(Eficode)" <claus.schneider@eficode.com>
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 explicitly wants to update the submodule reference.
The reason for the change is to support branch tracking in submodules
with configuration `submdule.<name>.branch` or similar workflows where the
user is not interested in tracking each update of the sha1 in the submdule.
You can additionally set `submodule.<name>.ignore=all` and the `git status`
will state nothing and, with this patch, the `git add` does not either - as
the default behaviour. This patch changes the workflow to a more logical
behaviour and similar to workflow for ignored files.
The patch gives more scenarios for submodules to be used effectively with
less friction similar to the "repo" tool. A submodule can be added for many
different reasons than a hard dependency. It can be added as loosely
coupled dependencies whereas the user wants the latest based on the
configuration `submoule.<name>.branch`, but are not interested to track
each commit in the `super-repo`. Currently it gives friction of handling
conflicts between branches even the sha1's are fast-forward and the user
just wants the latest in any way. The user can still add a sha1 explicitly
to track updates.
Signed-off-by: Claus Schneider(Eficode) <claus.schneider@eficode.com>
---
read-cache.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 0f4981d79f..cc79b25f43 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -47,6 +47,9 @@
#include "csum-file.h"
#include "promisor-remote.h"
#include "hook.h"
+#include "submodule.h"
+#include "submodule-config.h"
+#include "advice.h"
/* Mask for the name length in ce_flags in the on-disk index */
@@ -3910,8 +3913,68 @@ static int fix_unmerged_status(struct diff_filepair *p,
return DIFF_STATUS_MODIFIED;
}
+static int skip_submodule(const char *path,
+ struct repository *repo,
+ struct pathspec *pathspec,
+ int ignored_too)
+{
+ struct stat st;
+ const struct submodule *sub;
+ int pathspec_matches = 0;
+ int ps_i;
+ char *norm_pathspec = NULL;
+
+ /* Only consider if path is a directory */
+ if (lstat(path, &st) || !S_ISDIR(st.st_mode))
+ return 0;
+
+ /* Check if it's a submodule with ignore=all */
+ sub = submodule_from_path(repo, null_oid(the_hash_algo), path);
+ if (!sub || !sub->name || !sub->ignore || strcmp(sub->ignore, "all"))
+ return 0;
+
+ trace_printf("ignore=all: %s\n", path);
+ trace_printf("pathspec %s\n", (pathspec && pathspec->nr)
+ ? "has pathspec"
+ : "no pathspec");
+
+ /* Check if submodule path is explicitly mentioned in pathspec */
+ if (pathspec) {
+ for (ps_i = 0; ps_i < pathspec->nr; ps_i++) {
+ const char *m = pathspec->items[ps_i].match;
+ if (!m)
+ continue;
+ norm_pathspec = xstrdup(m);
+ strip_dir_trailing_slashes(norm_pathspec);
+ if (!strcmp(path, norm_pathspec)) {
+ pathspec_matches = 1;
+ FREE_AND_NULL(norm_pathspec);
+ break;
+ }
+ FREE_AND_NULL(norm_pathspec);
+ }
+ }
+
+ /* If explicitly matched and forced, allow adding */
+ if (pathspec_matches) {
+ if (ignored_too && ignored_too > 0) {
+ trace_printf("Add submodule due to --force: %s\n", path);
+ return 0;
+ } else {
+ advise_if_enabled(ADVICE_ADD_IGNORED_FILE,
+ _("Skipping submodule due to ignore=all: %s\n"
+ "Use --force if you really want to add the submodule."), path);
+ return 1;
+ }
+ }
+
+ /* No explicit pathspec match -> skip silently */
+ trace_printf("Pathspec to submodule does not match explicitly: %s\n", path);
+ return 1;
+}
+
static void update_callback(struct diff_queue_struct *q,
- struct diff_options *opt UNUSED, void *cbdata)
+ struct diff_options *opt UNUSED, void *cbdata)
{
int i;
struct update_callback_data *data = cbdata;
@@ -3921,14 +3984,19 @@ static void update_callback(struct diff_queue_struct *q,
const char *path = p->one->path;
if (!data->include_sparse &&
- !path_in_sparse_checkout(path, data->index))
+ !path_in_sparse_checkout(path, data->index))
continue;
switch (fix_unmerged_status(p, data)) {
default:
die(_("unexpected diff status %c"), p->status);
case DIFF_STATUS_MODIFIED:
- case DIFF_STATUS_TYPE_CHANGED: {
+ case DIFF_STATUS_TYPE_CHANGED:
+ if (skip_submodule(path, data->repo,
+ data->pathspec,
+ data->ignored_too))
+ continue;
+
if (add_file_to_index(data->index, path, data->flags)) {
if (!(data->flags & ADD_CACHE_IGNORE_ERRORS))
die(_("updating files failed"));
--
gitgitgadget
next prev parent reply other threads:[~2026-02-06 13:23 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-18 20:07 [PATCH 0/5] git-add : Respect submodule ignore=all and only add changes with --force Claus Schneider via GitGitGadget
2025-10-18 20:07 ` [PATCH 1/5] read-cache: update add_files_to_cache to take param ignored_too(--force) Claus Schneider(Eficode) via GitGitGadget
2025-10-18 20:07 ` [PATCH 2/5] read-cache: let read-cache respect submodule ignore=all and --force Claus Schneider(Eficode) via GitGitGadget
2025-10-18 20:07 ` [PATCH 3/5] tests: add new t2206-add-submodule-ignored.sh to test ignore=all scenario Claus Schneider(Eficode) via GitGitGadget
2025-10-18 20:07 ` [PATCH 4/5] tests: fix existing tests when add an ignore=all submodule Claus Schneider(Eficode) via GitGitGadget
2025-10-18 20:07 ` [PATCH 5/5] Documentation: update add --force and submodule ignore=all config Claus Schneider(Eficode) via GitGitGadget
2025-10-19 15:34 ` [PATCH 0/5] git-add : Respect submodule ignore=all and only add changes with --force Phillip Wood
[not found] ` <CA+GP4bpu3SUycG35DU5+NSuiqtfYN9-R=7d01EFhexgGh4sRPg@mail.gmail.com>
2025-10-20 7:28 ` Claus Schneider
[not found] ` <CA+GP4bqb775U5oBbLZg1dou+THJOjTbFN+2Pq1cBPqq1SgbxHw@mail.gmail.com>
2025-10-24 13:55 ` Phillip Wood
2025-11-13 12:51 ` Claus Schneider
2025-11-13 18:10 ` [PATCH v2 " Claus Schneider via GitGitGadget
2025-11-13 18:10 ` [PATCH v2 1/5] read-cache: update add_files_to_cache take param include_ignored_submodules Claus Schneider(Eficode) via GitGitGadget
2025-11-13 22:07 ` Junio C Hamano
2025-11-13 18:10 ` [PATCH v2 2/5] read-cache: add/read-cache respect submodule ignore=all Claus Schneider(Eficode) via GitGitGadget
2025-11-13 18:10 ` [PATCH v2 3/5] tests: add new t2206-add-submodule-ignored.sh to test ignore=all scenario Claus Schneider(Eficode) via GitGitGadget
2025-11-13 18:10 ` [PATCH v2 4/5] tests: fix existing tests when add an ignore=all submodule Claus Schneider(Eficode) via GitGitGadget
2025-11-13 18:10 ` [PATCH v2 5/5] Documentation: add --include_ignored_submodules + ignore=all config Claus Schneider(Eficode) via GitGitGadget
2025-11-13 19:58 ` [PATCH v2 0/5] git-add : Respect submodule ignore=all and only add changes with --force Junio C Hamano
2025-11-14 13:53 ` Claus Schneider
2026-02-05 8:51 ` Claus Schneider
2026-02-05 22:05 ` Junio C Hamano
2026-01-14 7:47 ` [PATCH v3 0/5] git-add: Skip submodules with ignore=all unless --force and explicit path used Claus Schneider via GitGitGadget
2026-01-14 7:47 ` [PATCH v3 1/5] read-cache: update add_files_to_cache take param ignored_too Claus Schneider(Eficode) via GitGitGadget
2026-01-14 7:47 ` [PATCH v3 2/5] read-cache: submodule add need --force given ignore=all configuration Claus Schneider(Eficode) via GitGitGadget
2026-01-15 15:42 ` Kristoffer Haugsbakk
2026-01-16 16:07 ` Claus Schneider
2026-01-14 7:47 ` [PATCH v3 3/5] tests: t2206-add-submodule-ignored: ignore=all and add --force tests Claus Schneider(Eficode) via GitGitGadget
2026-01-14 7:47 ` [PATCH v3 4/5] tests: fix existing tests when add an ignore=all submodule Claus Schneider(Eficode) via GitGitGadget
2026-01-14 7:47 ` [PATCH v3 5/5] Documentation: update add --force option + ignore=all config Claus Schneider(Eficode) via GitGitGadget
2026-01-14 17:53 ` Ben Knoble
2026-01-16 15:35 ` Claus Schneider
2026-02-06 13:22 ` [PATCH v4 0/5] git-add: Skip submodules with ignore=all unless --force and explicit path used Claus Schneider via GitGitGadget
2026-02-06 13:22 ` [PATCH v4 1/5] read-cache: update add_files_to_cache take param ignored_too Claus Schneider(Eficode) via GitGitGadget
2026-02-09 0:11 ` Junio C Hamano
2026-02-09 0:11 ` Junio C Hamano
2026-02-06 13:22 ` Claus Schneider(Eficode) via GitGitGadget [this message]
2026-02-06 13:22 ` [PATCH v4 3/5] tests: t2206-add-submodule-ignored: ignore=all and add --force tests Claus Schneider(Eficode) via GitGitGadget
2026-02-06 13:22 ` [PATCH v4 4/5] tests: fix existing tests when add an ignore=all submodule Claus Schneider(Eficode) via GitGitGadget
2026-02-06 13:23 ` [PATCH v4 5/5] Documentation: update add --force option + ignore=all config Claus Schneider(Eficode) via GitGitGadget
2026-03-04 14:01 ` Kristoffer Haugsbakk
2026-03-10 21:04 ` Claus Schneider
2026-03-10 21:10 ` Claus Schneider
2026-02-20 22:27 ` [PATCH v4 0/5] git-add: Skip submodules with ignore=all unless --force and explicit path used Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=504edcb0f522f18cb5586bb47bd2bbaf7c3adffb.1770384180.git.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=avarab@gmail.com \
--cc=ben.knoble@gmail.com \
--cc=bwilliams.eng@gmail.com \
--cc=claus.schneider@eficode.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=phillip.wood123@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox