ie_match_stat(): do not ignore skip-worktree bit with CE_MATCH_IGNORE_VALID

Previously CE_MATCH_IGNORE_VALID flag is used by both valid and
skip-worktree bits. While the two bits have similar behaviour, sharing
this flag means "git update-index --really-refresh" will ignore
skip-worktree while it should not. Instead another flag is
introduced to ignore skip-worktree bit, CE_MATCH_IGNORE_VALID only
applies to valid bit.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nguyễn Thái Ngọc Duy 2009-12-14 18:43:58 +07:00 committed by Junio C Hamano
parent bbbe508d77
commit 56cac48c35
5 changed files with 26 additions and 9 deletions

View File

@ -2505,7 +2505,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
return -1; return -1;
return 0; return 0;
} }
return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID); return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
} }
static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st) static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)

View File

@ -464,7 +464,9 @@ extern int index_name_is_other(const struct index_state *, const char *, int);
/* do stat comparison even if CE_VALID is true */ /* do stat comparison even if CE_VALID is true */
#define CE_MATCH_IGNORE_VALID 01 #define CE_MATCH_IGNORE_VALID 01
/* do not check the contents but report dirty on racily-clean entries */ /* do not check the contents but report dirty on racily-clean entries */
#define CE_MATCH_RACY_IS_DIRTY 02 #define CE_MATCH_RACY_IS_DIRTY 02
/* do stat comparison even if CE_SKIP_WORKTREE is true */
#define CE_MATCH_IGNORE_SKIP_WORKTREE 04
extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int); extern int ie_match_stat(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int); extern int ie_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);

View File

@ -202,7 +202,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
len += ce_namelen(ce); len += ce_namelen(ce);
if (!check_path(path, len, &st)) { if (!check_path(path, len, &st)) {
unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID); unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
if (!changed) if (!changed)
return 0; return 0;
if (!state->force) { if (!state->force) {

View File

@ -259,13 +259,18 @@ int ie_match_stat(const struct index_state *istate,
{ {
unsigned int changed; unsigned int changed;
int ignore_valid = options & CE_MATCH_IGNORE_VALID; int ignore_valid = options & CE_MATCH_IGNORE_VALID;
int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY; int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY;
/* /*
* If it's marked as always valid in the index, it's * If it's marked as always valid in the index, it's
* valid whatever the checked-out copy says. * valid whatever the checked-out copy says.
*
* skip-worktree has the same effect with higher precedence
*/ */
if (!ignore_valid && ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce))) if (!ignore_skip_worktree && ce_skip_worktree(ce))
return 0;
if (!ignore_valid && (ce->ce_flags & CE_VALID))
return 0; return 0;
/* /*
@ -564,7 +569,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
int size, namelen, was_same; int size, namelen, was_same;
mode_t st_mode = st->st_mode; mode_t st_mode = st->st_mode;
struct cache_entry *ce, *alias; struct cache_entry *ce, *alias;
unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY; unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE|CE_MATCH_RACY_IS_DIRTY;
int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND); int verbose = flags & (ADD_CACHE_VERBOSE | ADD_CACHE_PRETEND);
int pretend = flags & ADD_CACHE_PRETEND; int pretend = flags & ADD_CACHE_PRETEND;
int intent_only = flags & ADD_CACHE_INTENT; int intent_only = flags & ADD_CACHE_INTENT;
@ -1000,11 +1005,21 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
struct cache_entry *updated; struct cache_entry *updated;
int changed, size; int changed, size;
int ignore_valid = options & CE_MATCH_IGNORE_VALID; int ignore_valid = options & CE_MATCH_IGNORE_VALID;
int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
if (ce_uptodate(ce)) if (ce_uptodate(ce))
return ce; return ce;
if (!ignore_valid && ((ce->ce_flags & CE_VALID) || ce_skip_worktree(ce))) { /*
* CE_VALID or CE_SKIP_WORKTREE means the user promised us
* that the change to the work tree does not matter and told
* us not to worry.
*/
if (!ignore_skip_worktree && ce_skip_worktree(ce)) {
ce_mark_uptodate(ce);
return ce;
}
if (!ignore_valid && (ce->ce_flags & CE_VALID)) {
ce_mark_uptodate(ce); ce_mark_uptodate(ce);
return ce; return ce;
} }

View File

@ -569,7 +569,7 @@ static int verify_uptodate_1(struct cache_entry *ce,
return 0; return 0;
if (!lstat(ce->name, &st)) { if (!lstat(ce->name, &st)) {
unsigned changed = ie_match_stat(o->src_index, ce, &st, CE_MATCH_IGNORE_VALID); unsigned changed = ie_match_stat(o->src_index, ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
if (!changed) if (!changed)
return 0; return 0;
/* /*
@ -701,7 +701,7 @@ static int icase_exists(struct unpack_trees_options *o, struct cache_entry *dst,
struct cache_entry *src; struct cache_entry *src;
src = index_name_exists(o->src_index, dst->name, ce_namelen(dst), 1); src = index_name_exists(o->src_index, dst->name, ce_namelen(dst), 1);
return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID); return src && !ie_match_stat(o->src_index, src, st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
} }
/* /*
@ -1152,7 +1152,7 @@ int oneway_merge(struct cache_entry **src, struct unpack_trees_options *o)
if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) { if (o->reset && !ce_uptodate(old) && !ce_skip_worktree(old)) {
struct stat st; struct stat st;
if (lstat(old->name, &st) || if (lstat(old->name, &st) ||
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID)) ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE))
update |= CE_UPDATE; update |= CE_UPDATE;
} }
add_entry(o, old, update, 0); add_entry(o, old, update, 0);