Merge branch 'mt/add-rm-in-sparse-checkout'
"git add" and "git rm" learned not to touch those paths that are outside of sparse checkout. * mt/add-rm-in-sparse-checkout: rm: honor sparse checkout patterns add: warn when asked to update SKIP_WORKTREE entries refresh_index(): add flag to ignore SKIP_WORKTREE entries pathspec: allow to ignore SKIP_WORKTREE entries on index matching add: make --chmod and --renormalize honor sparse checkouts t3705: add tests for `git add` in sparse checkouts add: include magic part of pathspec on --refresh error
This commit is contained in:
@ -46,6 +46,9 @@ static int chmod_pathspec(struct pathspec *pathspec, char flip, int show_only)
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
int err;
|
||||
|
||||
if (ce_skip_worktree(ce))
|
||||
continue;
|
||||
|
||||
if (pathspec && !ce_path_match(&the_index, ce, pathspec, NULL))
|
||||
continue;
|
||||
|
||||
@ -146,6 +149,8 @@ static int renormalize_tracked_files(const struct pathspec *pathspec, int flags)
|
||||
for (i = 0; i < active_nr; i++) {
|
||||
struct cache_entry *ce = active_cache[i];
|
||||
|
||||
if (ce_skip_worktree(ce))
|
||||
continue;
|
||||
if (ce_stage(ce))
|
||||
continue; /* do not touch unmerged paths */
|
||||
if (!S_ISREG(ce->ce_mode) && !S_ISLNK(ce->ce_mode))
|
||||
@ -174,24 +179,44 @@ static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
|
||||
*dst++ = entry;
|
||||
}
|
||||
dir->nr = dst - dir->entries;
|
||||
add_pathspec_matches_against_index(pathspec, &the_index, seen);
|
||||
add_pathspec_matches_against_index(pathspec, &the_index, seen,
|
||||
PS_IGNORE_SKIP_WORKTREE);
|
||||
return seen;
|
||||
}
|
||||
|
||||
static void refresh(int verbose, const struct pathspec *pathspec)
|
||||
static int refresh(int verbose, const struct pathspec *pathspec)
|
||||
{
|
||||
char *seen;
|
||||
int i;
|
||||
int i, ret = 0;
|
||||
char *skip_worktree_seen = NULL;
|
||||
struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
|
||||
int flags = REFRESH_IGNORE_SKIP_WORKTREE |
|
||||
(verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET);
|
||||
|
||||
seen = xcalloc(pathspec->nr, 1);
|
||||
refresh_index(&the_index, verbose ? REFRESH_IN_PORCELAIN : REFRESH_QUIET,
|
||||
pathspec, seen, _("Unstaged changes after refreshing the index:"));
|
||||
refresh_index(&the_index, flags, pathspec, seen,
|
||||
_("Unstaged changes after refreshing the index:"));
|
||||
for (i = 0; i < pathspec->nr; i++) {
|
||||
if (!seen[i])
|
||||
die(_("pathspec '%s' did not match any files"),
|
||||
pathspec->items[i].match);
|
||||
if (!seen[i]) {
|
||||
if (matches_skip_worktree(pathspec, i, &skip_worktree_seen)) {
|
||||
string_list_append(&only_match_skip_worktree,
|
||||
pathspec->items[i].original);
|
||||
} else {
|
||||
die(_("pathspec '%s' did not match any files"),
|
||||
pathspec->items[i].original);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (only_match_skip_worktree.nr) {
|
||||
advise_on_updating_sparse_paths(&only_match_skip_worktree);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
free(seen);
|
||||
free(skip_worktree_seen);
|
||||
string_list_clear(&only_match_skip_worktree, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int run_add_interactive(const char *revision, const char *patch_mode,
|
||||
@ -567,15 +592,18 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
}
|
||||
|
||||
if (refresh_only) {
|
||||
refresh(verbose, &pathspec);
|
||||
exit_status |= refresh(verbose, &pathspec);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pathspec.nr) {
|
||||
int i;
|
||||
char *skip_worktree_seen = NULL;
|
||||
struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
|
||||
|
||||
if (!seen)
|
||||
seen = find_pathspecs_matching_against_index(&pathspec, &the_index);
|
||||
seen = find_pathspecs_matching_against_index(&pathspec,
|
||||
&the_index, PS_IGNORE_SKIP_WORKTREE);
|
||||
|
||||
/*
|
||||
* file_exists() assumes exact match
|
||||
@ -589,12 +617,24 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
|
||||
for (i = 0; i < pathspec.nr; i++) {
|
||||
const char *path = pathspec.items[i].match;
|
||||
|
||||
if (pathspec.items[i].magic & PATHSPEC_EXCLUDE)
|
||||
continue;
|
||||
if (!seen[i] && path[0] &&
|
||||
((pathspec.items[i].magic &
|
||||
(PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
|
||||
!file_exists(path))) {
|
||||
if (seen[i])
|
||||
continue;
|
||||
|
||||
if (matches_skip_worktree(&pathspec, i, &skip_worktree_seen)) {
|
||||
string_list_append(&only_match_skip_worktree,
|
||||
pathspec.items[i].original);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Don't complain at 'git add .' on empty repo */
|
||||
if (!path[0])
|
||||
continue;
|
||||
|
||||
if ((pathspec.items[i].magic & (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
|
||||
!file_exists(path)) {
|
||||
if (ignore_missing) {
|
||||
int dtype = DT_UNKNOWN;
|
||||
if (is_excluded(&dir, &the_index, path, &dtype))
|
||||
@ -605,7 +645,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)
|
||||
pathspec.items[i].original);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (only_match_skip_worktree.nr) {
|
||||
advise_on_updating_sparse_paths(&only_match_skip_worktree);
|
||||
exit_status = 1;
|
||||
}
|
||||
|
||||
free(seen);
|
||||
free(skip_worktree_seen);
|
||||
string_list_clear(&only_match_skip_worktree, 0);
|
||||
}
|
||||
|
||||
plug_bulk_checkin();
|
||||
|
||||
Reference in New Issue
Block a user