threads / patch / 11877

patch, 9 partsDiscard "deleted" cache entries after using them to update the working tree

Subject: [PATCH 4/9] Discard "deleted" cache entries after using them to update the working tree

## tl;dr

3 messages between Feb 4, 2008 and Feb 5, 2008. Diffs are folded; open one to read it.

replies: 2people: 2as markdown or json

Daniel Barkalow· Feb 4, 2008, 18:35 UTC · lore

Way back in read-tree.c, we used a mode 0 cache entry to indicate that an entry had been deleted, so that the update code would remove the working tree file, and we would just skip it when writing out the index file afterward.

These days, unpack_trees is a library function, and it is still leaving these entries in the active cache. Furthermore, unpack_trees doesn't correctly ignore those entries, and who knows what other code wouldn't expect them to be there, but just isn't yet called after a call to unpack_trees. To avoid having other code trip over these entries, have check_updates() remove them after it removes the working tree files.

While we're at it, make the loop more obvious and skip passing in globals to a static function with only one caller.

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
---
 unpack-trees.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)
Show changes to unpack-trees.c +9 −7
diff --git a/unpack-trees.c b/unpack-trees.c
index f462a56..40d4130 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -288,16 +288,16 @@ static void unlink_entry(char *name, char *last_symlink)
 }
 
 static struct checkout state;
-static void check_updates(struct cache_entry **src, int nr,
-			struct unpack_trees_options *o)
+static void check_updates(struct unpack_trees_options *o)
 {
 	unsigned cnt = 0, total = 0;
 	struct progress *progress = NULL;
 	char last_symlink[PATH_MAX];
+	int i;
 
 	if (o->update && o->verbose_update) {
-		for (total = cnt = 0; cnt < nr; cnt++) {
-			struct cache_entry *ce = src[cnt];
+		for (total = cnt = 0; cnt < active_nr; cnt++) {
+			struct cache_entry *ce = active_cache[cnt];
 			if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
 				total++;
 		}
@@ -308,14 +308,16 @@ static void check_updates(struct cache_entry **src, int nr,
 	}
 
 	*last_symlink = '\0';
-	while (nr--) {
-		struct cache_entry *ce = *src++;
+	for (i = 0; i < active_nr; i++) {
+		struct cache_entry *ce = active_cache[i];
 
 		if (ce->ce_flags & (CE_UPDATE | CE_REMOVE))
 			display_progress(progress, ++cnt);
 		if (ce->ce_flags & CE_REMOVE) {
 			if (o->update)
 				unlink_entry(ce->name, last_symlink);
+			remove_cache_entry_at(i);
+			i--;
 			continue;
 		}
 		if (ce->ce_flags & CE_UPDATE) {
@@ -374,7 +376,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
 			error("Merge requires file-level merging");
 	}
 
-	check_updates(active_cache, active_nr, o);
+	check_updates(o);
 	return 0;
 }
 
-- 
1.5.4
Johannes Schindelin· Feb 5, 2008, 01:25 UTC · re: Daniel Barkalow · lore

Re: [PATCH 4/9] Discard "deleted" cache entries after using them to update the working tree

Hi,
On Mon, 4 Feb 2008, Daniel Barkalow wrote:
Show 14 quoted lines
> Way back in read-tree.c, we used a mode 0 cache entry to indicate that 
> an entry had been deleted, so that the update code would remove the 
> working tree file, and we would just skip it when writing out the index 
> file afterward.
> 
> These days, unpack_trees is a library function, and it is still leaving 
> these entries in the active cache. Furthermore, unpack_trees doesn't 
> correctly ignore those entries, and who knows what other code wouldn't 
> expect them to be there, but just isn't yet called after a call to 
> unpack_trees. To avoid having other code trip over these entries, have 
> check_updates() remove them after it removes the working tree files.
> 
> While we're at it, make the loop more obvious and skip passing in 
> globals to a static function with only one caller.
After reading the code I understand what you mean.  How about
	While at it, make the loop removing those entries more obvious, 
	and avoid passing global variables as parameters to 
	check_updates(): there is only one call site anyway.

Ciao, Dscho

Daniel Barkalow· Feb 5, 2008, 20:38 UTC · re: Johannes Schindelin · lore

Re: [PATCH 4/9] Discard "deleted" cache entries after using them to update the working tree

On Tue, 5 Feb 2008, Johannes Schindelin wrote:
Show 24 quoted lines
> Hi,
> 
> On Mon, 4 Feb 2008, Daniel Barkalow wrote:
> 
> > Way back in read-tree.c, we used a mode 0 cache entry to indicate that 
> > an entry had been deleted, so that the update code would remove the 
> > working tree file, and we would just skip it when writing out the index 
> > file afterward.
> > 
> > These days, unpack_trees is a library function, and it is still leaving 
> > these entries in the active cache. Furthermore, unpack_trees doesn't 
> > correctly ignore those entries, and who knows what other code wouldn't 
> > expect them to be there, but just isn't yet called after a call to 
> > unpack_trees. To avoid having other code trip over these entries, have 
> > check_updates() remove them after it removes the working tree files.
> > 
> > While we're at it, make the loop more obvious and skip passing in 
> > globals to a static function with only one caller.
> 
> After reading the code I understand what you mean.  How about
> 
> 	While at it, make the loop removing those entries more obvious, 
> 	and avoid passing global variables as parameters to 
> 	check_updates(): there is only one call site anyway.

It's the loop's flow control that I'm making more obvious (using a normal for loop instead of a while loop that counts down the number of entries while counting up the pointer to the entry under consideration). I'll clarify the message for the next version.

	-Daniel
*This .sig left intentionally blank*

← back to recent threads