refresh_index() optionally takes a seen[] array to mark the pathspec items that had matches in the index. This is used by `git add --refresh` to find out if there was any pathspec without matches, and display an error accordingly. In the following patch, `git add` will also learn to warn about pathspecs that match no eligible path for updating, but do match sparse entries. For that, we will need a seen[] array marked exclusively with matches from dense entries. To avoid having to call ce_path_match() again for these entries after refresh_index() returns, add a flag that implements this restriction inside the function itself. Note that refresh_index() does not update sparse entries, regardless of passing the flag or not. The flag only controls whether matches with these entries should appear in the seen[] array. While we are here, also realign the REFRESH_* flags and convert the hex values to the more natural bit shift format, which makes it easier to spot holes. Signed-off-by: Matheus Tavares <matheus.bernardino@xxxxxx> --- cache.h | 15 ++++++++------- read-cache.c | 5 ++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/cache.h b/cache.h index 6fda8091f1..0b6074d49e 100644 --- a/cache.h +++ b/cache.h @@ -879,13 +879,14 @@ int match_stat_data_racy(const struct index_state *istate, void fill_stat_cache_info(struct index_state *istate, struct cache_entry *ce, struct stat *st); -#define REFRESH_REALLY 0x0001 /* ignore_valid */ -#define REFRESH_UNMERGED 0x0002 /* allow unmerged */ -#define REFRESH_QUIET 0x0004 /* be quiet about it */ -#define REFRESH_IGNORE_MISSING 0x0008 /* ignore non-existent */ -#define REFRESH_IGNORE_SUBMODULES 0x0010 /* ignore submodules */ -#define REFRESH_IN_PORCELAIN 0x0020 /* user friendly output, not "needs update" */ -#define REFRESH_PROGRESS 0x0040 /* show progress bar if stderr is tty */ +#define REFRESH_REALLY (1 << 0) /* ignore_valid */ +#define REFRESH_UNMERGED (1 << 1) /* allow unmerged */ +#define REFRESH_QUIET (1 << 2) /* be quiet about it */ +#define REFRESH_IGNORE_MISSING (1 << 3) /* ignore non-existent */ +#define REFRESH_IGNORE_SUBMODULES (1 << 4) /* ignore submodules */ +#define REFRESH_IN_PORCELAIN (1 << 5) /* user friendly output, not "needs update" */ +#define REFRESH_PROGRESS (1 << 6) /* show progress bar if stderr is tty */ +#define REFRESH_DONT_MARK_SPARSE_MATCHES (1 << 7) /* don't mark sparse entries' matches on seen[] */ int refresh_index(struct index_state *, unsigned int flags, const struct pathspec *pathspec, char *seen, const char *header_msg); /* * Refresh the index and write it to disk. diff --git a/read-cache.c b/read-cache.c index 1e9a50c6c7..0bf7c64eff 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1514,6 +1514,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, int quiet = (flags & REFRESH_QUIET) != 0; int not_new = (flags & REFRESH_IGNORE_MISSING) != 0; int ignore_submodules = (flags & REFRESH_IGNORE_SUBMODULES) != 0; + int no_sparse_on_seen = (flags & REFRESH_DONT_MARK_SPARSE_MATCHES) != 0; int first = 1; int in_porcelain = (flags & REFRESH_IN_PORCELAIN); unsigned int options = (CE_MATCH_REFRESH | @@ -1552,12 +1553,14 @@ int refresh_index(struct index_state *istate, unsigned int flags, int filtered = 0; int t2_did_lstat = 0; int t2_did_scan = 0; + char *cur_seen; ce = istate->cache[i]; if (ignore_submodules && S_ISGITLINK(ce->ce_mode)) continue; - if (pathspec && !ce_path_match(istate, ce, pathspec, seen)) + cur_seen = no_sparse_on_seen && ce_skip_worktree(ce) ? NULL : seen; + if (pathspec && !ce_path_match(istate, ce, pathspec, cur_seen)) filtered = 1; if (ce_stage(ce)) { -- 2.30.1