{"thread":{"id":"9464","subject":"Start moving unpack-trees to \"struct tree_desc\"","startedAt":"2007-08-10T05:21:29Z","lastAt":"2007-08-10T05:21:29Z","messageCount":1,"participants":["Linus Torvalds"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"50376","messageId":"alpine.LFD.0.999.0708092213240.30176@woody.linux-foundation.org","threadId":"9464","inReplyTo":null,"subject":"Start moving unpack-trees to \"struct tree_desc\"","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-08-10T05:21:29Z","receivedAt":"2007-08-10T05:21:29Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nThis doesn't actually change any real code, but it changes the interface \nto unpack_trees() to take an array of \"struct tree_desc\" entries, the same \nway the tree-walk.c functions do.\n\nThe reason for this is that we would be much better off if we can do the \ntree-unpacking using the generic \"traverse_trees()\" functionality instead \nof having to the special \"unpack\" infrastructure.\n\nThis really is a pretty minimal diff, just to change the calling \nconvention. It passes all the tests, and looks sane. There were only two \nusers of \"unpack_trees()\": builtin-read-tree and merge-recursive, and I \ntried to keep the changes minimal.\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n\nMy plan is that with the more regular interfaces, we can hopefully migrate \nthe cases that \"unpack_trees()\" handles one by one to other interfaces - \nbut in order to do that, it has to use the *common* tree traversal \ninterface, rather than a special one that requires munging from one \nformat to another.\n\n\t\tLinus\n\n---\n builtin-read-tree.c |   26 ++++++++++++++++++--------\n merge-recursive.c   |   16 +++++++++++-----\n unpack-trees.c      |   25 +++++++++----------------\n unpack-trees.h      |    2 +-\n 4 files changed, 39 insertions(+), 30 deletions(-)\n\ndiff --git a/builtin-read-tree.c b/builtin-read-tree.c\nindex a3b17a3..1967d10 100644\n--- a/builtin-read-tree.c\n+++ b/builtin-read-tree.c\n@@ -13,14 +13,19 @@\n #include \"dir.h\"\n #include \"builtin.h\"\n \n-static struct object_list *trees;\n+static int nr_trees;\n+static struct tree *trees[4];\n \n static int list_tree(unsigned char *sha1)\n {\n-\tstruct tree *tree = parse_tree_indirect(sha1);\n+\tstruct tree *tree;\n+\n+\tif (nr_trees >= 4)\n+\t\treturn -1;\n+\ttree = parse_tree_indirect(sha1);\n \tif (!tree)\n \t\treturn -1;\n-\tobject_list_append(&tree->object, &trees);\n+\ttrees[nr_trees++] = tree;\n \treturn 0;\n }\n \n@@ -76,11 +81,10 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)\n \n static void prime_cache_tree(void)\n {\n-\tstruct tree *tree = (struct tree *)trees->item;\n-\tif (!tree)\n+\tif (!nr_trees)\n \t\treturn;\n \tactive_cache_tree = cache_tree();\n-\tprime_cache_tree_rec(active_cache_tree, tree);\n+\tprime_cache_tree_rec(active_cache_tree, trees[0]);\n \n }\n \n@@ -92,6 +96,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n {\n \tint i, newfd, stage = 0;\n \tunsigned char sha1[20];\n+\tstruct tree_desc t[3];\n \tstruct unpack_trees_options opts;\n \n \tmemset(&opts, 0, sizeof(opts));\n@@ -258,7 +263,12 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \t\t\topts.head_idx = 1;\n \t}\n \n-\tunpack_trees(trees, &opts);\n+\tfor (i = 0; i < nr_trees; i++) {\n+\t\tstruct tree *tree = trees[i];\n+\t\tparse_tree(tree);\n+\t\tinit_tree_desc(t+i, tree->buffer, tree->size);\n+\t}\n+\tunpack_trees(nr_trees, t, &opts);\n \n \t/*\n \t * When reading only one tree (either the most basic form,\n@@ -266,7 +276,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)\n \t * valid cache-tree because the index must match exactly\n \t * what came from the tree.\n \t */\n-\tif (trees && trees->item && !opts.prefix && (!opts.merge || (stage == 2))) {\n+\tif (nr_trees && !opts.prefix && (!opts.merge || (stage == 2))) {\n \t\tcache_tree_free(&active_cache_tree);\n \t\tprime_cache_tree();\n \t}\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex c8539ec..f7d1b84 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -216,13 +216,19 @@ static int add_cacheinfo(unsigned int mode, const unsigned char *sha1,\n  */\n static int index_only = 0;\n \n+static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)\n+{\n+\tparse_tree(tree);\n+\tinit_tree_desc(desc, tree->buffer, tree->size);\n+}\n+\n static int git_merge_trees(int index_only,\n \t\t\t   struct tree *common,\n \t\t\t   struct tree *head,\n \t\t\t   struct tree *merge)\n {\n \tint rc;\n-\tstruct object_list *trees = NULL;\n+\tstruct tree_desc t[3];\n \tstruct unpack_trees_options opts;\n \n \tmemset(&opts, 0, sizeof(opts));\n@@ -234,11 +240,11 @@ static int git_merge_trees(int index_only,\n \topts.head_idx = 2;\n \topts.fn = threeway_merge;\n \n-\tobject_list_append(&common->object, &trees);\n-\tobject_list_append(&head->object, &trees);\n-\tobject_list_append(&merge->object, &trees);\n+\tinit_tree_desc_from_tree(t+0, common);\n+\tinit_tree_desc_from_tree(t+1, head);\n+\tinit_tree_desc_from_tree(t+2, merge);\n \n-\trc = unpack_trees(trees, &opts);\n+\trc = unpack_trees(3, t, &opts);\n \tcache_tree_free(&active_cache_tree);\n \treturn rc;\n }\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex dfd985b..5d1ffd1 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -16,19 +16,13 @@ struct tree_entry_list {\n \tconst unsigned char *sha1;\n };\n \n-static struct tree_entry_list *create_tree_entry_list(struct tree *tree)\n+static struct tree_entry_list *create_tree_entry_list(struct tree_desc *desc)\n {\n-\tstruct tree_desc desc;\n \tstruct name_entry one;\n \tstruct tree_entry_list *ret = NULL;\n \tstruct tree_entry_list **list_p = &ret;\n \n-\tif (!tree->object.parsed)\n-\t\tparse_tree(tree);\n-\n-\tinit_tree_desc(&desc, tree->buffer, tree->size);\n-\n-\twhile (tree_entry(&desc, &one)) {\n+\twhile (tree_entry(desc, &one)) {\n \t\tstruct tree_entry_list *entry;\n \n \t\tentry = xmalloc(sizeof(struct tree_entry_list));\n@@ -173,9 +167,11 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,\n \n \t\t\tif (S_ISDIR(posns[i]->mode)) {\n \t\t\t\tstruct tree *tree = lookup_tree(posns[i]->sha1);\n+\t\t\t\tstruct tree_desc t;\n \t\t\t\tany_dirs = 1;\n \t\t\t\tparse_tree(tree);\n-\t\t\t\tsubposns[i] = create_tree_entry_list(tree);\n+\t\t\t\tinit_tree_desc(&t, tree->buffer, tree->size);\n+\t\t\t\tsubposns[i] = create_tree_entry_list(&t);\n \t\t\t\tposns[i] = posns[i]->next;\n \t\t\t\tsrc[i + o->merge] = o->df_conflict_entry;\n \t\t\t\tcontinue;\n@@ -331,12 +327,10 @@ static void check_updates(struct cache_entry **src, int nr,\n \t\tstop_progress(&progress);;\n }\n \n-int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)\n+int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options *o)\n {\n-\tunsigned len = object_list_length(trees);\n \tstruct tree_entry_list **posns;\n \tint i;\n-\tstruct object_list *posn = trees;\n \tstruct tree_entry_list df_conflict_list;\n \tstatic struct cache_entry *dfc;\n \n@@ -356,10 +350,9 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)\n \n \tif (len) {\n \t\tposns = xmalloc(len * sizeof(struct tree_entry_list *));\n-\t\tfor (i = 0; i < len; i++) {\n-\t\t\tposns[i] = create_tree_entry_list((struct tree *) posn->item);\n-\t\t\tposn = posn->next;\n-\t\t}\n+\t\tfor (i = 0; i < len; i++)\n+\t\t\tposns[i] = create_tree_entry_list(t+i);\n+\n \t\tif (unpack_trees_rec(posns, len, o->prefix ? o->prefix : \"\",\n \t\t\t\t     o, &df_conflict_list))\n \t\t\treturn -1;\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex fee7da4..9cd39a2 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -26,7 +26,7 @@ struct unpack_trees_options {\n \tstruct cache_entry *df_conflict_entry;\n };\n \n-extern int unpack_trees(struct object_list *trees,\n+extern int unpack_trees(unsigned n, struct tree_desc *t,\n \t\tstruct unpack_trees_options *options);\n \n int threeway_merge(struct cache_entry **stages, struct unpack_trees_options *o);\n"}]}