{"thread":{"id":"11946","subject":"[PATCH v2 04/11] Discard \"deleted\" cache entries after using them to update the working tree","startedAt":"2008-02-07T16:39:59Z","lastAt":"2008-02-07T16:39:59Z","messageCount":1,"participants":["Daniel Barkalow"],"isPatch":true,"patchVersion":2,"patchTotal":11},"messages":[{"id":"67826","messageId":"alpine.LNX.1.00.0802071128030.13593@iabervon.org","threadId":"11946","inReplyTo":null,"subject":"[PATCH v2 04/11] Discard \"deleted\" cache entries after using them to update the working tree","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2008-02-07T16:39:59Z","receivedAt":"2008-02-07T16:39:59Z","isPatch":true,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"Way back in read-tree.c, we used a mode 0 cache entry to indicate that\nan entry had been deleted, so that the update code would remove the\nworking tree file, and we would just skip it when writing out the\nindex file afterward.\n\nThese days, unpack_trees is a library function, and it is still\nleaving these entries in the active cache. Furthermore, unpack_trees\ndoesn't correctly ignore those entries, and who knows what other code\nwouldn't expect them to be there, but just isn't yet called after a\ncall to unpack_trees. To avoid having other code trip over these\nentries, have check_updates() remove them after it removes the working\ntree files.\n\nWhile we're at it, simplify the loop in check_updates(), and avoid\npassing global variables as parameters to check_updates(): there is\nonly one call site anyway.\n\nSigned-off-by: Daniel Barkalow <barkalow@iabervon.org>\n---\n unpack-trees.c |   16 +++++++++-------\n 1 files changed, 9 insertions(+), 7 deletions(-)\n\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex c82a979..99aa45f 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -288,16 +288,16 @@ static void unlink_entry(char *name, char *last_symlink)\n }\n \n static struct checkout state;\n-static void check_updates(struct cache_entry **src, int nr,\n-\t\t\tstruct unpack_trees_options *o)\n+static void check_updates(struct unpack_trees_options *o)\n {\n \tunsigned cnt = 0, total = 0;\n \tstruct progress *progress = NULL;\n \tchar last_symlink[PATH_MAX];\n+\tint i;\n \n \tif (o->update && o->verbose_update) {\n-\t\tfor (total = cnt = 0; cnt < nr; cnt++) {\n-\t\t\tstruct cache_entry *ce = src[cnt];\n+\t\tfor (total = cnt = 0; cnt < active_nr; cnt++) {\n+\t\t\tstruct cache_entry *ce = active_cache[cnt];\n \t\t\tif (ce->ce_flags & (CE_UPDATE | CE_REMOVE))\n \t\t\t\ttotal++;\n \t\t}\n@@ -308,14 +308,16 @@ static void check_updates(struct cache_entry **src, int nr,\n \t}\n \n \t*last_symlink = '\\0';\n-\twhile (nr--) {\n-\t\tstruct cache_entry *ce = *src++;\n+\tfor (i = 0; i < active_nr; i++) {\n+\t\tstruct cache_entry *ce = active_cache[i];\n \n \t\tif (ce->ce_flags & (CE_UPDATE | CE_REMOVE))\n \t\t\tdisplay_progress(progress, ++cnt);\n \t\tif (ce->ce_flags & CE_REMOVE) {\n \t\t\tif (o->update)\n \t\t\t\tunlink_entry(ce->name, last_symlink);\n+\t\t\tremove_cache_entry_at(i);\n+\t\t\ti--;\n \t\t\tcontinue;\n \t\t}\n \t\tif (ce->ce_flags & CE_UPDATE) {\n@@ -374,7 +376,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options\n \t\t\terror(\"Merge requires file-level merging\");\n \t}\n \n-\tcheck_updates(active_cache, active_nr, o);\n+\tcheck_updates(o);\n \treturn 0;\n }\n \n-- \n1.5.4\n"}]}