These are ripoffs from pack-objects and do not do deltas at all. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- pack-write.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pack.h | 17 +++++++++++ 2 files changed, 104 insertions(+), 0 deletions(-) diff --git a/pack-write.c b/pack-write.c index cc7761e..2b71bd2 100644 --- a/pack-write.c +++ b/pack-write.c @@ -305,3 +305,90 @@ unsigned long compress_object(void **pptr, unsigned long size) return stream.total_out; } + +int create_pack(struct simple_pack *pack) +{ + char tmpname[PATH_MAX]; + struct pack_header hdr; + + if (pack->fd <= 0) { + pack->fd = odb_mkstemp(tmpname, sizeof(tmpname), "pack/tmp_pack_XXXXXX"); + pack->pack_tmp_name = xstrdup(tmpname); + } + pack->f = sha1fd(pack->fd, pack->pack_tmp_name ? pack->pack_tmp_name : "<unknown>"); + + if (pack->nr_objects) { + int pointer_size = sizeof(struct pack_idx_entry*) * pack->nr_objects; + int item_size = sizeof(struct pack_idx_entry) * pack->nr_objects; + void *buf = xmalloc(item_size + pointer_size); + pack->written_list = buf; + pack->written_items = (void*)(((char*)buf) + pointer_size); + } + + hdr.hdr_signature = htonl(PACK_SIGNATURE); + hdr.hdr_version = htonl(PACK_VERSION); + hdr.hdr_entries = htonl(pack->nr_objects); + sha1write(pack->f, &hdr, sizeof(hdr)); + if (pack->written_list) + pack->offset = sizeof(hdr); + + return 0; +} + +int write_object_to_pack(struct simple_pack *pack, + const unsigned char *sha1, + void *buf, + unsigned long size, + enum object_type type) +{ + unsigned long datalen; + unsigned hdrlen; + unsigned char header[10]; + + datalen = compress_object(&buf, size); + hdrlen = encode_in_pack_object_header(type, size, header); + if (pack->written_list) + crc32_begin(pack->f); + sha1write(pack->f, header, hdrlen); + sha1write(pack->f, buf, datalen); + free(buf); + + if (pack->written_list) { + struct pack_idx_entry *e; + + e = pack->written_list[pack->nr_written] = pack->written_items; + e->crc32 = crc32_end(pack->f); + hashcpy(e->sha1, sha1); + e->offset = pack->offset; + pack->offset += datalen+hdrlen; + } + pack->nr_written++; + pack->written_items++; + + return 0; +} + +int close_pack(struct simple_pack *pack) +{ + sha1close(pack->f, pack->sha1, CSUM_CLOSE); + if (pack->written_list) { + char tmpname[PATH_MAX]; + const char *idx_tmp_name; + + idx_tmp_name = write_idx_file(NULL, pack->written_list, pack->nr_written, pack->sha1); + + snprintf(tmpname, sizeof(tmpname), "%s/pack/pack-%s.pack", get_object_directory(), sha1_to_hex(pack->sha1)); + free_pack_by_name(tmpname); + if (adjust_shared_perm(pack->pack_tmp_name)) + die_errno("unable to make temporary pack file readable"); + if (rename(pack->pack_tmp_name, tmpname)) + die_errno("unable to rename temporary pack file"); + snprintf(tmpname, sizeof(tmpname), "%s/pack/pack-%s.idx", get_object_directory(), sha1_to_hex(pack->sha1)); + if (rename(idx_tmp_name, tmpname)) + die_errno("unable to rename temporary pack file"); + free(pack->written_list); + } + if (pack->pack_tmp_name) + free(pack->pack_tmp_name); + return 0; +} diff --git a/pack.h b/pack.h index 28a966b..a2e32c7 100644 --- a/pack.h +++ b/pack.h @@ -55,6 +55,19 @@ struct pack_idx_entry { off_t offset; }; +struct simple_pack { + uint32_t nr_objects; + unsigned char sha1[20]; + + int fd; + struct sha1file *f; + uint32_t nr_written; + off_t offset; + char *pack_tmp_name; + struct pack_idx_entry **written_list; + struct pack_idx_entry *written_items; +}; + extern const char *write_idx_file(const char *index_name, struct pack_idx_entry **objects, int nr_objects, unsigned char *sha1); extern int check_pack_crc(struct packed_git *p, struct pack_window **w_curs, off_t offset, off_t len, unsigned int nr); extern int verify_pack_index(struct packed_git *); @@ -64,6 +77,10 @@ extern char *index_pack_lockfile(int fd); extern int encode_in_pack_object_header(enum object_type, uintmax_t, unsigned char *); extern unsigned long compress_object(void **, unsigned long size); +extern int create_pack(struct simple_pack *); +extern int write_object_to_pack(struct simple_pack *, const unsigned char *, void *, unsigned long, enum object_type); +extern int close_pack(struct simple_pack *); + #define PH_ERROR_EOF (-1) #define PH_ERROR_PACK_SIGNATURE (-2) #define PH_ERROR_PROTOCOL (-3) -- 1.7.1.rc1.69.g24c2f7 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html