{"thread":{"id":"4355","subject":"[PATCH] handle concurrent pruning of packed objects","startedAt":"2006-05-30T15:56:11Z","lastAt":"2006-05-30T15:56:11Z","messageCount":1,"participants":["Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"20975","messageId":"20060530155611.GA16006@coredump.intra.peff.net","threadId":"4355","inReplyTo":null,"subject":"[PATCH] handle concurrent pruning of packed objects","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2006-05-30T15:56:11Z","receivedAt":"2006-05-30T15:56:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"This patch causes read_sha1_file and sha1_object_info to re-examine the\nlist of packs if an object cannot be found. It works by re-running\nprepare_packed_git() after an object fails to be found.\n\nIt does not attempt to clean up the old pack list. Old packs which are in\nuse can continue to be used (until unused by lru selection).  New packs\nare placed at the front of the list and will thus be examined before old\npacks.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n\nI tested this by making a simple repo with three commits: a, b, and c.\nI ran git diff-tree --stdin, and then did the following:\n  1. fed 'a b' to diff-tree\n  2. ran git repack -a -d\n  3. fed 'b c' to diff-tree\nVanilla git complains about the lack of object, whereas this version\nprovides the correct diff-tree output.\n\n sha1_file.c |   24 ++++++++++++++++++------\n 1 files changed, 18 insertions(+), 6 deletions(-)\n\ndiff --git a/sha1_file.c b/sha1_file.c\nindex f77c189..696e53f 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -626,12 +626,12 @@ static void prepare_packed_git_one(char \n \tclosedir(dir);\n }\n \n+static int prepare_packed_git_run_once = 0;\n void prepare_packed_git(void)\n {\n-\tstatic int run_once = 0;\n \tstruct alternate_object_database *alt;\n \n-\tif (run_once)\n+\tif (prepare_packed_git_run_once)\n \t\treturn;\n \tprepare_packed_git_one(get_object_directory(), 1);\n \tprepare_alt_odb();\n@@ -640,7 +640,13 @@ void prepare_packed_git(void)\n \t\tprepare_packed_git_one(alt->base, 0);\n \t\talt->name[-1] = '/';\n \t}\n-\trun_once = 1;\n+\tprepare_packed_git_run_once = 1;\n+}\n+\n+static void reprepare_packed_git(void)\n+{\n+\tprepare_packed_git_run_once = 0;\n+\tprepare_packed_git();\n }\n \n int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)\n@@ -1212,9 +1218,12 @@ int sha1_object_info(const unsigned char\n \tif (!map) {\n \t\tstruct pack_entry e;\n \n-\t\tif (!find_pack_entry(sha1, &e))\n-\t\t\treturn error(\"unable to find %s\", sha1_to_hex(sha1));\n-\t\treturn packed_object_info(&e, type, sizep);\n+\t\tif (find_pack_entry(sha1, &e))\n+\t\t\treturn packed_object_info(&e, type, sizep);\n+\t\treprepare_packed_git();\n+\t\tif (find_pack_entry(sha1, &e))\n+\t\t\treturn packed_object_info(&e, type, sizep);\n+\t\treturn error(\"unable to find %s\", sha1_to_hex(sha1));\n \t}\n \tif (unpack_sha1_header(&stream, map, mapsize, hdr, sizeof(hdr)) < 0)\n \t\tstatus = error(\"unable to unpack %s header\",\n@@ -1256,6 +1265,9 @@ void * read_sha1_file(const unsigned cha\n \t\tmunmap(map, mapsize);\n \t\treturn buf;\n \t}\n+\treprepare_packed_git();\n+\tif (find_pack_entry(sha1, &e))\n+\t\treturn read_packed_sha1(sha1, type, size);\n \treturn NULL;\n }\n \n-- \n1.3.3.g331f\n"}]}