From: Dana How <danahow@gmail•com>
To: Junio C Hamano <junkio@cox•net>
Cc: Git Mailing List <git@vger•kernel.org>, danahow@gmail•com
Subject: [PATCH 7/8] git-repack --max-pack-size: split packs as asked by write_object/write_one
Date: Sun, 08 Apr 2007 16:26:07 -0700 [thread overview]
Message-ID: <46197A0F.2090400@gmail.com> (raw)
Rewrite write_pack_file() to break to a new packfile
whenever write_object/write_one request it, and
correct the header's object count in the previous packfile.
Change write_index_file() to write an index
for just the objects in the most recent packfile.
Signed-off-by: Dana How <how@deathvalley•cswitch.com>
---
builtin-pack-objects.c | 126 ++++++++++++++++++++++++++++++++++--------------
1 files changed, 89 insertions(+), 37 deletions(-)
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index a088f2e..d750c4b 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -572,6 +572,7 @@ static off_t write_one(struct sha1file *f,
result = write_object(f, e, offset_limit && nr_written ? offset_limit - offset : 0);
if (!result)
return result;
+ written_list[nr_written++] = e;
e->offset = offset;
return offset + result;
}
@@ -628,52 +629,103 @@ static void write_index_file(void);
static void write_pack_file(void)
{
- uint32_t i;
+ uint32_t i, j;
struct sha1file *f;
off_t offset;
struct pack_header hdr;
unsigned last_percent = 999;
- int do_progress = progress;
+ int do_progress = progress >> !base_name;
+ char oldname[PATH_MAX];
+ int pack_fd;
+ SHA_CTX ctx;
- if (!base_name) {
- f = sha1fd(1, "<stdout>");
- do_progress >>= 1;
- }
- else
- f = sha1create("%s-%s.%s", base_name,
- sha1_to_hex(object_list_sha1), "pack");
if (do_progress)
fprintf(stderr, "Writing %u objects.\n", nr_result);
+ written_list = xmalloc(nr_objects * sizeof(struct object_entry *));
- hdr.hdr_signature = htonl(PACK_SIGNATURE);
- hdr.hdr_version = htonl(PACK_VERSION);
- hdr.hdr_entries = htonl(nr_result);
- sha1write(f, &hdr, sizeof(hdr));
- offset = sizeof(hdr);
- if (!nr_result)
- goto done;
- for (i = 0; i < nr_objects; i++) {
- offset = write_one(f, objects + i, offset);
- if (do_progress) {
- unsigned percent = written * 100 / nr_result;
- if (progress_update || percent != last_percent) {
- fprintf(stderr, "%4u%% (%u/%u) done\r",
- percent, written, nr_result);
- progress_update = 0;
- last_percent = percent;
+ for (i = 0; i < nr_objects;) {
+ if (!base_name) {
+ f = sha1fd(pack_fd = 1, "<stdout>");
+ }
+ else {
+ int len = snprintf(oldname, sizeof oldname, "%s-XXXXXX", base_name);
+ if (len >= PATH_MAX)
+ die("excessive pathname length for initial packfile name");
+ pack_fd = mkstemp(oldname);
+ if (pack_fd < 0)
+ die("can't create %s: %s", oldname, strerror(errno));
+ f = sha1fd(pack_fd, oldname);
+ }
+
+ hdr.hdr_signature = htonl(PACK_SIGNATURE);
+ hdr.hdr_version = htonl(PACK_VERSION);
+ hdr.hdr_entries = htonl(nr_result);
+ sha1write(f, &hdr, sizeof(hdr));
+ offset = sizeof(hdr);
+ nr_written = 0;
+ for (; i < nr_objects; i++) {
+ off_t offset_one = write_one(f, objects + i, offset);
+ if (!offset_one)
+ break;
+ offset = offset_one;
+ if (do_progress) {
+ unsigned percent = written * 100 / nr_result;
+ if (progress_update || percent != last_percent) {
+ fprintf(stderr, "%4u%% (%u/%u) done\r",
+ percent, written, nr_result);
+ progress_update = 0;
+ last_percent = percent;
+ }
}
}
+
+ /*
+ * Did we write the wrong # entries in the header?
+ * If so, rewrite it like in fast-import (gackk).
+ */
+ if ( !base_name || nr_written == nr_result ) {
+ sha1close(f, pack_file_sha1, 1);
+ } else {
+ sha1close(f, pack_file_sha1, -1);
+ fixup_header_footer(pack_fd, pack_file_sha1, oldname, nr_written);
+ }
+
+ /*
+ * compute object_list_sha1 of sorted sha's we just wrote out;
+ * we also mark these objects as written
+ */
+ current_sort = sha1_sort;
+ qsort(written_list, nr_written, sizeof(struct object_entry *), sort_comparator);
+ SHA1_Init(&ctx);
+ for (j = 0; j < nr_written; j++) {
+ struct object_entry *entry = written_list[j];
+ entry->prev_pack = 1;
+ SHA1_Update(&ctx, entry->sha1, 20);
+ }
+ SHA1_Final(object_list_sha1, &ctx);
+ /*
+ * now we can rename the pack correctly and write the index file
+ */
+ if (base_name) {
+ char newname[PATH_MAX];
+ int len = snprintf(newname, sizeof newname, "%s-%s.%s",
+ base_name, sha1_to_hex(object_list_sha1), "pack");
+ if (len >= PATH_MAX)
+ die("excessive pathname length for final packfile name");
+ if (rename(oldname, newname) < 0)
+ die("could not rename the pack file");
+ }
+ if (!pack_to_stdout) {
+ write_index_file();
+ puts(sha1_to_hex(object_list_sha1));
+ }
}
- if (do_progress)
+
+ free(written_list);
+ if (nr_result && do_progress)
fputc('\n', stderr);
- done:
if (written != nr_result)
die("wrote %u objects while expecting %u", written, nr_result);
- sha1close(f, pack_file_sha1, 1);
- if (!pack_to_stdout) {
- write_index_file();
- puts(sha1_to_hex(object_list_sha1));
- }
}
static void write_index_file(void)
@@ -681,8 +733,8 @@ static void write_index_file(void)
uint32_t i;
struct sha1file *f = sha1create("%s-%s.%s", base_name,
sha1_to_hex(object_list_sha1), "idx");
- struct object_entry **list = sorted_by_sha;
- struct object_entry **last = list + nr_result;
+ struct object_entry **list = written_list;
+ struct object_entry **last = list + nr_written;
uint32_t array[256];
/*
@@ -698,7 +750,7 @@ static void write_index_file(void)
break;
next++;
}
- array[i] = htonl(next - sorted_by_sha);
+ array[i] = htonl(next - written_list);
list = next;
}
sha1write(f, array, 256 * 4);
@@ -706,8 +758,8 @@ static void write_index_file(void)
/*
* Write the actual SHA1 entries..
*/
- list = sorted_by_sha;
- for (i = 0; i < nr_result; i++) {
+ list = written_list;
+ for (i = 0; i < nr_written; i++) {
struct object_entry *entry = *list++;
uint32_t offset = htonl(entry->offset);
sha1write(f, &offset, 4);
--
1.5.1.89.g8abf0
next reply other threads:[~2007-04-08 23:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-04-08 23:26 Dana How [this message]
-- strict thread matches above, loose matches on Subject: below --
2007-04-30 23:24 [PATCH 7/8] git-repack --max-pack-size: split packs as asked by write_object/write_one Dana How
2007-05-01 5:40 ` Shawn O. Pearce
2007-05-01 6:05 ` Dana How
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46197A0F.2090400@gmail.com \
--to=danahow@gmail$(echo .)com \
--cc=git@vger$(echo .)kernel.org \
--cc=junkio@cox$(echo .)net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox