{"thread":{"id":"22326","subject":"Remove diff machinery dependency from read-cache","startedAt":"2010-01-21T19:37:38Z","lastAt":"2010-01-23T06:31:35Z","messageCount":23,"participants":["Linus Torvalds","Junio C Hamano","Johannes Schindelin","Nicolas Pitre","Johannes Sixt","Brian Campbell"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"132328","messageId":"alpine.LFD.2.00.1001211119130.13231@localhost.localdomain","threadId":"22326","inReplyTo":null,"subject":"Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-21T19:37:38Z","receivedAt":"2010-01-21T19:37:38Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nExal Sibeaz pointed out that some git files are way too big, and that \nadd_files_to_cache() brings in all the diff machinery to any git binary \nthat needs the basic git SHA1 object operations from read-cache.c. Which \nis pretty much all of them.\n\nIt's doubly silly, since add_files_to_cache() is only used by builtin \nprograms (add, checkout and commit), so it's fairly easily fixed by just \nmoving the thing to builtin-add.c, and avoiding the dependency entirely.\n\nI initially argued to Exal that it would probably be best to try to depend \non smart compilers and linkers, but after spending some time trying to \nmake -ffunction-sections work and giving up, I think Exal was right, and \nthe fix is to just do some trivial cleanups like this.\n\nThis trivial cleanup results in pretty stunning file size differences. \nThe diff machinery really is mostly used by just the builtin programs, and \nyou have things like these trivial before-and-after numbers:\n\n  -rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object\n  -rwxrwxr-x 1 torvalds torvalds  940265 2010-01-21 11:16 git-hash-object\n\nNow, I'm not saying that 940kB is good either, but that's mostly all the \ndebug information - you can see the real code with 'size':\n\n   text\t   data\t    bss\t    dec\t    hex\tfilename\n 418675\t   3920\t 127408\t 550003\t  86473\tgit-hash-object (before)\n 230650\t   2288\t 111728\t 344666\t  5425a\tgit-hash-object (after)\n\nie we have a nice 24% size reduction from this trivial cleanup.\n\nIt's not just that one file either. I get:\n\n\t[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core\n\t45640\t/home/torvalds/libexec/git-core (before)\n\t33508\t/home/torvalds/libexec/git-core (after)\n\nso we're talking 12MB of diskspace here. \n\n(Of course, stripping all the binaries brings the 33MB down to 9MB, so the \nwhole debug information thing is still the bulk of it all, but that's a \nseparate issue entirely)\n\nNow, I'm sure there are other things we should do, and changing our \ncompiler flags from -O2 to -Os would bring the text size down by an \nadditional almost 20%, but this thing Exal pointed out seems to be some \ngood low-hanging fruit.\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n builtin-add.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n read-cache.c  |   78 ---------------------------------------------------------\n 2 files changed, 76 insertions(+), 78 deletions(-)\n\ndiff --git a/builtin-add.c b/builtin-add.c\nindex cb6e590..2705f8d 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -11,6 +11,7 @@\n #include \"run-command.h\"\n #include \"parse-options.h\"\n #include \"diff.h\"\n+#include \"diffcore.h\"\n #include \"revision.h\"\n \n static const char * const builtin_add_usage[] = {\n@@ -20,6 +21,81 @@ static const char * const builtin_add_usage[] = {\n static int patch_interactive, add_interactive, edit_interactive;\n static int take_worktree_changes;\n \n+struct update_callback_data\n+{\n+\tint flags;\n+\tint add_errors;\n+};\n+\n+static void update_callback(struct diff_queue_struct *q,\n+\t\t\t    struct diff_options *opt, void *cbdata)\n+{\n+\tint i;\n+\tstruct update_callback_data *data = cbdata;\n+\n+\tfor (i = 0; i < q->nr; i++) {\n+\t\tstruct diff_filepair *p = q->queue[i];\n+\t\tconst char *path = p->one->path;\n+\t\tswitch (p->status) {\n+\t\tdefault:\n+\t\t\tdie(\"unexpected diff status %c\", p->status);\n+\t\tcase DIFF_STATUS_UNMERGED:\n+\t\t\t/*\n+\t\t\t * ADD_CACHE_IGNORE_REMOVAL is unset if \"git\n+\t\t\t * add -u\" is calling us, In such a case, a\n+\t\t\t * missing work tree file needs to be removed\n+\t\t\t * if there is an unmerged entry at stage #2,\n+\t\t\t * but such a diff record is followed by\n+\t\t\t * another with DIFF_STATUS_DELETED (and if\n+\t\t\t * there is no stage #2, we won't see DELETED\n+\t\t\t * nor MODIFIED).  We can simply continue\n+\t\t\t * either way.\n+\t\t\t */\n+\t\t\tif (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))\n+\t\t\t\tcontinue;\n+\t\t\t/*\n+\t\t\t * Otherwise, it is \"git add path\" is asking\n+\t\t\t * to explicitly add it; we fall through.  A\n+\t\t\t * missing work tree file is an error and is\n+\t\t\t * caught by add_file_to_index() in such a\n+\t\t\t * case.\n+\t\t\t */\n+\t\tcase DIFF_STATUS_MODIFIED:\n+\t\tcase DIFF_STATUS_TYPE_CHANGED:\n+\t\t\tif (add_file_to_index(&the_index, path, data->flags)) {\n+\t\t\t\tif (!(data->flags & ADD_CACHE_IGNORE_ERRORS))\n+\t\t\t\t\tdie(\"updating files failed\");\n+\t\t\t\tdata->add_errors++;\n+\t\t\t}\n+\t\t\tbreak;\n+\t\tcase DIFF_STATUS_DELETED:\n+\t\t\tif (data->flags & ADD_CACHE_IGNORE_REMOVAL)\n+\t\t\t\tbreak;\n+\t\t\tif (!(data->flags & ADD_CACHE_PRETEND))\n+\t\t\t\tremove_file_from_index(&the_index, path);\n+\t\t\tif (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))\n+\t\t\t\tprintf(\"remove '%s'\\n\", path);\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+}\n+\n+int add_files_to_cache(const char *prefix, const char **pathspec, int flags)\n+{\n+\tstruct update_callback_data data;\n+\tstruct rev_info rev;\n+\tinit_revisions(&rev, prefix);\n+\tsetup_revisions(0, NULL, &rev, NULL);\n+\trev.prune_data = pathspec;\n+\trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n+\trev.diffopt.format_callback = update_callback;\n+\tdata.flags = flags;\n+\tdata.add_errors = 0;\n+\trev.diffopt.format_callback_data = &data;\n+\trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n+\treturn !!data.add_errors;\n+}\n+\n static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)\n {\n \tint num_unmatched = 0, i;\ndiff --git a/read-cache.c b/read-cache.c\nindex edd9959..79938bf 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -10,9 +10,6 @@\n #include \"dir.h\"\n #include \"tree.h\"\n #include \"commit.h\"\n-#include \"diff.h\"\n-#include \"diffcore.h\"\n-#include \"revision.h\"\n #include \"blob.h\"\n #include \"resolve-undo.h\"\n \n@@ -1648,81 +1645,6 @@ int read_index_unmerged(struct index_state *istate)\n \treturn unmerged;\n }\n \n-struct update_callback_data\n-{\n-\tint flags;\n-\tint add_errors;\n-};\n-\n-static void update_callback(struct diff_queue_struct *q,\n-\t\t\t    struct diff_options *opt, void *cbdata)\n-{\n-\tint i;\n-\tstruct update_callback_data *data = cbdata;\n-\n-\tfor (i = 0; i < q->nr; i++) {\n-\t\tstruct diff_filepair *p = q->queue[i];\n-\t\tconst char *path = p->one->path;\n-\t\tswitch (p->status) {\n-\t\tdefault:\n-\t\t\tdie(\"unexpected diff status %c\", p->status);\n-\t\tcase DIFF_STATUS_UNMERGED:\n-\t\t\t/*\n-\t\t\t * ADD_CACHE_IGNORE_REMOVAL is unset if \"git\n-\t\t\t * add -u\" is calling us, In such a case, a\n-\t\t\t * missing work tree file needs to be removed\n-\t\t\t * if there is an unmerged entry at stage #2,\n-\t\t\t * but such a diff record is followed by\n-\t\t\t * another with DIFF_STATUS_DELETED (and if\n-\t\t\t * there is no stage #2, we won't see DELETED\n-\t\t\t * nor MODIFIED).  We can simply continue\n-\t\t\t * either way.\n-\t\t\t */\n-\t\t\tif (!(data->flags & ADD_CACHE_IGNORE_REMOVAL))\n-\t\t\t\tcontinue;\n-\t\t\t/*\n-\t\t\t * Otherwise, it is \"git add path\" is asking\n-\t\t\t * to explicitly add it; we fall through.  A\n-\t\t\t * missing work tree file is an error and is\n-\t\t\t * caught by add_file_to_index() in such a\n-\t\t\t * case.\n-\t\t\t */\n-\t\tcase DIFF_STATUS_MODIFIED:\n-\t\tcase DIFF_STATUS_TYPE_CHANGED:\n-\t\t\tif (add_file_to_index(&the_index, path, data->flags)) {\n-\t\t\t\tif (!(data->flags & ADD_CACHE_IGNORE_ERRORS))\n-\t\t\t\t\tdie(\"updating files failed\");\n-\t\t\t\tdata->add_errors++;\n-\t\t\t}\n-\t\t\tbreak;\n-\t\tcase DIFF_STATUS_DELETED:\n-\t\t\tif (data->flags & ADD_CACHE_IGNORE_REMOVAL)\n-\t\t\t\tbreak;\n-\t\t\tif (!(data->flags & ADD_CACHE_PRETEND))\n-\t\t\t\tremove_file_from_index(&the_index, path);\n-\t\t\tif (data->flags & (ADD_CACHE_PRETEND|ADD_CACHE_VERBOSE))\n-\t\t\t\tprintf(\"remove '%s'\\n\", path);\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-}\n-\n-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)\n-{\n-\tstruct update_callback_data data;\n-\tstruct rev_info rev;\n-\tinit_revisions(&rev, prefix);\n-\tsetup_revisions(0, NULL, &rev, NULL);\n-\trev.prune_data = pathspec;\n-\trev.diffopt.output_format = DIFF_FORMAT_CALLBACK;\n-\trev.diffopt.format_callback = update_callback;\n-\tdata.flags = flags;\n-\tdata.add_errors = 0;\n-\trev.diffopt.format_callback_data = &data;\n-\trun_diff_files(&rev, DIFF_RACY_IS_MODIFIED);\n-\treturn !!data.add_errors;\n-}\n-\n /*\n  * Returns 1 if the path is an \"other\" path with respect to\n  * the index; that is, the path is not mentioned in the index at all,\n"},{"id":"132330","messageId":"7vljfrp6g2.fsf@alter.siamese.dyndns.org","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211119130.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-21T20:07:57Z","receivedAt":"2010-01-21T20:07:57Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> This trivial cleanup results in pretty stunning file size differences. \n> The diff machinery really is mostly used by just the builtin programs, and \n> you have things like these trivial before-and-after numbers:\n>\n>   -rwxr-xr-x 1 torvalds torvalds 1727420 2010-01-21 10:53 git-hash-object\n>   -rwxrwxr-x 1 torvalds torvalds  940265 2010-01-21 11:16 git-hash-object\n>\n> Now, I'm not saying that 940kB is good either, but that's mostly all the \n> debug information - you can see the real code with 'size':\n>\n>    text\t   data\t    bss\t    dec\t    hex\tfilename\n>  418675\t   3920\t 127408\t 550003\t  86473\tgit-hash-object (before)\n>  230650\t   2288\t 111728\t 344666\t  5425a\tgit-hash-object (after)\n>\n> ie we have a nice 24% size reduction from this trivial cleanup.\n\n\nThe patch itself to move add_files_to_cache() to builtin-add.c (or to its\nown file) makes sense from the code placement POV, but if the goal is to\nshrink the on-disk footprint, isn't an alternative approach be to make\nhash-object built-in?  You can lose the whole 1.7M from the filesystem\nfootprint that way, no?\n"},{"id":"132333","messageId":"alpine.LFD.2.00.1001211215080.13231@localhost.localdomain","threadId":"22326","inReplyTo":"7vljfrp6g2.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-21T20:15:56Z","receivedAt":"2010-01-21T20:15:56Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Junio C Hamano wrote:\n> \n> The patch itself to move add_files_to_cache() to builtin-add.c (or to its\n> own file) makes sense from the code placement POV, but if the goal is to\n> shrink the on-disk footprint, isn't an alternative approach be to make\n> hash-object built-in?  You can lose the whole 1.7M from the filesystem\n> footprint that way, no?\n\nSure. Except, as I mentioned, it's not just git-hash-object. It's _all_ of \nthem.\n\nThe total space savings wasn't 1.7M, it was 12M.\n\n\t\tLinus\n"},{"id":"132339","messageId":"alpine.LFD.2.00.1001211355500.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211215080.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-21T22:18:34Z","receivedAt":"2010-01-21T22:18:34Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Linus Torvalds wrote:\n> \n> Sure. Except, as I mentioned, it's not just git-hash-object. It's _all_ of \n> them.\n> \n> The total space savings wasn't 1.7M, it was 12M.\n\nThere are some other interesting cases. For example, look at this:\n\n\t[torvalds@nehalem git]$ size show-index.o git-show-index\n\t   text\t   data\t    bss\t    dec\t    hex\tfilename\n\t   1310\t      0\t   1024\t   2334\t    91e\tshow-index.o\n\t 222706\t   2296\t 112720\t 337722\t  5273a\tgit-show-index\n\nie a trivial program like 'show-index' has ballooned to 220kB. Let's look \nat why:\n\n\t[torvalds@nehalem git]$ nm show-index.o | grep ' U '\n\t                 U die\n\t                 U fread\n\t                 U free\n\t                 U printf\n\t                 U sha1_to_hex\n\t                 U stdin\n\t                 U usage\n\t                 U xmalloc\n\nok, if you ignore standard library things (which will be from a shared \nlibrary anyway), it really only wants totally trivial things: die, \nxmalloc, and sha1_to_hex. Those should be a few hundred bytes, not a few \nhundred _kilo_bytes.\n\nSo what happens?\n\n - sha1_to_hex brings in all of sha1_file.c, even though it doesn't need \n   any of it. Ok, that's easily fixed: split up the hex helpers into a \n   file of its own (\"hex.c\")\n\n - \"die()\" brings in usage.c, which is actually designed correctly, so it \n   is all fine. No extra pain there. Sure, we'll get some other trivial \n   stuff from there, but we're talking maybe a kilobyte of code.\n\n - \"xmalloc()\" brings in the trivial wrappers.\n\n   OOPS.\n\nThose wrappers bring in zlib (through git_inflate*), which is not a huge \nissue, we coult just move the git_inflate*() wrappers to its own file. \nTrivial. But the wrappers also bring in:\n\n - xmalloc/xrealloc/xstrdup:\n                 U release_pack_memory\n\nwhich in turn brings in _all_ of the rest of the git libraries. End \nresult: a trivial git helper program that _should_ be a couple of \nkilobytes in size ends up being 200+kB of text, and 900kB with debug \ninformation.\n\nAbsolutely _none_ of which is in the least useful.\n\nOh well.\n\nWe could fix it a few ways\n\n - ignore it. Most git programs will get the pack handling functions \n   anyway, since they want to get object reading.\n\n - as mentioned, just build in _everything_ so that we only ever have one \n   binary\n\n - get rid of release_pack_memory() entirely. We have better ways to limit \n   pack memory use these days, but they do require configuration (we do \n   have a default packed_git_limit, though, so even without any explicit \n   configuration it's not insane).\n\n - don't have explicit knowledge about 'release_pack_memory' in xmalloc, \n   but instead have the packing functions register a \"xmalloc \n   pressure_reliever function\". So then programs that have pack handling \n   will register the fixup function, and programs that don't will never \n   even know.\n\nHmm? We have about 20 external programs that may hide issues like this.\n\n\t\tLinus\n"},{"id":"132340","messageId":"alpine.LFD.2.00.1001211515470.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211355500.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-21T23:25:19Z","receivedAt":"2010-01-21T23:25:19Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Linus Torvalds wrote:\n> \n> We could fix it a few ways\n> \n>  - ignore it. Most git programs will get the pack handling functions \n>    anyway, since they want to get object reading.\n\nIn fact, we should probably remove git-show-index. It may have some \nhistorical significance as a pack-file index debugger, but it has no \nactual redeeming features now, considering that the binary is a megabyte \nof useless crud with debugging info.\n\nHowever, we do actually use it in t/t5302-pack-index.sh. So in the \nmeantime, how about this hacky patch to simply just avoid xmalloc, and \nseparating out the trivial hex functions into \"hex.o\".\n\nThis results in\n\n  [torvalds@nehalem git]$ size git-show-index \n       text    data     bss     dec     hex filename\n     222818    2276  112688  337782   52776 git-show-index (before)\n       5696     624    1264    7584    1da0 git-show-index (after)\n\nwhich is a whole lot better, no?\n\n(Or make it a built-in, if we actually think we want to carry it along in \nthe long run)\n\n\t\tLinus\n\n---\n Makefile     |    1 +\n sha1_file.c  |   66 ----------------------------------------------------------\n show-index.c |    2 +-\n 3 files changed, 2 insertions(+), 67 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ad890ec..a041b69 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -559,6 +559,7 @@ LIB_OBJS += graph.o\n LIB_OBJS += grep.o\n LIB_OBJS += hash.o\n LIB_OBJS += help.o\n+LIB_OBJS += hex.o\n LIB_OBJS += ident.o\n LIB_OBJS += levenshtein.o\n LIB_OBJS += list-objects.o\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 7086760..12478a3 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -35,54 +35,6 @@ static size_t sz_fmt(size_t s) { return s; }\n \n const unsigned char null_sha1[20];\n \n-const signed char hexval_table[256] = {\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 00-07 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 08-0f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 10-17 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 18-1f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 20-27 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 28-2f */\n-\t  0,  1,  2,  3,  4,  5,  6,  7,\t\t/* 30-37 */\n-\t  8,  9, -1, -1, -1, -1, -1, -1,\t\t/* 38-3f */\n-\t -1, 10, 11, 12, 13, 14, 15, -1,\t\t/* 40-47 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 48-4f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 50-57 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 58-5f */\n-\t -1, 10, 11, 12, 13, 14, 15, -1,\t\t/* 60-67 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 68-67 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 70-77 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 78-7f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 80-87 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 88-8f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 90-97 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* 98-9f */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* a0-a7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* a8-af */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* b0-b7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* b8-bf */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* c0-c7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* c8-cf */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* d0-d7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* d8-df */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* e0-e7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* e8-ef */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* f0-f7 */\n-\t -1, -1, -1, -1, -1, -1, -1, -1,\t\t/* f8-ff */\n-};\n-\n-int get_sha1_hex(const char *hex, unsigned char *sha1)\n-{\n-\tint i;\n-\tfor (i = 0; i < 20; i++) {\n-\t\tunsigned int val = (hexval(hex[0]) << 4) | hexval(hex[1]);\n-\t\tif (val & ~0xff)\n-\t\t\treturn -1;\n-\t\t*sha1++ = val;\n-\t\thex += 2;\n-\t}\n-\treturn 0;\n-}\n-\n static inline int offset_1st_component(const char *path)\n {\n \tif (has_dos_drive_prefix(path))\n@@ -133,24 +85,6 @@ int safe_create_leading_directories_const(const char *path)\n \treturn result;\n }\n \n-char *sha1_to_hex(const unsigned char *sha1)\n-{\n-\tstatic int bufno;\n-\tstatic char hexbuffer[4][50];\n-\tstatic const char hex[] = \"0123456789abcdef\";\n-\tchar *buffer = hexbuffer[3 & ++bufno], *buf = buffer;\n-\tint i;\n-\n-\tfor (i = 0; i < 20; i++) {\n-\t\tunsigned int val = *sha1++;\n-\t\t*buf++ = hex[val >> 4];\n-\t\t*buf++ = hex[val & 0xf];\n-\t}\n-\t*buf = '\\0';\n-\n-\treturn buffer;\n-}\n-\n static void fill_sha1_path(char *pathbuf, const unsigned char *sha1)\n {\n \tint i;\ndiff --git a/show-index.c b/show-index.c\nindex 63f9da5..4c0ac13 100644\n--- a/show-index.c\n+++ b/show-index.c\n@@ -48,7 +48,7 @@ int main(int argc, char **argv)\n \t\t\tunsigned char sha1[20];\n \t\t\tuint32_t crc;\n \t\t\tuint32_t off;\n-\t\t} *entries = xmalloc(nr * sizeof(entries[0]));\n+\t\t} *entries = malloc(nr * sizeof(entries[0]));\n \t\tfor (i = 0; i < nr; i++)\n \t\t\tif (fread(entries[i].sha1, 20, 1, stdin) != 1)\n \t\t\t\tdie(\"unable to read sha1 %u/%u\", i, nr);\n"},{"id":"132349","messageId":"7v636vj7c2.fsf@alter.siamese.dyndns.org","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211515470.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-22T00:45:17Z","receivedAt":"2010-01-22T00:45:17Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Thu, 21 Jan 2010, Linus Torvalds wrote:\n>> \n>> We could fix it a few ways\n>> \n>>  - ignore it. Most git programs will get the pack handling functions \n>>    anyway, since they want to get object reading.\n>\n> In fact, we should probably remove git-show-index. It may have some \n> historical significance as a pack-file index debugger, but it has no \n> actual redeeming features now, considering that the binary is a megabyte \n> of useless crud with debugging info.\n>\n> However, we do actually use it in t/t5302-pack-index.sh. So in the \n> meantime, how about this hacky patch to simply just avoid xmalloc, and \n> separating out the trivial hex functions into \"hex.o\".\n>\n> This results in\n>\n>   [torvalds@nehalem git]$ size git-show-index \n>        text    data     bss     dec     hex filename\n>      222818    2276  112688  337782   52776 git-show-index (before)\n>        5696     624    1264    7584    1da0 git-show-index (after)\n>\n> which is a whole lot better, no?\n>\n> (Or make it a built-in, if we actually think we want to carry it along in \n> the long run)\n\nWe tend to not remove things unless we are absolutely certain nobody uses\nit, so probably making it built-in would be preferrable.  I don't think\nshow-index is used very often if ever, but scripts that use hash-object\nwould use it really often and would do so via its --stdin interface if it\nknows that it is creating more than a dozen objects, so start-up time\nrequired to map the whole git is probably not an issue.\n\nBy the way, do you think anybody still uses \"git merge-trees\"?\n"},{"id":"132351","messageId":"alpine.DEB.1.00.1001220158381.4985@pacific.mpi-cbg.de","threadId":"22326","inReplyTo":"7v636vj7c2.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-22T00:59:14Z","receivedAt":"2010-01-22T00:59:14Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 21 Jan 2010, Junio C Hamano wrote:\n\n> By the way, do you think anybody still uses \"git merge-trees\"?\n\nIMO this is the only viable way to a non-broken merge-recursive.  Removing \nit would be counterproductive.\n\nCiao,\nDscho\n"},{"id":"132353","messageId":"7v3a1zhrzz.fsf@alter.siamese.dyndns.org","threadId":"22326","inReplyTo":"alpine.DEB.1.00.1001220158381.4985@pacific.mpi-cbg.de","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-22T01:01:52Z","receivedAt":"2010-01-22T01:01:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> On Thu, 21 Jan 2010, Junio C Hamano wrote:\n>\n>> By the way, do you think anybody still uses \"git merge-trees\"?\n>\n> IMO this is the only viable way to a non-broken merge-recursive.  Removing \n> it would be counterproductive.\n\nDo you mean you don't think\n\n    Subject: Re: git-merge segfault in 1.6.6 and master\n    Date: Thu, 21 Jan 2010 16:38:56 -0800\n    Message-ID: <7vaaw7j7mn.fsf@alter.siamese.dyndns.org>\n\n    ...\n    In the meantime, I think applying this patch is the right thing to do.\n\n    -- >8 --\n    Subject: merge-recursive: do not return NULL only to cause segfault\n\nwould help us?\n"},{"id":"132354","messageId":"alpine.DEB.1.00.1001220242170.4985@pacific.mpi-cbg.de","threadId":"22326","inReplyTo":"7v3a1zhrzz.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-22T01:43:30Z","receivedAt":"2010-01-22T01:43:30Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 21 Jan 2010, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> > On Thu, 21 Jan 2010, Junio C Hamano wrote:\n> >\n> >> By the way, do you think anybody still uses \"git merge-trees\"?\n> >\n> > IMO this is the only viable way to a non-broken merge-recursive.  Removing \n> > it would be counterproductive.\n> \n> Do you mean you don't think\n> \n>     Subject: Re: git-merge segfault in 1.6.6 and master\n>     Date: Thu, 21 Jan 2010 16:38:56 -0800\n>     Message-ID: <7vaaw7j7mn.fsf@alter.siamese.dyndns.org>\n> \n>     ...\n>     In the meantime, I think applying this patch is the right thing to do.\n> \n>     -- >8 --\n>     Subject: merge-recursive: do not return NULL only to cause segfault\n> \n> would help us?\n\nSorry, I cannot have a look at this now.\n\nBut in the long run, I think that it gets tiring to chase all kinds of \nweird interactions between unpack_trees(), the rename detection and the \nrecursive merge.\n\nI could see merge-trees as a viable alternative approach.\n\nCiao,\nDscho\n"},{"id":"132362","messageId":"alpine.LFD.2.00.1001211811140.13231@localhost.localdomain","threadId":"22326","inReplyTo":"7v636vj7c2.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T02:20:14Z","receivedAt":"2010-01-22T02:20:14Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Junio C Hamano wrote:\n> \n> We tend to not remove things unless we are absolutely certain nobody uses\n> it, so probably making it built-in would be preferrable.  I don't think\n> show-index is used very often if ever, but scripts that use hash-object\n> would use it really often and would do so via its --stdin interface if it\n> knows that it is creating more than a dozen objects, so start-up time\n> required to map the whole git is probably not an issue.\n\ngit-show-index should certainly be easy to turn into a built-in too. Patch \nappended.\n\n> By the way, do you think anybody still uses \"git merge-trees\"?\n\nI dunno. I think it has some conceptual advantages, but realistically, I \ndoubt anybody is willing to go through the pain to make it grow up enough \nto become a viable alternative to our current situation.\n\n\t\tLinus\n\n---\nFrom: Linus Torvalds <torvalds@linux-foundation.org>\nDate: Thu Jan 21 18:16:49 2010 -0800\nSubject: Turn 'show-index' into a builtin\n\n.. rather than being a huge executable just because it sucks in all the\ngit library code and then does something really trivial.\n\nSigned-off-by: Linus Torvalds <torvalds@linux-foundation.org>\n---\n Makefile                             |    2 +-\n show-index.c => builtin-show-index.c |    2 +-\n builtin.h                            |    1 +\n git.c                                |    3 ++-\n 4 files changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ad890ec..3439d2c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -396,7 +396,6 @@ PROGRAMS += git-mktag$X\n PROGRAMS += git-pack-redundant$X\n PROGRAMS += git-patch-id$X\n PROGRAMS += git-shell$X\n-PROGRAMS += git-show-index$X\n PROGRAMS += git-unpack-file$X\n PROGRAMS += git-upload-pack$X\n PROGRAMS += git-var$X\n@@ -693,6 +692,7 @@ BUILTIN_OBJS += builtin-rm.o\n BUILTIN_OBJS += builtin-send-pack.o\n BUILTIN_OBJS += builtin-shortlog.o\n BUILTIN_OBJS += builtin-show-branch.o\n+BUILTIN_OBJS += builtin-show-index.o\n BUILTIN_OBJS += builtin-show-ref.o\n BUILTIN_OBJS += builtin-stripspace.o\n BUILTIN_OBJS += builtin-symbolic-ref.o\ndiff --git a/show-index.c b/builtin-show-index.c\nsimilarity index 96%\nrename from show-index.c\nrename to builtin-show-index.c\nindex 63f9da5..92202b8 100644\n--- a/show-index.c\n+++ b/builtin-show-index.c\n@@ -4,7 +4,7 @@\n static const char show_index_usage[] =\n \"git show-index < <packed archive index>\";\n \n-int main(int argc, char **argv)\n+int cmd_show_index(int argc, const char **argv, const  char *prefix)\n {\n \tint i;\n \tunsigned nr;\ndiff --git a/builtin.h b/builtin.h\nindex c3f83c0..4d73d7c 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -93,6 +93,7 @@ extern int cmd_send_pack(int argc, const char **argv, const char *prefix);\n extern int cmd_shortlog(int argc, const char **argv, const char *prefix);\n extern int cmd_show(int argc, const char **argv, const char *prefix);\n extern int cmd_show_branch(int argc, const char **argv, const char *prefix);\n+extern int cmd_show_index(int argc, const char **argv, const char *prefix);\n extern int cmd_status(int argc, const char **argv, const char *prefix);\n extern int cmd_stripspace(int argc, const char **argv, const char *prefix);\n extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex 194471f..5fabf18 100644\n--- a/git.c\n+++ b/git.c\n@@ -358,8 +358,9 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"rm\", cmd_rm, RUN_SETUP },\n \t\t{ \"send-pack\", cmd_send_pack, RUN_SETUP },\n \t\t{ \"shortlog\", cmd_shortlog, USE_PAGER },\n-\t\t{ \"show-branch\", cmd_show_branch, RUN_SETUP },\n \t\t{ \"show\", cmd_show, RUN_SETUP | USE_PAGER },\n+\t\t{ \"show-branch\", cmd_show_branch, RUN_SETUP },\n+\t\t{ \"show-index\", cmd_show_index },\n \t\t{ \"status\", cmd_status, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"stripspace\", cmd_stripspace },\n \t\t{ \"symbolic-ref\", cmd_symbolic_ref, RUN_SETUP },\n"},{"id":"132363","messageId":"alpine.LFD.2.00.1001211823590.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211811140.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T02:25:20Z","receivedAt":"2010-01-22T02:25:20Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Linus Torvalds wrote:\n> \n> > By the way, do you think anybody still uses \"git merge-trees\"?\n> \n> I dunno. I think it has some conceptual advantages, but realistically, I \n> doubt anybody is willing to go through the pain to make it grow up enough \n> to become a viable alternative to our current situation.\n\nThis makes it a built-in, at least, so it doesn't waste the diskspace.\n\n\t\tLinus\n\n---\n Makefile                             |    2 +-\n merge-tree.c => builtin-merge-tree.c |    4 +---\n builtin.h                            |    1 +\n git.c                                |    1 +\n 4 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 3439d2c..35aea16 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -391,7 +391,6 @@ PROGRAMS += git-hash-object$X\n PROGRAMS += git-imap-send$X\n PROGRAMS += git-index-pack$X\n PROGRAMS += git-merge-index$X\n-PROGRAMS += git-merge-tree$X\n PROGRAMS += git-mktag$X\n PROGRAMS += git-pack-redundant$X\n PROGRAMS += git-patch-id$X\n@@ -670,6 +669,7 @@ BUILTIN_OBJS += builtin-merge-base.o\n BUILTIN_OBJS += builtin-merge-file.o\n BUILTIN_OBJS += builtin-merge-ours.o\n BUILTIN_OBJS += builtin-merge-recursive.o\n+BUILTIN_OBJS += builtin-merge-tree.o\n BUILTIN_OBJS += builtin-mktree.o\n BUILTIN_OBJS += builtin-mv.o\n BUILTIN_OBJS += builtin-name-rev.o\ndiff --git a/merge-tree.c b/builtin-merge-tree.c\nsimilarity index 99%\nrename from merge-tree.c\nrename to builtin-merge-tree.c\nindex 37b94d9..8e16c3e 100644\n--- a/merge-tree.c\n+++ b/builtin-merge-tree.c\n@@ -337,7 +337,7 @@ static void *get_tree_descriptor(struct tree_desc *desc, const char *rev)\n \treturn buf;\n }\n \n-int main(int argc, char **argv)\n+int cmd_merge_tree(int argc, const char **argv, const char *prefix)\n {\n \tstruct tree_desc t[3];\n \tvoid *buf1, *buf2, *buf3;\n@@ -347,8 +347,6 @@ int main(int argc, char **argv)\n \n \tgit_extract_argv0_path(argv[0]);\n \n-\tsetup_git_directory();\n-\n \tbuf1 = get_tree_descriptor(t+0, argv[1]);\n \tbuf2 = get_tree_descriptor(t+1, argv[2]);\n \tbuf3 = get_tree_descriptor(t+2, argv[3]);\ndiff --git a/builtin.h b/builtin.h\nindex 4d73d7c..06bf04e 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -70,6 +70,7 @@ extern int cmd_merge_base(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_ours(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_file(int argc, const char **argv, const char *prefix);\n extern int cmd_merge_recursive(int argc, const char **argv, const char *prefix);\n+extern int cmd_merge_tree(int argc, const char **argv, const char *prefix);\n extern int cmd_mktree(int argc, const char **argv, const char *prefix);\n extern int cmd_mv(int argc, const char **argv, const char *prefix);\n extern int cmd_name_rev(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex 5fabf18..e5964a8 100644\n--- a/git.c\n+++ b/git.c\n@@ -335,6 +335,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"merge-recursive-ours\", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"merge-recursive-theirs\", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"merge-subtree\", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },\n+\t\t{ \"merge-tree\", cmd_merge_tree, RUN_SETUP },\n \t\t{ \"mktree\", cmd_mktree, RUN_SETUP },\n \t\t{ \"mv\", cmd_mv, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"name-rev\", cmd_name_rev, RUN_SETUP },\n"},{"id":"132365","messageId":"alpine.LFD.2.00.1001212131230.1726@xanadu.home","threadId":"22326","inReplyTo":"7v636vj7c2.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-22T02:35:08Z","receivedAt":"2010-01-22T02:35:08Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 21 Jan 2010, Junio C Hamano wrote:\n\n> Linus Torvalds <torvalds@linux-foundation.org> writes:\n> \n> > On Thu, 21 Jan 2010, Linus Torvalds wrote:\n> >> \n> >> We could fix it a few ways\n> >> \n> >>  - ignore it. Most git programs will get the pack handling functions \n> >>    anyway, since they want to get object reading.\n> >\n> > In fact, we should probably remove git-show-index. It may have some \n> > historical significance as a pack-file index debugger, but it has no \n> > actual redeeming features now, considering that the binary is a megabyte \n> > of useless crud with debugging info.\n> >\n> > However, we do actually use it in t/t5302-pack-index.sh. So in the \n> > meantime, how about this hacky patch to simply just avoid xmalloc, and \n> > separating out the trivial hex functions into \"hex.o\".\n> >\n> > This results in\n> >\n> >   [torvalds@nehalem git]$ size git-show-index \n> >        text    data     bss     dec     hex filename\n> >      222818    2276  112688  337782   52776 git-show-index (before)\n> >        5696     624    1264    7584    1da0 git-show-index (after)\n> >\n> > which is a whole lot better, no?\n> >\n> > (Or make it a built-in, if we actually think we want to carry it along in \n> > the long run)\n> \n> We tend to not remove things unless we are absolutely certain nobody uses\n> it, so probably making it built-in would be preferrable.  I don't think\n> show-index is used very often if ever, but scripts that use hash-object\n> would use it really often and would do so via its --stdin interface if it\n> knows that it is creating more than a dozen objects, so start-up time\n> required to map the whole git is probably not an issue.\n\nI do use it, but for developing/debugging pack stuff.\nI don't suggest removing it, but I don't think making it a built-in has \nvalue either.\n\nSo I really think that Linus' patch (which is missing hex.c btw) is a \ngood thing to do, even if only for the cleanup value.\n\nThen, git-show-index could probably become test-show-index and no longer \nleave the build directory.\n\n\nNicolas\n"},{"id":"132367","messageId":"alpine.LFD.2.00.1001211843160.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001212131230.1726@xanadu.home","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T02:44:37Z","receivedAt":"2010-01-22T02:44:37Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Nicolas Pitre wrote:\n> \n> So I really think that Linus' patch (which is missing hex.c btw) is a \n> good thing to do, even if only for the cleanup value.\n\nGaah. hex.c was the obvious code movement with just a \"cache.h\" include at \nthe top. However, I already threw away that whole tree in favor of the \nbuilt-in version, and now I'm too lazy to re-create it.\n\n\t\tLinus\n"},{"id":"132373","messageId":"alpine.LFD.2.00.1001211949250.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211823590.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T03:50:11Z","receivedAt":"2010-01-22T03:50:11Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Linus Torvalds wrote:\n> \n> This makes it a built-in, at least, so it doesn't waste the diskspace.\n\n.. and here's 'git hash-object' as a built-in.\n\n\t\tLinus\n\n---\n Makefile                               |    2 +-\n hash-object.c => builtin-hash-object.c |    5 +----\n builtin.h                              |    1 +\n git.c                                  |    1 +\n 4 files changed, 4 insertions(+), 5 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 35aea16..f9e4aa3 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -387,7 +387,6 @@ EXTRA_PROGRAMS =\n # ... and all the rest that could be moved out of bindir to gitexecdir\n PROGRAMS += $(EXTRA_PROGRAMS)\n PROGRAMS += git-fast-import$X\n-PROGRAMS += git-hash-object$X\n PROGRAMS += git-imap-send$X\n PROGRAMS += git-index-pack$X\n PROGRAMS += git-merge-index$X\n@@ -656,6 +655,7 @@ BUILTIN_OBJS += builtin-for-each-ref.o\n BUILTIN_OBJS += builtin-fsck.o\n BUILTIN_OBJS += builtin-gc.o\n BUILTIN_OBJS += builtin-grep.o\n+BUILTIN_OBJS += builtin-hash-object.o\n BUILTIN_OBJS += builtin-help.o\n BUILTIN_OBJS += builtin-init-db.o\n BUILTIN_OBJS += builtin-log.o\ndiff --git a/hash-object.c b/builtin-hash-object.c\nsimilarity index 97%\nrename from hash-object.c\nrename to builtin-hash-object.c\nindex 9455dd0..6a5f5b5 100644\n--- a/hash-object.c\n+++ b/builtin-hash-object.c\n@@ -73,17 +73,14 @@ static const struct option hash_object_options[] = {\n \tOPT_END()\n };\n \n-int main(int argc, const char **argv)\n+int cmd_hash_object(int argc, const char **argv, const char *prefix)\n {\n \tint i;\n-\tconst char *prefix = NULL;\n \tint prefix_length = -1;\n \tconst char *errstr = NULL;\n \n \ttype = blob_type;\n \n-\tgit_extract_argv0_path(argv[0]);\n-\n \targc = parse_options(argc, argv, NULL, hash_object_options,\n \t\t\t     hash_object_usage, 0);\n \ndiff --git a/builtin.h b/builtin.h\nindex 06bf04e..3aa6b6c 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -55,6 +55,7 @@ extern int cmd_fsck(int argc, const char **argv, const char *prefix);\n extern int cmd_gc(int argc, const char **argv, const char *prefix);\n extern int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix);\n extern int cmd_grep(int argc, const char **argv, const char *prefix);\n+extern int cmd_hash_object(int argc, const char **argv, const char *prefix);\n extern int cmd_help(int argc, const char **argv, const char *prefix);\n extern int cmd_http_fetch(int argc, const char **argv, const char *prefix);\n extern int cmd_init_db(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex e5964a8..a952663 100644\n--- a/git.c\n+++ b/git.c\n@@ -318,6 +318,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"gc\", cmd_gc, RUN_SETUP },\n \t\t{ \"get-tar-commit-id\", cmd_get_tar_commit_id },\n \t\t{ \"grep\", cmd_grep, USE_PAGER },\n+\t\t{ \"hash-object\", cmd_hash_object },\n \t\t{ \"help\", cmd_help },\n \t\t{ \"init\", cmd_init_db },\n \t\t{ \"init-db\", cmd_init_db },\n"},{"id":"132372","messageId":"7vzl46bxxe.fsf@alter.siamese.dyndns.org","threadId":"22326","inReplyTo":"alpine.DEB.1.00.1001220242170.4985@pacific.mpi-cbg.de","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-22T03:50:21Z","receivedAt":"2010-01-22T03:50:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>>     In the meantime, I think applying this patch is the right thing to do.\n>> \n>>     -- >8 --\n>>     Subject: merge-recursive: do not return NULL only to cause segfault\n>> \n>> would help us?\n>\n> Sorry, I cannot have a look at this now.\n\nThat's fine; I know you've been busy outside git (you've kept saying that\nfor past several months), and I didn't really expect you to be single\nhandedly fixing or rewriting merge-recursive.  \"In the meantime\" patch is\nnot about attempting to \"fix\" anything deep inside the guts of it; it is\nmerely to die() with messages in a function that returned NULL when the\ncaller never expected to see NULL and caused segfault.\n\n> But in the long run, I think that it gets tiring to chase all kinds of \n> weird interactions between unpack_trees(), the rename detection and the \n> recursive merge.\n\nI don't think there is any interaction; as Tim Olsen reported, \"resolve\"\nthat uses the same unpack_trees() merges the trees just fine.  The bug\nseems to be all inside merge_recursive().\n"},{"id":"132374","messageId":"7vvdeubxnh.fsf@alter.siamese.dyndns.org","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001212131230.1726@xanadu.home","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-22T03:56:18Z","receivedAt":"2010-01-22T03:56:18Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> I do use it, but for developing/debugging pack stuff.  I don't suggest\n> removing it, but I don't think making it a built-in has value either.\n\nI thought people _might_ have used it for satistics purposes, but it\nappears that the command doesn't even give in-pack size of objects nor\ndelta chain length, so probably anybody doing pack statistics would be\nusing \"verify-pack -v\" and wouldn't mind if it became test-show-index.\n\n> So I really think that Linus' patch (which is missing hex.c btw) is a \n> good thing to do, even if only for the cleanup value.\n>\n> Then, git-show-index could probably become test-show-index and no longer \n> leave the build directory.\n\nYeah, I think that is a sensible long term plan, too.\n"},{"id":"132375","messageId":"alpine.LFD.2.00.1001211950480.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211119130.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T03:58:13Z","receivedAt":"2010-01-22T03:58:13Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Linus Torvalds wrote:\n> \n> It's not just that one file either. I get:\n> \n> \t[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core\n> \t45640\t/home/torvalds/libexec/git-core (before)\n> \t33508\t/home/torvalds/libexec/git-core (after)\n> \n> so we're talking 12MB of diskspace here. \n\nBtw, with the few built-in patches I've sent, it's now\n\n\t[torvalds@nehalem git]$ du -s /home/torvalds/libexec/git-core\n\t27876\t/home/torvalds/libexec/git-core\n\nso they're worth about 5.5M of disk-space.\n\nOf course, without debugging and with -Os, the difference is much smaller, \nand libexec ends up being \"just\" 8.6MB in size. There are still a number \nof trivial programs that could be made builtin.\n\nOptimally, I suspect just things like 'git-daemon' and the remote helpers \nwould be actual separate binaries.\n\n\t\tLinus\n"},{"id":"132378","messageId":"alpine.LFD.2.00.1001212014481.13231@localhost.localdomain","threadId":"22326","inReplyTo":"7vvdeubxnh.fsf@alter.siamese.dyndns.org","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T04:21:55Z","receivedAt":"2010-01-22T04:21:55Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Junio C Hamano wrote:\n\n> Nicolas Pitre <nico@fluxnic.net> writes:\n> \n> > I do use it, but for developing/debugging pack stuff.  I don't suggest\n> > removing it, but I don't think making it a built-in has value either.\n> \n> I thought people _might_ have used it for satistics purposes, but it\n> appears that the command doesn't even give in-pack size of objects nor\n> delta chain length, so probably anybody doing pack statistics would be\n> using \"verify-pack -v\" and wouldn't mind if it became test-show-index.\n> \n> > So I really think that Linus' patch (which is missing hex.c btw) is a \n> > good thing to do, even if only for the cleanup value.\n> >\n> > Then, git-show-index could probably become test-show-index and no longer \n> > leave the build directory.\n> \n> Yeah, I think that is a sensible long term plan, too.\n\nNote that there are other totally trivial git programs like 'git-var' that \nhave exactly the same issue as 'git-show-index'.\n\nSame details: it doesn't really want any diff machinery, doesn't want any \ngit object handling, but can't avoid it because it uses xmalloc (through \nenvironment.c and config.c etc), so a program that _should_ be pretty \ntrivially small again ends up being 200+kB in size even without debug \ninfo (and almost a megabyte with it).\n\nSo here's another trivial builtin-ification patch.\n\n\t\tLinus\n\n---\n Makefile               |    2 +-\n var.c => builtin-var.c |    4 +---\n builtin.h              |    1 +\n git.c                  |    1 +\n 4 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex f9e4aa3..398b5fb 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -396,7 +396,6 @@ PROGRAMS += git-patch-id$X\n PROGRAMS += git-shell$X\n PROGRAMS += git-unpack-file$X\n PROGRAMS += git-upload-pack$X\n-PROGRAMS += git-var$X\n PROGRAMS += git-http-backend$X\n \n # List built-in command $C whose implementation cmd_$C() is not in\n@@ -703,6 +702,7 @@ BUILTIN_OBJS += builtin-update-index.o\n BUILTIN_OBJS += builtin-update-ref.o\n BUILTIN_OBJS += builtin-update-server-info.o\n BUILTIN_OBJS += builtin-upload-archive.o\n+BUILTIN_OBJS += builtin-var.o\n BUILTIN_OBJS += builtin-verify-pack.o\n BUILTIN_OBJS += builtin-verify-tag.o\n BUILTIN_OBJS += builtin-write-tree.o\ndiff --git a/var.c b/builtin-var.c\nsimilarity index 96%\nrename from var.c\nrename to builtin-var.c\nindex d9892f8..2280518 100644\n--- a/var.c\n+++ b/builtin-var.c\n@@ -72,7 +72,7 @@ static int show_config(const char *var, const char *value, void *cb)\n \treturn git_default_config(var, value, cb);\n }\n \n-int main(int argc, char **argv)\n+int cmd_var(int argc, const char **argv, const char *prefix)\n {\n \tconst char *val;\n \tint nongit;\n@@ -80,8 +80,6 @@ int main(int argc, char **argv)\n \t\tusage(var_usage);\n \t}\n \n-\tgit_extract_argv0_path(argv[0]);\n-\n \tsetup_git_directory_gently(&nongit);\n \tval = NULL;\n \ndiff --git a/builtin.h b/builtin.h\nindex 3aa6b6c..0c9c396 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -107,6 +107,7 @@ extern int cmd_update_ref(int argc, const char **argv, const char *prefix);\n extern int cmd_update_server_info(int argc, const char **argv, const char *prefix);\n extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);\n extern int cmd_upload_tar(int argc, const char **argv, const char *prefix);\n+extern int cmd_var(int argc, const char **argv, const char *prefix);\n extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);\n extern int cmd_version(int argc, const char **argv, const char *prefix);\n extern int cmd_whatchanged(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex a952663..09d3272 100644\n--- a/git.c\n+++ b/git.c\n@@ -373,6 +373,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"update-ref\", cmd_update_ref, RUN_SETUP },\n \t\t{ \"update-server-info\", cmd_update_server_info, RUN_SETUP },\n \t\t{ \"upload-archive\", cmd_upload_archive },\n+\t\t{ \"var\", cmd_var },\n \t\t{ \"verify-tag\", cmd_verify_tag, RUN_SETUP },\n \t\t{ \"version\", cmd_version },\n \t\t{ \"whatchanged\", cmd_whatchanged, RUN_SETUP | USE_PAGER },\n"},{"id":"132379","messageId":"alpine.LFD.2.00.1001212025270.13231@localhost.localdomain","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001212131230.1726@xanadu.home","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T04:31:25Z","receivedAt":"2010-01-22T04:31:25Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 21 Jan 2010, Nicolas Pitre wrote:\n> \n> So I really think that Linus' patch (which is missing hex.c btw) is a \n> good thing to do, even if only for the cleanup value.\n\nBtw, it looks like the separate hex.c would fix not just git-show-index \n(together with de-xmalloc), but also make git-patch-id shrink down. Except \ngit-patch-id for some reason does git_extract_argv0_path(), which brings \nin exec_cmd.o, which brings in strbuf, and xmalloc, and now it's all the \nsame old pain again.\n\nSo rather than try to solve it all (xmalloc in particular is pretty \nhairy), here's another patch.\n\n\t\tLinus\n---\n Makefile                         |    2 +-\n patch-id.c => builtin-patch-id.c |    4 +---\n builtin.h                        |    1 +\n git.c                            |    1 +\n 4 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 398b5fb..5b614e4 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -392,7 +392,6 @@ PROGRAMS += git-index-pack$X\n PROGRAMS += git-merge-index$X\n PROGRAMS += git-mktag$X\n PROGRAMS += git-pack-redundant$X\n-PROGRAMS += git-patch-id$X\n PROGRAMS += git-shell$X\n PROGRAMS += git-unpack-file$X\n PROGRAMS += git-upload-pack$X\n@@ -674,6 +673,7 @@ BUILTIN_OBJS += builtin-mv.o\n BUILTIN_OBJS += builtin-name-rev.o\n BUILTIN_OBJS += builtin-pack-objects.o\n BUILTIN_OBJS += builtin-pack-refs.o\n+BUILTIN_OBJS += builtin-patch-id.o\n BUILTIN_OBJS += builtin-prune-packed.o\n BUILTIN_OBJS += builtin-prune.o\n BUILTIN_OBJS += builtin-push.o\ndiff --git a/patch-id.c b/builtin-patch-id.c\nsimilarity index 95%\nrename from patch-id.c\nrename to builtin-patch-id.c\nindex 0df4cb0..af0911e 100644\n--- a/patch-id.c\n+++ b/builtin-patch-id.c\n@@ -75,13 +75,11 @@ static void generate_id_list(void)\n \n static const char patch_id_usage[] = \"git patch-id < patch\";\n \n-int main(int argc, char **argv)\n+int cmd_patch_id(int argc, const char **argv, const char *prefix)\n {\n \tif (argc != 1)\n \t\tusage(patch_id_usage);\n \n-\tgit_extract_argv0_path(argv[0]);\n-\n \tgenerate_id_list();\n \treturn 0;\n }\ndiff --git a/builtin.h b/builtin.h\nindex 0c9c396..ab723f8 100644\n--- a/builtin.h\n+++ b/builtin.h\n@@ -76,6 +76,7 @@ extern int cmd_mktree(int argc, const char **argv, const char *prefix);\n extern int cmd_mv(int argc, const char **argv, const char *prefix);\n extern int cmd_name_rev(int argc, const char **argv, const char *prefix);\n extern int cmd_pack_objects(int argc, const char **argv, const char *prefix);\n+extern int cmd_patch_id(int argc, const char **argv, const char *prefix);\n extern int cmd_pickaxe(int argc, const char **argv, const char *prefix);\n extern int cmd_prune(int argc, const char **argv, const char *prefix);\n extern int cmd_prune_packed(int argc, const char **argv, const char *prefix);\ndiff --git a/git.c b/git.c\nindex 09d3272..e38f201 100644\n--- a/git.c\n+++ b/git.c\n@@ -341,6 +341,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"mv\", cmd_mv, RUN_SETUP | NEED_WORK_TREE },\n \t\t{ \"name-rev\", cmd_name_rev, RUN_SETUP },\n \t\t{ \"pack-objects\", cmd_pack_objects, RUN_SETUP },\n+\t\t{ \"patch-id\", cmd_patch_id },\n \t\t{ \"peek-remote\", cmd_ls_remote },\n \t\t{ \"pickaxe\", cmd_blame, RUN_SETUP },\n \t\t{ \"prune\", cmd_prune, RUN_SETUP },\n"},{"id":"132389","messageId":"4B596519.8060508@viscovery.net","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211823590.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2010-01-22T08:43:05Z","receivedAt":"2010-01-22T08:43:05Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Linus Torvalds schrieb:\n> @@ -347,8 +347,6 @@ int main(int argc, char **argv)\n>  \n>  \tgit_extract_argv0_path(argv[0]);\n\nThis line must go away as well.\n\n> -\tsetup_git_directory();\n> -\n\n-- Hannes\n"},{"id":"132397","messageId":"1264160879-26079-1-git-send-email-j6t@kdbg.org","threadId":"22326","inReplyTo":"4B596519.8060508@viscovery.net","subject":"[PATCH] merge-tree: remove unnecessary call of git_extract_argv0_path","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2010-01-22T11:47:59Z","receivedAt":"2010-01-22T11:47:59Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"This call should have been removed when the utility was made a builtin by\n907a7cb.\n\nSigned-off-by: Johannes Sixt <j6t@kdbg.org>\n---\n builtin-merge-tree.c |    2 --\n 1 files changed, 0 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin-merge-tree.c b/builtin-merge-tree.c\nindex 8e16c3e..a4a4f2c 100644\n--- a/builtin-merge-tree.c\n+++ b/builtin-merge-tree.c\n@@ -345,8 +345,6 @@ int cmd_merge_tree(int argc, const char **argv, const char *prefix)\n \tif (argc != 4)\n \t\tusage(merge_tree_usage);\n \n-\tgit_extract_argv0_path(argv[0]);\n-\n \tbuf1 = get_tree_descriptor(t+0, argv[1]);\n \tbuf2 = get_tree_descriptor(t+1, argv[2]);\n \tbuf3 = get_tree_descriptor(t+2, argv[3]);\n-- \n1.6.6.1.372.g084d\n"},{"id":"132406","messageId":"alpine.LFD.2.00.1001220840120.13231@localhost.localdomain","threadId":"22326","inReplyTo":"1264160879-26079-1-git-send-email-j6t@kdbg.org","subject":"Re: [PATCH] merge-tree: remove unnecessary call of git_extract_argv0_path","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2010-01-22T16:40:29Z","receivedAt":"2010-01-22T16:40:29Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 22 Jan 2010, Johannes Sixt wrote:\n>\n> This call should have been removed when the utility was made a builtin by\n> 907a7cb.\n\nAck.\n\n\t\t\tLinus\n"},{"id":"132453","messageId":"18EEE333-C31B-4648-A9A5-F828C1582C10@continuation.org","threadId":"22326","inReplyTo":"alpine.LFD.2.00.1001211119130.13231@localhost.localdomain","subject":"Re: Remove diff machinery dependency from read-cache","fromName":"Brian Campbell","fromEmail":"lambda@continuation.org","sentAt":"2010-01-23T06:31:35Z","receivedAt":"2010-01-23T06:31:35Z","isPatch":false,"sender":{"key":"lambda@continuation.org","avatar":null},"body":"On Jan 21, 2010, at 2:37 PM, Linus Torvalds wrote:\n\n> ---\n> builtin-add.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n> read-cache.c  |   78 ---------------------------------------------------------\n> 2 files changed, 76 insertions(+), 78 deletions(-)\n> \n> diff --git a/builtin-add.c b/builtin-add.c\n> index cb6e590..2705f8d 100644\n\nI've recently tried building \"master\" from git://git.kernel.org/pub/scm/git/git.git, and got the following error:\n\n    $ make\n...snip...\t\n        LINK git-fast-import\n    Undefined symbols:\n      \"_git_mailmap_file\", referenced from:\n          _git_default_config in libgit.a(config.o)\n    ld: symbol(s) not found\n    collect2: ld returned 1 exit status\n    make: *** [git-fast-import] Error 1\n\nWhen I bisect, I find this commit to blame:\n\n    $ git bisect start master v1.6.6.1\n    Bisecting: 197 revisions left to test after this (roughly 8 steps)\n    [f8eb50f60b5c8efda3529fcf89517080c686ce0b] Merge branch 'jh/commit-status'\n    $ git bisect run make -j2\n    running make -j2\n    GIT_VERSION = 1.6.6.240.gf8eb5\n...snip...\n    fb7d3f32b283a3847e6f151a06794abd14ffd81b is the first bad commit\n    commit fb7d3f32b283a3847e6f151a06794abd14ffd81b\n    Author: Linus Torvalds <torvalds@linux-foundation.org>\n    Date:   Thu Jan 21 11:37:38 2010 -0800\n\nI also verified that it fails from with \"make clean; make\", so a dirty tree or -j2 aren't to blame. I'm not terribly familiar with the code base, so I'm a bit puzzled about why this commit would have cause the error that it does; I don't see any obvious connection between add_files_to_cache() and git_mailmap_file. \n\nCan anyone explain why I'd be seeing such an error? Is this a problem on my end?\n\n    $ uname -a\n    Darwin erlang.local 10.2.0 Darwin Kernel Version 10.2.0: Tue Nov  3 10:37:10 PST 2009; root:xnu-1486.2.11~1/RELEASE_I386 i386\n    $ gcc --version\n    i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5646) (dot 1)\n    Copyright (C) 2007 Free Software Foundation, Inc.\n    This is free software; see the source for copying conditions.  There is NO\n    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"}]}