read-cache: mark updated entries for split index
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>
Nguyễn Thái Ngọc Duy committed
Jun 13, 2014 at 19:19 UTC
078a58e825d14987df82af9d19c00ddc8eb82481
7 files changed
+30
-2
builtin/update-index.c
+2
@@ -55,6 +55,7 @@ static int mark_ce_flags(const char *path, int flag, int mark)
55
active_cache[pos]->ce_flags |= flag;
56
else
57
active_cache[pos]->ce_flags &= ~flag;
58
+ active_cache[pos]->ce_flags |= CE_UPDATE_IN_BASE;
59
cache_tree_invalidate_path(&the_index, path);
60
active_cache_changed |= CE_ENTRY_CHANGED;
61
return 0;
@@ -268,6 +269,7 @@ static void chmod_path(int flip, const char *path)
269
goto fail;
270
}
271
cache_tree_invalidate_path(&the_index, path);
272
+ ce->ce_flags |= CE_UPDATE_IN_BASE;
273
active_cache_changed |= CE_ENTRY_CHANGED;
274
report("chmod %cx '%s'", flip, path);
275
return;
cache.h
+2
@@ -169,6 +169,8 @@ struct cache_entry {
169
/* used to temporarily mark paths matched by pathspecs */
170
#define CE_MATCHED (1 << 26)
171
172
+#define CE_UPDATE_IN_BASE (1 << 27)
173
+
174
/*
175
* Extended on-disk flags
176
*/
entry.c
+1
@@ -214,6 +214,7 @@ finish:
214
if (!fstat_done)
215
lstat(ce->name, &st);
216
fill_stat_cache_info(ce, &st);
217
+ ce->ce_flags |= CE_UPDATE_IN_BASE;
218
state->istate->cache_changed |= CE_ENTRY_CHANGED;
219
}
220
return 0;
read-cache.c
+4
-1
@@ -39,7 +39,7 @@ static struct cache_entry *refresh_cache_entry(struct cache_entry *ce,
39
40
/* changes that can be kept in $GIT_DIR/index (basically all extensions) */
41
#define EXTMASK (RESOLVE_UNDO_CHANGED | CACHE_TREE_CHANGED | \
42
- CE_ENTRY_ADDED | CE_ENTRY_REMOVED)
42
+ CE_ENTRY_ADDED | CE_ENTRY_REMOVED | CE_ENTRY_CHANGED)
43
44
struct index_state the_index;
45
static const char *alternate_index_output;
@@ -54,9 +54,11 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
54
{
55
struct cache_entry *old = istate->cache[nr];
56
57
+ replace_index_entry_in_base(istate, old, ce);
58
remove_name_hash(istate, old);
59
free(old);
60
set_index_entry(istate, nr, ce);
61
+ ce->ce_flags |= CE_UPDATE_IN_BASE;
62
istate->cache_changed |= CE_ENTRY_CHANGED;
63
}
64
@@ -1192,6 +1194,7 @@ int refresh_index(struct index_state *istate, unsigned int flags,
1194
* means the index is not valid anymore.
1195
*/
1196
ce->ce_flags &= ~CE_VALID;
1197
+ ce->ce_flags |= CE_UPDATE_IN_BASE;
1198
istate->cache_changed |= CE_ENTRY_CHANGED;
1199
}
1200
if (quiet)
split-index.c
+15
@@ -100,3 +100,18 @@ void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce
100
else
101
free(ce);
102
}
103
+
104
+void replace_index_entry_in_base(struct index_state *istate,
105
+ struct cache_entry *old,
106
+ struct cache_entry *new)
107
+{
108
+ if (old->index &&
109
+ istate->split_index &&
110
+ istate->split_index->base &&
111
+ old->index <= istate->split_index->base->cache_nr) {
112
+ new->index = old->index;
113
+ if (old != istate->split_index->base->cache[new->index - 1])
114
+ free(istate->split_index->base->cache[new->index - 1]);
115
+ istate->split_index->base->cache[new->index - 1] = new;
116
+ }
117
+}
split-index.h
+3
@@ -13,6 +13,9 @@ struct split_index {
13
14
struct split_index *init_split_index(struct index_state *istate);
15
void save_or_free_index_entry(struct index_state *istate, struct cache_entry *ce);
16
+void replace_index_entry_in_base(struct index_state *istate,
17
+ struct cache_entry *old,
18
+ struct cache_entry *new);
19
int read_link_extension(struct index_state *istate,
20
const void *data, unsigned long sz);
21
int write_link_extension(struct strbuf *sb,
unpack-trees.c
+3
-1
@@ -257,8 +257,10 @@ static int apply_sparse_checkout(struct index_state *istate,
257
ce->ce_flags |= CE_SKIP_WORKTREE;
258
else
259
ce->ce_flags &= ~CE_SKIP_WORKTREE;
260
- if (was_skip_worktree != ce_skip_worktree(ce))
260
+ if (was_skip_worktree != ce_skip_worktree(ce)) {
261
+ ce->ce_flags |= CE_UPDATE_IN_BASE;
262
istate->cache_changed |= CE_ENTRY_CHANGED;
263
+ }
264
265
/*
266
* if (!was_skip_worktree && !ce_skip_worktree()) {