{"thread":{"id":"3951","subject":"[PATCH 3/4] Update write-tree to use cache-tree.","startedAt":"2006-04-23T23:52:35Z","lastAt":"2006-04-23T23:52:35Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"19025","messageId":"7vacabetoc.fsf@assigned-by-dhcp.cox.net","threadId":"3951","inReplyTo":null,"subject":"[PATCH 3/4] Update write-tree to use cache-tree.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-04-23T23:52:35Z","receivedAt":"2006-04-23T23:52:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The updated write-tree reads from $GIT_DIR/index.aux to pick up\nsubtree objects information, updates the cache-tree with the\nindex, and updates index.aux file after writing a tree out of\nthe index file.\n\nUntil update-index and other programs that modify the index are\nupdated to maintain index.aux file, the index.aux file written\nby the last write-tree will become stale immediately after they\nupdate the index, which will result in the whole tree\nrecomputation just like the original write-tree.\n\nThe idea is to convert those commands to invalidate cache-tree\nwhenever they touch the index entries, and write updated\nindex.aux out.  After the index is updated with them, write-tree\nwill be able to reuse the parts of the cache-tree that have not\nbeen touched.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n\n---\n\n * And this is the \"Willie the Coyote waiting for the big rock\n   to fail\" patch.  Right now nobody uses the cache but...\n\n write-tree.c |  135 +++++-----------------------------------------------------\n 1 files changed, 11 insertions(+), 124 deletions(-)\n\nff283e7fafdd0740f74dfa65d8efaaaf9a5a0bbf\ndiff --git a/write-tree.c b/write-tree.c\nindex dcad6e6..dbcfe8c 100644\n--- a/write-tree.c\n+++ b/write-tree.c\n@@ -5,96 +5,23 @@\n  */\n #include \"cache.h\"\n #include \"tree.h\"\n+#include \"cache-tree.h\"\n \n-static int missing_ok = 0;\n-\n-static int check_valid_sha1(unsigned char *sha1)\n-{\n-\tint ret;\n-\n-\t/* If we were anal, we'd check that the sha1 of the contents actually matches */\n-\tret = has_sha1_file(sha1);\n-\tif (ret == 0)\n-\t\tperror(sha1_file_name(sha1));\n-\treturn ret ? 0 : -1;\n-}\n-\n-static int write_tree(struct cache_entry **cachep, int maxentries, const char *base, int baselen, unsigned char *returnsha1)\n-{\n-\tunsigned char subdir_sha1[20];\n-\tunsigned long size, offset;\n-\tchar *buffer;\n-\tint nr;\n-\n-\t/* Guess at some random initial size */\n-\tsize = 8192;\n-\tbuffer = xmalloc(size);\n-\toffset = 0;\n-\n-\tnr = 0;\n-\twhile (nr < maxentries) {\n-\t\tstruct cache_entry *ce = cachep[nr];\n-\t\tconst char *pathname = ce->name, *filename, *dirname;\n-\t\tint pathlen = ce_namelen(ce), entrylen;\n-\t\tunsigned char *sha1;\n-\t\tunsigned int mode;\n-\n-\t\t/* Did we hit the end of the directory? Return how many we wrote */\n-\t\tif (baselen >= pathlen || memcmp(base, pathname, baselen))\n-\t\t\tbreak;\n-\n-\t\tsha1 = ce->sha1;\n-\t\tmode = ntohl(ce->ce_mode);\n-\n-\t\t/* Do we have _further_ subdirectories? */\n-\t\tfilename = pathname + baselen;\n-\t\tdirname = strchr(filename, '/');\n-\t\tif (dirname) {\n-\t\t\tint subdir_written;\n+static unsigned char active_cache_sha1[20];\n+static struct cache_tree *active_cache_tree;\n \n-\t\t\tsubdir_written = write_tree(cachep + nr, maxentries - nr, pathname, dirname-pathname+1, subdir_sha1);\n-\t\t\tnr += subdir_written;\n-\n-\t\t\t/* Now we need to write out the directory entry into this tree.. */\n-\t\t\tmode = S_IFDIR;\n-\t\t\tpathlen = dirname - pathname;\n-\n-\t\t\t/* ..but the directory entry doesn't count towards the total count */\n-\t\t\tnr--;\n-\t\t\tsha1 = subdir_sha1;\n-\t\t}\n-\n-\t\tif (!missing_ok && check_valid_sha1(sha1) < 0)\n-\t\t\texit(1);\n-\n-\t\tentrylen = pathlen - baselen;\n-\t\tif (offset + entrylen + 100 > size) {\n-\t\t\tsize = alloc_nr(offset + entrylen + 100);\n-\t\t\tbuffer = xrealloc(buffer, size);\n-\t\t}\n-\t\toffset += sprintf(buffer + offset, \"%o %.*s\", mode, entrylen, filename);\n-\t\tbuffer[offset++] = 0;\n-\t\tmemcpy(buffer + offset, sha1, 20);\n-\t\toffset += 20;\n-\t\tnr++;\n-\t}\n-\n-\twrite_sha1_file(buffer, offset, tree_type, returnsha1);\n-\tfree(buffer);\n-\treturn nr;\n-}\n+static int missing_ok = 0;\n \n static const char write_tree_usage[] = \"git-write-tree [--missing-ok]\";\n \n int main(int argc, char **argv)\n {\n-\tint i, funny;\n \tint entries;\n-\tunsigned char sha1[20];\n \t\n \tsetup_git_directory();\n \n-\tentries = read_cache();\n+\tentries = read_cache_1(active_cache_sha1);\n+\tactive_cache_tree = read_cache_tree(active_cache_sha1);\n \tif (argc == 2) {\n \t\tif (!strcmp(argv[1], \"--missing-ok\"))\n \t\t\tmissing_ok = 1;\n@@ -108,51 +35,11 @@ int main(int argc, char **argv)\n \tif (entries < 0)\n \t\tdie(\"git-write-tree: error reading cache\");\n \n-\t/* Verify that the tree is merged */\n-\tfunny = 0;\n-\tfor (i = 0; i < entries; i++) {\n-\t\tstruct cache_entry *ce = active_cache[i];\n-\t\tif (ce_stage(ce)) {\n-\t\t\tif (10 < ++funny) {\n-\t\t\t\tfprintf(stderr, \"...\\n\");\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tfprintf(stderr, \"%s: unmerged (%s)\\n\", ce->name, sha1_to_hex(ce->sha1));\n-\t\t}\n-\t}\n-\tif (funny)\n-\t\tdie(\"git-write-tree: not able to write tree\");\n-\n-\t/* Also verify that the cache does not have path and path/file\n-\t * at the same time.  At this point we know the cache has only\n-\t * stage 0 entries.\n-\t */\n-\tfunny = 0;\n-\tfor (i = 0; i < entries - 1; i++) {\n-\t\t/* path/file always comes after path because of the way\n-\t\t * the cache is sorted.  Also path can appear only once,\n-\t\t * which means conflicting one would immediately follow.\n-\t\t */\n-\t\tconst char *this_name = active_cache[i]->name;\n-\t\tconst char *next_name = active_cache[i+1]->name;\n-\t\tint this_len = strlen(this_name);\n-\t\tif (this_len < strlen(next_name) &&\n-\t\t    strncmp(this_name, next_name, this_len) == 0 &&\n-\t\t    next_name[this_len] == '/') {\n-\t\t\tif (10 < ++funny) {\n-\t\t\t\tfprintf(stderr, \"...\\n\");\n-\t\t\t\tbreak;\n-\t\t\t}\n-\t\t\tfprintf(stderr, \"You have both %s and %s\\n\",\n-\t\t\t\tthis_name, next_name);\n-\t\t}\n-\t}\n-\tif (funny)\n-\t\tdie(\"git-write-tree: not able to write tree\");\n+\tif (cache_tree_update(active_cache_tree, active_cache, active_nr,\n+\t\t\t      missing_ok))\n+\t\tdie(\"git-write-tree: error building trees\");\n+\twrite_cache_tree(active_cache_sha1, active_cache_tree);\n \n-\t/* Ok, write it out */\n-\tif (write_tree(active_cache, entries, \"\", 0, sha1) != entries)\n-\t\tdie(\"git-write-tree: internal error\");\n-\tprintf(\"%s\\n\", sha1_to_hex(sha1));\n+\tprintf(\"%s\\n\", sha1_to_hex(active_cache_tree->sha1));\n \treturn 0;\n }\n-- \n1.3.0.g623a\n"}]}