diff options
author | Michael Schubert <schu@schu.io> | 2013-05-11 11:36:29 +0200 |
---|---|---|
committer | Michael Schubert <schu@schu.io> | 2013-05-27 13:41:09 +0200 |
commit | 563c19a9ce556301e642a508e53598faf3c8935a (patch) | |
tree | c60937f5fb94cab89c83cd007d449b6db91a1ded | |
parent | 63908cee27e85949130f9b0a187c316f1d98b3a2 (diff) | |
download | libgit2-563c19a9ce556301e642a508e53598faf3c8935a.tar.gz |
packbuilder: also write index in git_packbuilder_write
git_packbuilder_write() used to write a packfile to the passed file
path. Instead, ask for a destination directory and create both the
packfile and an index, as most users probably do expect.
-rw-r--r-- | include/git2/pack.h | 12 | ||||
-rw-r--r-- | src/pack-objects.c | 58 |
2 files changed, 45 insertions, 25 deletions
diff --git a/include/git2/pack.h b/include/git2/pack.h index 5e431e62d..242bddd25 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -107,14 +107,20 @@ GIT_EXTERN(int) git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid * GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *id); /** - * Write the new pack and the corresponding index to path + * Write the new pack and corresponding index file to path. * * @param pb The packbuilder - * @param path Directory to store the new pack and index + * @param path to the directory where the packfile and index should be stored + * @param progress_cb function to call with progress information from the indexer (optional) + * @param progress_payload payload for the progress callback (optional) * * @return 0 or an error code */ -GIT_EXTERN(int) git_packbuilder_write(git_packbuilder *pb, const char *file); +GIT_EXTERN(int) git_packbuilder_write( + git_packbuilder *pb, + const char *path, + git_transfer_progress_callback progress_cb, + void *progress_cb_payload); typedef int (*git_packbuilder_foreach_cb)(void *buf, size_t size, void *payload); /** diff --git a/src/pack-objects.c b/src/pack-objects.c index 1329a9bc1..3d382026e 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -33,6 +33,11 @@ struct tree_walk_context { git_buf buf; }; +struct pack_write_context { + git_indexer_stream *indexer; + git_transfer_progress *stats; +}; + #ifdef GIT_THREADS #define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \ @@ -620,26 +625,6 @@ static int write_pack_buf(void *buf, size_t size, void *data) return git_buf_put(b, buf, size); } -static int write_pack_to_file(void *buf, size_t size, void *data) -{ - git_filebuf *file = (git_filebuf *)data; - return git_filebuf_write(file, buf, size); -} - -static int write_pack_file(git_packbuilder *pb, const char *path) -{ - git_filebuf file = GIT_FILEBUF_INIT; - - if (git_filebuf_open(&file, path, 0) < 0 || - write_pack(pb, &write_pack_to_file, &file) < 0 || - git_filebuf_commit(&file, GIT_PACK_FILE_MODE) < 0) { - git_filebuf_cleanup(&file); - return -1; - } - - return 0; -} - static int type_size_sort(const void *_a, const void *_b) { const git_pobject *a = (git_pobject *)_a; @@ -1259,10 +1244,39 @@ int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) return write_pack(pb, &write_pack_buf, buf); } -int git_packbuilder_write(git_packbuilder *pb, const char *path) +static int write_cb(void *buf, size_t len, void *payload) { + struct pack_write_context *ctx = payload; + return git_indexer_stream_add(ctx->indexer, buf, len, ctx->stats); +} + +int git_packbuilder_write( + git_packbuilder *pb, + const char *path, + git_transfer_progress_callback progress_cb, + void *progress_cb_payload) +{ + git_indexer_stream *indexer; + git_transfer_progress stats; + struct pack_write_context ctx; + PREPARE_PACK; - return write_pack_file(pb, path); + + if (git_indexer_stream_new( + &indexer, path, progress_cb, progress_cb_payload) < 0) + return -1; + + ctx.indexer = indexer; + ctx.stats = &stats; + + if (git_packbuilder_foreach(pb, write_cb, &ctx) < 0 || + git_indexer_stream_finalize(indexer, &stats) < 0) { + git_indexer_stream_free(indexer); + return -1; + } + + git_indexer_stream_free(indexer); + return 0; } #undef PREPARE_PACK |