]> git.ipfire.org Git - thirdparty/git.git/commitdiff
read-cache: mark updated entries for split index
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Fri, 13 Jun 2014 12:19:39 +0000 (19:19 +0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 13 Jun 2014 18:49:40 +0000 (11:49 -0700)
The large part of this patch just follows CE_ENTRY_CHANGED
marks. replace_index_entry() is updated to update
split_index->base->cache[] as well so base->cache[] does not reference
to a freed entry.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/update-index.c
cache.h
entry.c
read-cache.c
split-index.c
split-index.h
unpack-trees.c

index fa3c44140dd3020ea84f5527ba2f584d58f5ae3d..f7a19c47a6094ccc4fbb8a8b4048b744bc7f12e4 100644 (file)
@@ -55,6 +55,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)
                        active_cache[pos]->ce_flags |= flag;
                else
                        active_cache[pos]->ce_flags &= ~flag;
+               active_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;
                cache_tree_invalidate_path(&the_index, path);
                active_cache_changed |= CE_ENTRY_CHANGED;
                return 0;
@@ -268,6 +269,7 @@ static void chmod_path(int flip, const char *path)
                goto fail;
        }
        cache_tree_invalidate_path(&the_index, path);
+       ce->ce_flags |= CE_UPDATE_IN_BASE;
        active_cache_changed |= CE_ENTRY_CHANGED;
        report("chmod %cx '%s'", flip, path);
        return;
diff --git a/cache.h b/cache.h
index 47fe3746be9ea12c030f73ac050d8d6a018d3465..295bf9da5b9f7f8b386ab01df638e1d4aaf0f1e1 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -169,6 +169,8 @@ struct cache_entry {
 /* used to temporarily mark paths matched by pathspecs */
 #define CE_MATCHED           (1 << 26)
 
+#define CE_UPDATE_IN_BASE    (1 << 27)
+
 /*
  * Extended on-disk flags
  */
diff --git a/entry.c b/entry.c
index d913c1d62ca792c8c75b28d3c0b152aab2238fb8..1eda8e94714bbd6020d61b4b627f721b1042673c 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -214,6 +214,7 @@ finish:
                if (!fstat_done)
                        lstat(ce->name, &st);
                fill_stat_cache_info(ce, &st);
+               ce->ce_flags |= CE_UPDATE_IN_BASE;
                state->istate->cache_changed |= CE_ENTRY_CHANGED;
        }
        return 0;
index c43758515da6325848cde0ca5cbd05653aa263f8..7966fb7e02471648cbdcd61e945c07dc7502a490 100644 (file)
@@ -39,7 +39,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
 
 /* changes that can be kept in $GIT_DIR/index (basically all extensions) */
 #define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \
-                CE_ENTRY_ADDED | CE_ENTRY_REMOVED)
+                CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED)
 
 struct index_state the_index;
 static const char *alternate_index_output;
@@ -54,9 +54,11 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
 {
        struct cache_entry *old = istate->cache[nr];
 
+       replace_index_entry_in_base(istate, old, ce);
        remove_name_hash(istate, old);
        free(old);
        set_index_entry(istate, nr, ce);
+       ce->ce_flags |= CE_UPDATE_IN_BASE;
        istate->cache_changed |= CE_ENTRY_CHANGED;
 }
 
@@ -1192,6 +1194,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
                                 * means the index is not valid anymore.
                                 */
                                ce->ce_flags &= ~CE_VALID;
+                               ce->ce_flags |= CE_UPDATE_IN_BASE;
                                istate->cache_changed |= CE_ENTRY_CHANGED;
                        }
                        if (quiet)
index 2bb5d556f0d7929f4d58737154874f9879862009..b36c73b3aa95f41d1f3170deeda796bdc34996bc 100644 (file)
@@ -100,3 +100,18 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce
        else
                free(ce);
 }
+
+void replace_index_entry_in_base(struct index_state *istate,
+                                struct cache_entry *old,
+                                struct cache_entry *new)
+{
+       if (old->index &&
+           istate->split_index &&
+           istate->split_index->base &&
+           old->index <= istate->split_index->base->cache_nr) {
+               new->index = old->index;
+               if (old != istate->split_index->base->cache[new->index - 1])
+                       free(istate->split_index->base->cache[new->index - 1]);
+               istate->split_index->base->cache[new->index - 1] = new;
+       }
+}
index 530211829897a9a82d821a71655f3a6b528136c3..812e510f7e71cb9f32c1945e6a4cbd80598cd89a 100644 (file)
@@ -13,6 +13,9 @@ struct split_index {
 
 struct split_index *init_split_index(struct index_state *istate);
 void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce);
+void replace_index_entry_in_base(struct index_state *istate,
+                                struct cache_entry *old,
+                                struct cache_entry *new);
 int read_link_extension(struct index_state *istate,
                        const void *data, unsigned long sz);
 int write_link_extension(struct strbuf *sb,
index a941f7c33e709a4af148f4d29373b4761a2843cd..4a9cdf2105f03f4f615d88155d28984f3fcf50ae 100644 (file)
@@ -257,8 +257,10 @@ static int apply_sparse_checkout(struct index_state *istate,
                ce->ce_flags |= CE_SKIP_WORKTREE;
        else
                ce->ce_flags &= ~CE_SKIP_WORKTREE;
-       if (was_skip_worktree != ce_skip_worktree(ce))
+       if (was_skip_worktree != ce_skip_worktree(ce)) {
+               ce->ce_flags |= CE_UPDATE_IN_BASE;
                istate->cache_changed |= CE_ENTRY_CHANGED;
+       }
 
        /*
         * if (!was_skip_worktree && !ce_skip_worktree()) {