Am 17.06.2013 22:44, schrieb Junio C Hamano: > René Scharfe <rene.scharfe@xxxxxxxxxxxxxx> writes: > >>> The information is only useful for the unpack_trees callback, and >>> "info->data" is a more appropriate place to hang such a callback >>> specific data. >>> >>> Perhaps we should use info->data field to point at >>> >>> struct { >>> struct unpack_trees_options *o; >>> unsigned long df_conflict; >>> }; >>> >>> and get rid of info->conflicts field? >> >> Here's a patch that does so, but it complicates matters quite a bit. >> Did I miss anything (or rather: add too much)? > > I do not think so. These bits are needed per recursion level, and > it cannot be shoved into unpack_trees_options so I suspect that your > patch is the best we can do. Or, perhaps we can > > - add df_conflict to struct unpack_trees_options; > > - have traverse_info->data point at struct unpack_trees_options as > before; and > > - save the old value of o->df_conflict on the stack of > traverse_trees_recursive(), update the field in place, and > restore it when the recursion returns??? How about going into the opposite direction and moving df_conflicts handling more into traverse_tree? If the function saved the mask and dirmask in traverse_info then callbacks could calculate the cumulated d/f conflicts by walking the info chain, similar to how make_traverse_path works. That would match the spirit of that struct. Below is a patch for that, for illustration. We could then remove the mask and dirmask parameters from traverse_callback_t functions, as the callbacks can then get them through traverse_info. René tree-walk.c | 2 ++ tree-walk.h | 2 +- unpack-trees.c | 11 ++++++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tree-walk.c b/tree-walk.c index 6e30ef9..dae5db7 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -400,6 +400,8 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info) } if (!mask) break; + info->mask = mask; + info->dirmask = dirmask; interesting = prune_traversal(e, info, &base, interesting); if (interesting < 0) break; diff --git a/tree-walk.h b/tree-walk.h index ae04b64..e308859 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -46,7 +46,7 @@ struct traverse_info { int pathlen; struct pathspec *pathspec; - unsigned long df_conflicts; + unsigned long mask, dirmask; traverse_callback_t fn; void *data; int show_all_errors; diff --git a/unpack-trees.c b/unpack-trees.c index b27f2a6..58210d0 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -445,7 +445,6 @@ static int switch_cache_bottom(struct traverse_info *info) } static int traverse_trees_recursive(int n, unsigned long dirmask, - unsigned long df_conflicts, struct name_entry *names, struct traverse_info *info) { @@ -464,7 +463,6 @@ static int traverse_trees_recursive(int n, unsigned long dirmask, newinfo.pathspec = info->pathspec; newinfo.name = *p; newinfo.pathlen += tree_entry_len(p) + 1; - newinfo.df_conflicts |= df_conflicts; for (i = 0; i < n; i++, dirmask >>= 1) { const unsigned char *sha1 = NULL; @@ -565,12 +563,16 @@ static int unpack_nondirectories(int n, unsigned long mask, { int i; struct unpack_trees_options *o = info->data; - unsigned long conflicts = info->df_conflicts | dirmask; + unsigned long conflicts = dirmask; + const struct traverse_info *previnfo; /* Do we have *only* directories? Nothing to do */ if (mask == dirmask && !src[0]) return 0; + for (previnfo = info->prev; previnfo; previnfo = previnfo->prev) + conflicts |= previnfo->mask & ~previnfo->dirmask; + /* * Ok, we've filled in up to any potential index entry in src[0], * now do the rest. @@ -820,8 +822,7 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str } } - if (traverse_trees_recursive(n, dirmask, mask & ~dirmask, - names, info) < 0) + if (traverse_trees_recursive(n, dirmask, names, info) < 0) return -1; return mask; } -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html