{"thread":{"id":"8041","subject":"[PATCH 3/4] git-repack --max-pack-size: split packs as asked by write_{object,one}()","startedAt":"2007-05-08T20:04:20Z","lastAt":"2007-05-08T20:04:20Z","messageCount":1,"participants":["Dana How"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"41490","messageId":"4640D7C4.8020907@gmail.com","threadId":"8041","inReplyTo":null,"subject":"[PATCH 3/4] git-repack --max-pack-size: split packs as asked by write_{object,one}()","fromName":"Dana How","fromEmail":"danahow@gmail.com","sentAt":"2007-05-08T20:04:20Z","receivedAt":"2007-05-08T20:04:20Z","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 L. How <danahow@gmail.com>\n---\n builtin-pack-objects.c |  120 ++++++++++++++++++++++++++++-------------------\n 1 files changed, 71 insertions(+), 49 deletions(-)\n\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex fbff8fa..2932b88 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -636,6 +636,7 @@ static off_t write_one(struct sha1file *f,\n \t\te->offset = 0;\n \t\treturn 0;\n \t}\n+\twritten_list[nr_written++] = e;\n \n \t/* make sure off_t is sufficiently large not to wrap */\n \tif (offset > offset + size)\n@@ -655,47 +656,57 @@ static int adjust_perm(const char *path, mode_t mode);\n \n static void write_pack_file(void)\n {\n-\tuint32_t i;\n+\tuint32_t i = 0, j;\n \tstruct sha1file *f;\n-\toff_t offset, last_obj_offset = 0;\n+\toff_t offset, offset_one, last_obj_offset = 0;\n \tstruct pack_header hdr;\n-\tint do_progress = progress;\n-\n-\tif (pack_to_stdout) {\n-\t\tf = sha1fd(1, \"<stdout>\");\n-\t\tdo_progress >>= 1;\n-\t} else {\n-\t\tint fd = open_object_dir_tmp(\"tmp_pack_XXXXXX\");\n-\t\tif (fd < 0)\n-\t\t\tdie(\"unable to create %s: %s\\n\", tmpname, strerror(errno));\n-\t\tpack_tmp_name = xstrdup(tmpname);\n-\t\tf = sha1fd(fd, pack_tmp_name);\n-\t}\n+\tint do_progress = progress >> pack_to_stdout;\n+\tuint32_t nr_remaining = nr_result;\n \n \tif (do_progress)\n \t\tstart_progress(&progress_state, \"Writing %u objects...\", \"\", 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\tlast_obj_offset = offset;\n-\t\toffset = write_one(f, objects + i, offset);\n-\t\tif (do_progress)\n-\t\t\tdisplay_progress(&progress_state, written);\n-\t}\n-\tif (do_progress)\n-\t\tstop_progress(&progress_state);\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+\tdo {\n+\t\tif (pack_to_stdout) {\n+\t\t\tf = sha1fd(1, \"<stdout>\");\n+\t\t} else {\n+\t\t\tint fd = open_object_dir_tmp(\"tmp_pack_XXXXXX\");\n+\t\t\tif (fd < 0)\n+\t\t\t\tdie(\"unable to create %s: %s\\n\", tmpname, strerror(errno));\n+\t\t\tpack_tmp_name = xstrdup(tmpname);\n+\t\t\tf = sha1fd(fd, pack_tmp_name);\n+\t\t}\n \n-\tif (!pack_to_stdout) {\n+\t\thdr.hdr_signature = htonl(PACK_SIGNATURE);\n+\t\thdr.hdr_version = htonl(PACK_VERSION);\n+\t\thdr.hdr_entries = htonl(nr_remaining);\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\tlast_obj_offset = offset;\n+\t\t\toffset_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\tdisplay_progress(&progress_state, written);\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\n+\t\t */\n+\t\tif (pack_to_stdout || nr_written == nr_remaining) {\n+\t\t\tsha1close(f, pack_file_sha1, 1);\n+\t\t} else {\n+\t\t\tsha1close(f, pack_file_sha1, 0);\n+\t\t\tfixup_pack_header_footer(f->fd, pack_file_sha1, pack_tmp_name, nr_written);\n+\t\t\tclose(f->fd);\n+\t\t}\n+\n+\t\tif (!pack_to_stdout) {\n \t\t\tunsigned char object_list_sha1[20];\n \t\t\tmode_t mode = umask(0);\n \n@@ -720,7 +731,26 @@ static void write_pack_file(void)\n \t\t\t\tdie(\"unable to rename temporary index file: %s\",\n \t\t\t\t    strerror(errno));\n \t\t\tputs(sha1_to_hex(object_list_sha1));\n+\t\t}\n+\n+\t\t/* mark written objects as written to previous pack */\n+\t\tfor (j = 0; j < nr_written; j++) {\n+\t\t\twritten_list[j]->offset = (off_t)-1;\n+\t\t}\n+\t\tnr_remaining -= nr_written;\n+\t} while (nr_remaining && i < nr_objects);\n+\n+\tfree(written_list);\n+\tif (do_progress)\n+\t\tstop_progress(&progress_state);\n+\tif (written != nr_result)\n+\t\tdie(\"wrote %u objects while expecting %u\", written, nr_result);\n+\tfor (j = 0; i < nr_objects; i++) {\n+\t\tstruct object_entry *e = objects + i;\n+\t\tj += !e->offset && !e->preferred_base;\n \t}\n+\tif (j)\n+\t\tdie(\"wrote %u objects as expected but %u unwritten\", written, j);\n }\n \n static int sha1_sort(const void *_a, const void *_b)\n@@ -747,18 +777,11 @@ static void write_index_file(off_t last_obj_offset, unsigned char *sha1)\n \tidx_tmp_name = xstrdup(tmpname);\n \tf = sha1fd(fd, idx_tmp_name);\n \n-\tif (nr_result) {\n-\t\tuint32_t j = 0;\n-\t\tsorted_by_sha =\n-\t\t\txcalloc(nr_result, sizeof(struct object_entry *));\n-\t\tfor (i = 0; i < nr_objects; i++)\n-\t\t\tif (!objects[i].preferred_base)\n-\t\t\t\tsorted_by_sha[j++] = objects + i;\n-\t\tif (j != nr_result)\n-\t\t\tdie(\"listed %u objects while expecting %u\", j, nr_result);\n-\t\tqsort(sorted_by_sha, nr_result, sizeof(*sorted_by_sha), sha1_sort);\n+\tif (nr_written) {\n+\t\tsorted_by_sha = written_list;\n+\t\tqsort(sorted_by_sha, nr_written, sizeof(*sorted_by_sha), sha1_sort);\n \t\tlist = sorted_by_sha;\n-\t\tlast = sorted_by_sha + nr_result;\n+\t\tlast = sorted_by_sha + nr_written;\n \t} else\n \t\tsorted_by_sha = list = last = NULL;\n \n@@ -796,7 +819,7 @@ static void write_index_file(off_t last_obj_offset, unsigned char *sha1)\n \n \t/* Write the actual SHA1 entries. */\n \tlist = sorted_by_sha;\n-\tfor (i = 0; i < nr_result; i++) {\n+\tfor (i = 0; i < nr_written; i++) {\n \t\tstruct object_entry *entry = *list++;\n \t\tif (index_version < 2) {\n \t\t\tuint32_t offset = htonl(entry->offset);\n@@ -811,7 +834,7 @@ static void write_index_file(off_t last_obj_offset, unsigned char *sha1)\n \n \t\t/* write the crc32 table */\n \t\tlist = sorted_by_sha;\n-\t\tfor (i = 0; i < nr_objects; i++) {\n+\t\tfor (i = 0; i < nr_written; i++) {\n \t\t\tstruct object_entry *entry = *list++;\n \t\t\tuint32_t crc32_val = htonl(entry->crc32);\n \t\t\tsha1write(f, &crc32_val, 4);\n@@ -819,7 +842,7 @@ static void write_index_file(off_t last_obj_offset, unsigned char *sha1)\n \n \t\t/* write the 32-bit offset table */\n \t\tlist = sorted_by_sha;\n-\t\tfor (i = 0; i < nr_objects; i++) {\n+\t\tfor (i = 0; i < nr_written; i++) {\n \t\t\tstruct object_entry *entry = *list++;\n \t\t\tuint32_t offset = (entry->offset <= index_off32_limit) ?\n \t\t\t\tentry->offset : (0x80000000 | nr_large_offset++);\n@@ -844,7 +867,6 @@ static void write_index_file(off_t last_obj_offset, unsigned char *sha1)\n \n \tsha1write(f, pack_file_sha1, 20);\n \tsha1close(f, NULL, 1);\n-\tfree(sorted_by_sha);\n \tSHA1_Final(sha1, &ctx);\n }\n \n-- \n1.5.2.rc0.787.g0014\n"}]}