Skip to content

Commit 3cf773e

Browse files
pcloudsgitster
authored andcommitted
cache-tree: fix writing cache-tree when CE_REMOVE is present
entry_count is used in update_one() for two purposes: 1. to skip through the number of processed entries in in-memory index 2. to record the number of entries this cache-tree covers on disk Unfortunately when CE_REMOVE is present these numbers are not the same because CE_REMOVE entries are automatically removed before writing to disk but entry_count is not adjusted and still counts CE_REMOVE entries. Separate the two use cases into two different variables. #1 is taken care by the new field count in struct cache_tree_sub and entry_count is prepared for #2. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 386cc8b commit 3cf773e

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

cache-tree.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,13 +238,16 @@ static int update_one(struct cache_tree *it,
238238
int entries,
239239
const char *base,
240240
int baselen,
241+
int *skip_count,
241242
int flags)
242243
{
243244
struct strbuf buffer;
244245
int missing_ok = flags & WRITE_TREE_MISSING_OK;
245246
int dryrun = flags & WRITE_TREE_DRY_RUN;
246247
int i;
247248

249+
*skip_count = 0;
250+
248251
if (0 <= it->entry_count && has_sha1_file(it->sha1))
249252
return it->entry_count;
250253

@@ -264,7 +267,7 @@ static int update_one(struct cache_tree *it,
264267
struct cache_entry *ce = cache[i];
265268
struct cache_tree_sub *sub;
266269
const char *path, *slash;
267-
int pathlen, sublen, subcnt;
270+
int pathlen, sublen, subcnt, subskip;
268271

269272
path = ce->name;
270273
pathlen = ce_namelen(ce);
@@ -289,10 +292,13 @@ static int update_one(struct cache_tree *it,
289292
cache + i, entries - i,
290293
path,
291294
baselen + sublen + 1,
295+
&subskip,
292296
flags);
293297
if (subcnt < 0)
294298
return subcnt;
295299
i += subcnt;
300+
sub->count = subcnt; /* to be used in the next loop */
301+
*skip_count += subskip;
296302
sub->used = 1;
297303
}
298304

@@ -324,7 +330,7 @@ static int update_one(struct cache_tree *it,
324330
if (!sub)
325331
die("cache-tree.c: '%.*s' in '%s' not found",
326332
entlen, path + baselen, path);
327-
i += sub->cache_tree->entry_count;
333+
i += sub->count;
328334
sha1 = sub->cache_tree->sha1;
329335
mode = S_IFDIR;
330336
}
@@ -340,8 +346,18 @@ static int update_one(struct cache_tree *it,
340346
mode, sha1_to_hex(sha1), entlen+baselen, path);
341347
}
342348

343-
if (ce->ce_flags & (CE_REMOVE | CE_INTENT_TO_ADD))
344-
continue; /* entry being removed or placeholder */
349+
/*
350+
* CE_REMOVE entries are removed before the index is
351+
* written to disk. Skip them to remain consistent
352+
* with the future on-disk index.
353+
*/
354+
if (ce->ce_flags & CE_REMOVE) {
355+
*skip_count = *skip_count + 1;
356+
continue;
357+
}
358+
359+
if (ce->ce_flags & CE_INTENT_TO_ADD)
360+
continue;
345361

346362
strbuf_grow(&buffer, entlen + 100);
347363
strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
@@ -361,7 +377,7 @@ static int update_one(struct cache_tree *it,
361377
}
362378

363379
strbuf_release(&buffer);
364-
it->entry_count = i;
380+
it->entry_count = i - *skip_count;
365381
#if DEBUG
366382
fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n",
367383
it->entry_count, it->subtree_nr,
@@ -375,11 +391,11 @@ int cache_tree_update(struct cache_tree *it,
375391
int entries,
376392
int flags)
377393
{
378-
int i;
394+
int i, skip;
379395
i = verify_cache(cache, entries, flags);
380396
if (i)
381397
return i;
382-
i = update_one(it, cache, entries, "", 0, flags);
398+
i = update_one(it, cache, entries, "", 0, &skip, flags);
383399
if (i < 0)
384400
return i;
385401
return 0;

cache-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
struct cache_tree;
88
struct cache_tree_sub {
99
struct cache_tree *cache_tree;
10+
int count; /* internally used by update_one() */
1011
int namelen;
1112
int used;
1213
char name[FLEX_ARRAY];

0 commit comments

Comments
 (0)