{"thread":{"id":"7576","subject":"[PATCH 7/8] git-repack --max-pack-size: split packs as asked by write_object/write_one","startedAt":"2007-04-08T23:26:07Z","lastAt":"2007-04-08T23:26:07Z","messageCount":1,"participants":["Dana How"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"38895","messageId":"46197A0F.2090400@gmail.com","threadId":"7576","inReplyTo":null,"subject":"[PATCH 7/8] git-repack --max-pack-size: split packs as asked by write_object/write_one","fromName":"Dana How","fromEmail":"danahow@gmail.com","sentAt":"2007-04-08T23:26:07Z","receivedAt":"2007-04-08T23:26:07Z","isPatch":true,"sender":{"key":"danahow@gmail.com","avatar":null},"body":"\nRewrite write_pack_file() to break to a new packfile\nwhenever write_object/write_one request it,  and\ncorrect the header's object count in the previous packfile.\nChange write_index_file() to write an index\nfor just the objects in the most recent packfile.\n\nSigned-off-by: Dana How <how@deathvalley.cswitch.com>\n---\n builtin-pack-objects.c |  126 ++++++++++++++++++++++++++++++++++--------------\n 1 files changed, 89 insertions(+), 37 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex a088f2e..d750c4b 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -572,6 +572,7 @@ static off_t write_one(struct sha1file *f,\n \tresult = write_object(f, e, offset_limit && nr_written ? offset_limit - offset : 0);\n \tif (!result)\n \t\treturn result;\n+\twritten_list[nr_written++] = e;\n \te->offset = offset;\n \treturn offset + result;\n }\n@@ -628,52 +629,103 @@ static void write_index_file(void);\n \n static void write_pack_file(void)\n {\n-\tuint32_t i;\n+\tuint32_t i, j;\n \tstruct sha1file *f;\n \toff_t offset;\n \tstruct pack_header hdr;\n \tunsigned last_percent = 999;\n-\tint do_progress = progress;\n+\tint do_progress = progress >> !base_name;\n+\tchar oldname[PATH_MAX];\n+\tint pack_fd;\n+\tSHA_CTX ctx;\n \n-\tif (!base_name) {\n-\t\tf = sha1fd(1, \"<stdout>\");\n-\t\tdo_progress >>= 1;\n-\t}\n-\telse\n-\t\tf = sha1create(\"%s-%s.%s\", base_name,\n-\t\t\t       sha1_to_hex(object_list_sha1), \"pack\");\n \tif (do_progress)\n \t\tfprintf(stderr, \"Writing %u objects.\\n\", nr_result);\n+\twritten_list = xmalloc(nr_objects * sizeof(struct object_entry *));\n \n-\thdr.hdr_signature = htonl(PACK_SIGNATURE);\n-\thdr.hdr_version = htonl(PACK_VERSION);\n-\thdr.hdr_entries = htonl(nr_result);\n-\tsha1write(f, &hdr, sizeof(hdr));\n-\toffset = sizeof(hdr);\n-\tif (!nr_result)\n-\t\tgoto done;\n-\tfor (i = 0; i < nr_objects; i++) {\n-\t\toffset = write_one(f, objects + i, offset);\n-\t\tif (do_progress) {\n-\t\t\tunsigned percent = written * 100 / nr_result;\n-\t\t\tif (progress_update || percent != last_percent) {\n-\t\t\t\tfprintf(stderr, \"%4u%% (%u/%u) done\\r\",\n-\t\t\t\t\tpercent, written, nr_result);\n-\t\t\t\tprogress_update = 0;\n-\t\t\t\tlast_percent = percent;\n+\tfor (i = 0; i < nr_objects;) {\n+\t\tif (!base_name) {\n+\t\t\tf = sha1fd(pack_fd = 1, \"<stdout>\");\n+\t\t}\n+\t\telse {\n+\t\t\tint len = snprintf(oldname, sizeof oldname, \"%s-XXXXXX\", base_name);\n+\t\t\tif (len >= PATH_MAX)\n+\t\t\t\tdie(\"excessive pathname length for initial packfile name\");\n+\t\t\tpack_fd = mkstemp(oldname);\n+\t\t\tif (pack_fd < 0)\n+\t\t\t\tdie(\"can't create %s: %s\", oldname, strerror(errno));\n+\t\t\tf = sha1fd(pack_fd, oldname);\n+\t\t}\n+\n+\t\thdr.hdr_signature = htonl(PACK_SIGNATURE);\n+\t\thdr.hdr_version = htonl(PACK_VERSION);\n+\t\thdr.hdr_entries = htonl(nr_result);\n+\t\tsha1write(f, &hdr, sizeof(hdr));\n+\t\toffset = sizeof(hdr);\n+\t\tnr_written = 0;\n+\t\tfor (; i < nr_objects; i++) {\n+\t\t\toff_t offset_one = write_one(f, objects + i, offset);\n+\t\t\tif (!offset_one)\n+\t\t\t\tbreak;\n+\t\t\toffset = offset_one;\n+\t\t\tif (do_progress) {\n+\t\t\t\tunsigned percent = written * 100 / nr_result;\n+\t\t\t\tif (progress_update || percent != last_percent) {\n+\t\t\t\t\tfprintf(stderr, \"%4u%% (%u/%u) done\\r\",\n+\t\t\t\t\t\tpercent, written, nr_result);\n+\t\t\t\t\tprogress_update = 0;\n+\t\t\t\t\tlast_percent = percent;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n+\n+\t\t/*\n+\t\t * Did we write the wrong # entries in the header?\n+\t\t * If so, rewrite it like in fast-import (gackk).\n+\t\t */\n+\t\tif ( !base_name || nr_written == nr_result ) {\n+\t\t\tsha1close(f, pack_file_sha1, 1);\n+\t\t} else {\n+\t\t\tsha1close(f, pack_file_sha1, -1);\n+\t\t\tfixup_header_footer(pack_fd, pack_file_sha1, oldname, nr_written);\n+\t\t}\n+\n+\t\t/*\n+\t\t * compute object_list_sha1 of sorted sha's we just wrote out;\n+\t\t * we also mark these objects as written\n+\t\t */\n+\t\tcurrent_sort = sha1_sort;\n+\t\tqsort(written_list, nr_written, sizeof(struct object_entry *), sort_comparator);\n+\t\tSHA1_Init(&ctx);\n+\t\tfor (j = 0; j < nr_written; j++) {\n+\t\t\tstruct object_entry *entry = written_list[j];\n+\t\t\tentry->prev_pack = 1;\n+\t\t\tSHA1_Update(&ctx, entry->sha1, 20);\n+\t\t}\n+\t\tSHA1_Final(object_list_sha1, &ctx);\n+\t\t/*\n+\t\t * now we can rename the pack correctly and write the index file\n+\t\t */\n+\t\tif (base_name) {\n+\t\t\tchar newname[PATH_MAX];\n+\t\t\tint len = snprintf(newname, sizeof newname, \"%s-%s.%s\",\n+\t\t\t\t\t\tbase_name, sha1_to_hex(object_list_sha1), \"pack\");\n+\t\t\tif (len >= PATH_MAX)\n+\t\t\t\tdie(\"excessive pathname length for final packfile name\");\n+\t\t\tif (rename(oldname, newname) < 0)\n+\t\t\t\tdie(\"could not rename the pack file\");\n+\t\t}\n+\t\tif (!pack_to_stdout) {\n+\t\t\twrite_index_file();\n+\t\t\tputs(sha1_to_hex(object_list_sha1));\n+\t\t}\n \t}\n-\tif (do_progress)\n+\n+\tfree(written_list);\n+\tif (nr_result && do_progress)\n \t\tfputc('\\n', stderr);\n- done:\n \tif (written != nr_result)\n \t\tdie(\"wrote %u objects while expecting %u\", written, nr_result);\n-\tsha1close(f, pack_file_sha1, 1);\n-\tif (!pack_to_stdout) {\n-\t\twrite_index_file();\n-\t\tputs(sha1_to_hex(object_list_sha1));\n-\t}\n }\n \n static void write_index_file(void)\n@@ -681,8 +733,8 @@ static void write_index_file(void)\n \tuint32_t i;\n \tstruct sha1file *f = sha1create(\"%s-%s.%s\", base_name,\n \t\t\t\t\tsha1_to_hex(object_list_sha1), \"idx\");\n-\tstruct object_entry **list = sorted_by_sha;\n-\tstruct object_entry **last = list + nr_result;\n+\tstruct object_entry **list = written_list;\n+\tstruct object_entry **last = list + nr_written;\n \tuint32_t array[256];\n \n \t/*\n@@ -698,7 +750,7 @@ static void write_index_file(void)\n \t\t\t\tbreak;\n \t\t\tnext++;\n \t\t}\n-\t\tarray[i] = htonl(next - sorted_by_sha);\n+\t\tarray[i] = htonl(next - written_list);\n \t\tlist = next;\n \t}\n \tsha1write(f, array, 256 * 4);\n@@ -706,8 +758,8 @@ static void write_index_file(void)\n \t/*\n \t * Write the actual SHA1 entries..\n \t */\n-\tlist = sorted_by_sha;\n-\tfor (i = 0; i < nr_result; i++) {\n+\tlist = written_list;\n+\tfor (i = 0; i < nr_written; i++) {\n \t\tstruct object_entry *entry = *list++;\n \t\tuint32_t offset = htonl(entry->offset);\n \t\tsha1write(f, &offset, 4);\n-- \n1.5.1.89.g8abf0\n"}]}