summaryrefslogtreecommitdiff
path: root/src/pack-objects.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-12-04 21:22:57 -0800
committerRussell Belfer <rb@github.com>2013-12-11 10:57:49 -0800
commitdab89f9b6821b67dd07c8bd4dbb53e25a3e687c7 (patch)
treec7f4f4738dfb249b7534635226128d2e20dac6a5 /src/pack-objects.c
parent96869a4edb2872934e0e167a726ab240f4270fea (diff)
downloadlibgit2-dab89f9b6821b67dd07c8bd4dbb53e25a3e687c7.tar.gz
Further EUSER and error propagation fixes
This continues auditing all the places where GIT_EUSER is being returned and making sure to clear any existing error using the new giterr_user_cancel helper. As a result, places that relied on intercepting GIT_EUSER but having the old error preserved also needed to be cleaned up to correctly stash and then retrieve the actual error. Additionally, as I encountered places where error codes were not being propagated correctly, I tried to fix them up. A number of those fixes are included in the this commit as well.
Diffstat (limited to 'src/pack-objects.c')
-rw-r--r--src/pack-objects.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 2d62507f2..ac0615064 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -32,6 +32,7 @@ struct unpacked {
struct tree_walk_context {
git_packbuilder *pb;
git_buf buf;
+ git_error_state error;
};
struct pack_write_context {
@@ -220,12 +221,15 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
if (pb->progress_cb) {
double current_time = git__timer();
- if ((current_time - pb->last_progress_report_time) >= MIN_PROGRESS_UPDATE_INTERVAL) {
+ double elapsed = current_time - pb->last_progress_report_time;
+
+ if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
pb->last_progress_report_time = current_time;
- if (pb->progress_cb(GIT_PACKBUILDER_ADDING_OBJECTS, pb->nr_objects, 0, pb->progress_cb_payload)) {
- giterr_clear();
- return GIT_EUSER;
- }
+
+ if (pb->progress_cb(
+ GIT_PACKBUILDER_ADDING_OBJECTS,
+ pb->nr_objects, 0, pb->progress_cb_payload))
+ return giterr_user_cancel();
}
}
@@ -1284,21 +1288,22 @@ const git_oid *git_packbuilder_hash(git_packbuilder *pb)
return &pb->pack_oid;
}
-static int cb_tree_walk(const char *root, const git_tree_entry *entry, void *payload)
+static int cb_tree_walk(
+ const char *root, const git_tree_entry *entry, void *payload)
{
+ int error;
struct tree_walk_context *ctx = payload;
/* A commit inside a tree represents a submodule commit and should be skipped. */
if (git_tree_entry_type(entry) == GIT_OBJ_COMMIT)
return 0;
- if (git_buf_sets(&ctx->buf, root) < 0 ||
- git_buf_puts(&ctx->buf, git_tree_entry_name(entry)) < 0)
- return -1;
+ if (!(error = git_buf_sets(&ctx->buf, root)) &&
+ !(error = git_buf_puts(&ctx->buf, git_tree_entry_name(entry))))
+ error = git_packbuilder_insert(
+ ctx->pb, git_tree_entry_id(entry), git_buf_cstr(&ctx->buf));
- return git_packbuilder_insert(ctx->pb,
- git_tree_entry_id(entry),
- git_buf_cstr(&ctx->buf));
+ return giterr_capture(&ctx->error, error);
}
int git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *oid)
@@ -1318,22 +1323,20 @@ int git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *oid)
int git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *oid)
{
- git_tree *tree;
+ int error;
+ git_tree *tree = NULL;
struct tree_walk_context context = { pb, GIT_BUF_INIT };
- if (git_tree_lookup(&tree, pb->repo, oid) < 0 ||
- git_packbuilder_insert(pb, oid, NULL) < 0)
- return -1;
+ if (!(error = git_tree_lookup(&tree, pb->repo, oid)) &&
+ !(error = git_packbuilder_insert(pb, oid, NULL)))
+ error = git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context);
- if (git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context) < 0) {
- git_tree_free(tree);
- git_buf_free(&context.buf);
- return -1;
- }
+ if (error == GIT_EUSER)
+ error = giterr_restore(&context.error);
git_tree_free(tree);
git_buf_free(&context.buf);
- return 0;
+ return error;
}
uint32_t git_packbuilder_object_count(git_packbuilder *pb)