ie_match_stat(): do not ignore skip-worktree bit with CE_MATCH_IGNORE_VALID
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Mon, 14 Dec 2009 11:43:58 +0000 (18:43 +0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 14 Dec 2009 22:03:58 +0000 (14:03 -0800)
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>
builtin-apply.c
cache.h
entry.c
read-cache.c
unpack-trees.c

index 39dc96ae0237235eb429b504ec28c9d66c32f4e1..7717a667432554ee44ff447d78b61f685c92c464 100644 (file)
@@ -2505,7 +2505,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
                        return -1;
                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)
diff --git a/cache.h b/cache.h
index 2de00f812055b1c3c7a107645f55e47fdb2e10aa..9dcaf41a6c7aa4cd97f37eae33dd0aa7cc45753f 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -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 */
 #define CE_MATCH_IGNORE_VALID          01
 /* 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_modified(const struct index_state *, struct cache_entry *, struct stat *, unsigned int);
 
diff --git a/entry.c b/entry.c
index f276cf3b88ea40cb4e6d03c623ce27cb0204c63e..efee21fe199768ac1e69578e2c3f4d210f484aa4 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -202,7 +202,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
        len += ce_namelen(ce);
 
        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)
                        return 0;
                if (!state->force) {
index 5ee7d9da9c7674f2f7d16b64eaba9c21ae3d78c0..b31861c87e2b6ec5bb1bc2f4a00ff3a11184dfcb 100644 (file)
@@ -259,13 +259,18 @@ int ie_match_stat(const struct index_state *istate,
 {
        unsigned int changed;
        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;
 
        /*
         * If it's marked as always valid in the index, it's
         * 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;
 
        /*
@@ -564,7 +569,7 @@ int add_to_index(struct index_state *istate, const char *path, struct stat *st,
        int size, namelen, was_same;
        mode_t st_mode = st->st_mode;
        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 pretend = flags & ADD_CACHE_PRETEND;
        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;
        int changed, size;
        int ignore_valid = options & CE_MATCH_IGNORE_VALID;
+       int ignore_skip_worktree = options & CE_MATCH_IGNORE_SKIP_WORKTREE;
 
        if (ce_uptodate(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);
                return ce;
        }
index 80ae2a0f4f149a130d06d7e8129f1e24a9c23b7f..d33b39e084a7faa108803b520d0b7f869ec0fbc7 100644 (file)
@@ -569,7 +569,7 @@ static int verify_uptodate_1(struct cache_entry *ce,
                return 0;
 
        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)
                        return 0;
                /*
@@ -701,7 +701,7 @@ static int icase_exists(struct unpack_trees_options *o, struct cache_entry *dst,
        struct cache_entry *src;
 
        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)) {
                        struct stat 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;
                }
                add_entry(o, old, update, 0);