diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/attr.c | 7 | ||||
-rw-r--r-- | src/clone.c | 120 | ||||
-rw-r--r-- | src/fetchhead.c | 4 | ||||
-rw-r--r-- | src/ignore.c | 21 | ||||
-rw-r--r-- | src/index.c | 12 | ||||
-rw-r--r-- | src/indexer.c | 6 | ||||
-rw-r--r-- | src/merge.c | 5 | ||||
-rw-r--r-- | src/notes.c | 2 | ||||
-rw-r--r-- | src/pack-objects.c | 47 | ||||
-rw-r--r-- | src/pack.c | 6 | ||||
-rw-r--r-- | src/push.c | 2 | ||||
-rw-r--r-- | src/refs.c | 27 | ||||
-rw-r--r-- | src/remote.c | 47 | ||||
-rw-r--r-- | src/revwalk.c | 21 | ||||
-rw-r--r-- | src/stash.c | 4 | ||||
-rw-r--r-- | src/status.c | 3 | ||||
-rw-r--r-- | src/tag.c | 42 | ||||
-rw-r--r-- | src/transports/git.c | 27 | ||||
-rw-r--r-- | src/transports/smart.c | 3 | ||||
-rw-r--r-- | src/tree.c | 13 |
20 files changed, 227 insertions, 192 deletions
diff --git a/src/attr.c b/src/attr.c index 2fccf21f8..1a0f1f97f 100644 --- a/src/attr.c +++ b/src/attr.c @@ -480,6 +480,7 @@ typedef struct { const char *workdir; git_index *index; git_vector *files; + git_error_state error; } attr_walk_up_info; int git_attr_cache__decide_sources( @@ -523,7 +524,7 @@ static int push_one_attr(void *ref, git_buf *path) info->repo, path->ptr, GIT_ATTR_FILE, src[i], git_attr_file__parse_buffer, NULL, info->files); - return error; + return giterr_capture(&info->error, error); } static int collect_attr_files( @@ -535,7 +536,7 @@ static int collect_attr_files( int error; git_buf dir = GIT_BUF_INIT; const char *workdir = git_repository_workdir(repo); - attr_walk_up_info info; + attr_walk_up_info info = { NULL }; if (git_attr_cache__init(repo) < 0 || git_vector_init(files, 4, NULL) < 0) @@ -569,6 +570,8 @@ static int collect_attr_files( info.files = files; error = git_path_walk_up(&dir, workdir, push_one_attr, &info); + if (error == GIT_EUSER) + error = giterr_restore(&info.error); if (error < 0) goto cleanup; diff --git a/src/clone.c b/src/clone.c index 23aacd478..415efabba 100644 --- a/src/clone.c +++ b/src/clone.c @@ -107,6 +107,7 @@ struct head_info { git_buf branchname; const git_refspec *refspec; bool found; + git_error_state error; }; static int reference_matches_remote_head( @@ -115,43 +116,38 @@ static int reference_matches_remote_head( { struct head_info *head_info = (struct head_info *)payload; git_oid oid; + int error; /* TODO: Should we guard against references * which name doesn't start with refs/heads/ ? */ - /* Stop looking if we've already found a match */ - if (head_info->found) + error = git_reference_name_to_id(&oid, head_info->repo, reference_name); + if (error == GIT_ENOTFOUND) { + /* If the reference doesn't exists, it obviously cannot match the + * expected oid. */ + giterr_clear(); return 0; - - if (git_reference_name_to_id( - &oid, - head_info->repo, - reference_name) < 0) { - /* If the reference doesn't exists, it obviously cannot match the expected oid. */ - giterr_clear(); - return 0; } - if (git_oid__cmp(&head_info->remote_head_oid, &oid) == 0) { + if (!error && !git_oid__cmp(&head_info->remote_head_oid, &oid)) { /* Determine the local reference name from the remote tracking one */ - if (git_refspec_transform_l( - &head_info->branchname, - head_info->refspec, - reference_name) < 0) - return -1; - - if (git_buf_len(&head_info->branchname) > 0) { - if (git_buf_sets( - &head_info->branchname, - git_buf_cstr(&head_info->branchname) + strlen(GIT_REFS_HEADS_DIR)) < 0) - return -1; + error = git_refspec_transform_l( + &head_info->branchname, head_info->refspec, reference_name); - head_info->found = 1; + if (!error && + git_buf_len(&head_info->branchname) > 0 && + !(error = git_buf_sets( + &head_info->branchname, + git_buf_cstr(&head_info->branchname) + + strlen(GIT_REFS_HEADS_DIR)))) + { + head_info->found = true; + error = GIT_ITEROVER; } } - return 0; + return giterr_capture(&head_info->error, error); } static int update_head_to_new_branch( @@ -160,16 +156,11 @@ static int update_head_to_new_branch( const char *name) { git_reference *tracking_branch = NULL; - int error; - - if ((error = create_tracking_branch( - &tracking_branch, - repo, - target, - name)) < 0) - return error; + int error = create_tracking_branch(&tracking_branch, repo, target, name); - error = git_repository_set_head(repo, git_reference_name(tracking_branch)); + if (!error) + error = git_repository_set_head( + repo, git_reference_name(tracking_branch)); git_reference_free(tracking_branch); @@ -178,34 +169,30 @@ static int update_head_to_new_branch( static int update_head_to_remote(git_repository *repo, git_remote *remote) { - int retcode = -1; + int error = 0; size_t refs_len; git_refspec dummy_spec; const git_remote_head *remote_head, **refs; struct head_info head_info; git_buf remote_master_name = GIT_BUF_INIT; - if (git_remote_ls(&refs, &refs_len, remote) < 0) - return -1; + if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0) + return error; /* Did we just clone an empty repository? */ - if (refs_len == 0) { + if (refs_len == 0) return setup_tracking_config( - repo, - "master", - GIT_REMOTE_ORIGIN, - GIT_REFS_HEADS_MASTER_FILE); - } + repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE); /* Get the remote's HEAD. This is always the first ref in the list. */ remote_head = refs[0]; assert(remote_head); + memset(&head_info, 0, sizeof(head_info)); git_oid_cpy(&head_info.remote_head_oid, &remote_head->oid); - git_buf_init(&head_info.branchname, 16); head_info.repo = repo; - head_info.refspec = git_remote__matching_refspec(remote, GIT_REFS_HEADS_MASTER_FILE); - head_info.found = 0; + head_info.refspec = + git_remote__matching_refspec(remote, GIT_REFS_HEADS_MASTER_FILE); if (head_info.refspec == NULL) { memset(&dummy_spec, 0, sizeof(git_refspec)); @@ -213,50 +200,53 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote) } /* Determine the remote tracking reference name from the local master */ - if (git_refspec_transform_r( + if ((error = git_refspec_transform_r( &remote_master_name, head_info.refspec, - GIT_REFS_HEADS_MASTER_FILE) < 0) - return -1; + GIT_REFS_HEADS_MASTER_FILE)) < 0) + return error; /* Check to see if the remote HEAD points to the remote master */ - if (reference_matches_remote_head(git_buf_cstr(&remote_master_name), &head_info) < 0) - goto cleanup; + error = reference_matches_remote_head( + git_buf_cstr(&remote_master_name), &head_info); + + if (error < 0) { + error = giterr_restore(&head_info.error); + if (error < 0 && error != GIT_ITEROVER) + goto cleanup; + } if (head_info.found) { - retcode = update_head_to_new_branch( + error = update_head_to_new_branch( repo, &head_info.remote_head_oid, git_buf_cstr(&head_info.branchname)); - goto cleanup; } /* Not master. Check all the other refs. */ - if (git_reference_foreach_name( - repo, - reference_matches_remote_head, - &head_info) < 0) - goto cleanup; + error = git_reference_foreach_name( + repo, reference_matches_remote_head, &head_info); + + if (error == GIT_EUSER) + error = giterr_restore(&head_info.error); + if (error < 0 && error != GIT_ITEROVER) + goto cleanup; if (head_info.found) { - retcode = update_head_to_new_branch( + error = update_head_to_new_branch( repo, &head_info.remote_head_oid, git_buf_cstr(&head_info.branchname)); - - goto cleanup; } else { - retcode = git_repository_set_head_detached( - repo, - &head_info.remote_head_oid); - goto cleanup; + error = git_repository_set_head_detached( + repo, &head_info.remote_head_oid); } cleanup: git_buf_free(&remote_master_name); git_buf_free(&head_info.branchname); - return retcode; + return error; } static int update_head_to_branch( diff --git a/src/fetchhead.c b/src/fetchhead.c index 67089d13d..ee1492211 100644 --- a/src/fetchhead.c +++ b/src/fetchhead.c @@ -269,8 +269,8 @@ int git_repository_fetchhead_foreach(git_repository *repo, else ref_name = NULL; - if ((cb(ref_name, remote_url, &oid, is_merge, payload)) != 0) { - error = GIT_EUSER; + if (cb(ref_name, remote_url, &oid, is_merge, payload) != 0) { + error = giterr_user_cancel(); goto done; } } diff --git a/src/ignore.c b/src/ignore.c index 27d7c7ec4..aa53d409d 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -74,10 +74,20 @@ static int parse_ignore_file( #define push_ignore_file(R,IGN,S,B,F) \ git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,parse_ignore_file,(IGN),(S)) +struct ignores_walk_up_data { + git_ignores *ign; + git_error_state error; +}; + static int push_one_ignore(void *ref, git_buf *path) { - git_ignores *ign = (git_ignores *)ref; - return push_ignore_file(ign->repo, ign, &ign->ign_path, path->ptr, GIT_IGNORE_FILE); + struct ignores_walk_up_data *data = ref; + + return giterr_capture( + &data->error, + push_ignore_file( + data->ign->repo, data->ign, &data->ign->ign_path, + path->ptr, GIT_IGNORE_FILE) ); } static int get_internal_ignores(git_attr_file **ign, git_repository *repo) @@ -132,8 +142,13 @@ int git_ignore__for_path( /* load .gitignore up the path */ if (workdir != NULL) { + struct ignores_walk_up_data data = { ignores }; + error = git_path_walk_up( - &ignores->dir, workdir, push_one_ignore, ignores); + &ignores->dir, workdir, push_one_ignore, &data); + + if (error == GIT_EUSER) + error = giterr_restore(&data.error); if (error < 0) goto cleanup; } diff --git a/src/index.c b/src/index.c index 09e7b2346..d0d2cf187 100644 --- a/src/index.c +++ b/src/index.c @@ -2036,6 +2036,12 @@ int git_index_read_tree(git_index *index, const git_tree *tree) error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data); + if (error == GIT_EUSER) { + giterr_set_oom(); + git_vector_free(&entries); + return -1; + } + git_vector_sort(&entries); git_index_clear(index); @@ -2116,8 +2122,7 @@ int git_index_add_all( if (error > 0) /* return > 0 means skip this one */ continue; if (error < 0) { /* return < 0 means abort */ - giterr_clear(); - error = GIT_EUSER; + error = giterr_user_cancel(); break; } } @@ -2205,8 +2210,7 @@ static int index_apply_to_all( continue; } if (error < 0) { /* return < 0 means abort */ - giterr_clear(); - error = GIT_EUSER; + error = giterr_user_cancel(); break; } } diff --git a/src/indexer.c b/src/indexer.c index 852a04120..7312809bf 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -387,10 +387,8 @@ on_error: static int do_progress_callback(git_indexer *idx, git_transfer_progress *stats) { if (idx->progress_cb && - idx->progress_cb(stats, idx->progress_payload)) { - giterr_clear(); - return GIT_EUSER; - } + idx->progress_cb(stats, idx->progress_payload)) + return giterr_user_cancel(); return 0; } diff --git a/src/merge.c b/src/merge.c index e552b037b..0d89da5a0 100644 --- a/src/merge.c +++ b/src/merge.c @@ -254,7 +254,8 @@ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_l return 0; } -int git_repository_mergehead_foreach(git_repository *repo, +int git_repository_mergehead_foreach( + git_repository *repo, git_repository_mergehead_foreach_cb cb, void *payload) { @@ -287,7 +288,7 @@ int git_repository_mergehead_foreach(git_repository *repo, goto cleanup; if (cb(&oid, payload) != 0) { - error = GIT_EUSER; + error = giterr_user_cancel(); goto cleanup; } diff --git a/src/notes.c b/src/notes.c index d8ed32f82..7e8aecbae 100644 --- a/src/notes.c +++ b/src/notes.c @@ -584,7 +584,7 @@ int git_note_foreach( while (!(error = git_note_next(¬e_id, &annotated_id, iter))) { if (note_cb(¬e_id, &annotated_id, payload)) { - error = GIT_EUSER; + error = giterr_user_cancel(); break; } } 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) diff --git a/src/pack.c b/src/pack.c index 644b2d465..f69fe85e8 100644 --- a/src/pack.c +++ b/src/pack.c @@ -1042,10 +1042,9 @@ int git_pack_foreach_entry( { const unsigned char *index = p->index_map.data, *current; uint32_t i; + int error = 0; if (index == NULL) { - int error; - if ((error = pack_index_open(p)) < 0) return error; @@ -1062,7 +1061,6 @@ int git_pack_foreach_entry( if (p->oids == NULL) { git_vector offsets, oids; - int error; if ((error = git_vector_init(&oids, p->num_objects, NULL))) return error; @@ -1090,7 +1088,7 @@ int git_pack_foreach_entry( for (i = 0; i < p->num_objects; i++) if (cb(p->oids[i], data)) - return GIT_EUSER; + return giterr_user_cancel(); return 0; } diff --git a/src/push.c b/src/push.c index 3c9d5bb35..e592249d9 100644 --- a/src/push.c +++ b/src/push.c @@ -663,7 +663,7 @@ int git_push_status_foreach(git_push *push, git_vector_foreach(&push->status, i, status) { if (cb(status->ref, status->msg, data) < 0) - return GIT_EUSER; + return giterr_user_cancel(); } return 0; diff --git a/src/refs.c b/src/refs.c index bae62158b..60ed9ffb1 100644 --- a/src/refs.c +++ b/src/refs.c @@ -513,20 +513,19 @@ int git_reference_foreach( git_reference *ref; int error; - if (git_reference_iterator_new(&iter, repo) < 0) - return -1; + if ((error = git_reference_iterator_new(&iter, repo)) < 0) + return error; while ((error = git_reference_next(&ref, iter)) == 0) { if (callback(ref, payload)) { - error = GIT_EUSER; - goto out; + error = giterr_user_cancel(); + break; } } if (error == GIT_ITEROVER) error = 0; -out: git_reference_iterator_free(iter); return error; } @@ -540,20 +539,19 @@ int git_reference_foreach_name( const char *refname; int error; - if (git_reference_iterator_new(&iter, repo) < 0) - return -1; + if ((error = git_reference_iterator_new(&iter, repo)) < 0) + return error; while ((error = git_reference_next_name(&refname, iter)) == 0) { if (callback(refname, payload)) { - error = GIT_EUSER; - goto out; + error = giterr_user_cancel(); + break; } } if (error == GIT_ITEROVER) error = 0; -out: git_reference_iterator_free(iter); return error; } @@ -568,20 +566,19 @@ int git_reference_foreach_glob( const char *refname; int error; - if (git_reference_iterator_glob_new(&iter, repo, glob) < 0) - return -1; + if ((error = git_reference_iterator_glob_new(&iter, repo, glob)) < 0) + return error; while ((error = git_reference_next_name(&refname, iter)) == 0) { if (callback(refname, payload)) { - error = GIT_EUSER; - goto out; + error = giterr_user_cancel(); + break; } } if (error == GIT_ITEROVER) error = 0; -out: git_reference_iterator_free(iter); return error; } diff --git a/src/remote.c b/src/remote.c index e4bebe1c6..e9d079db5 100644 --- a/src/remote.c +++ b/src/remote.c @@ -1370,46 +1370,43 @@ static int rename_fetch_refspecs( if (git_buf_printf(&base, "+refs/heads/*:refs/remotes/%s/*", remote->name) < 0) goto cleanup; + if ((error = git_repository_config__weakptr(&config, remote->repo)) < 0) + goto cleanup; + git_vector_foreach(&remote->refspecs, i, spec) { if (spec->push) continue; - /* Every refspec is a problem refspec for an in-memory remote */ - if (!remote->name) { - if (callback(spec->string, payload) < 0) { - error = GIT_EUSER; - goto cleanup; - } - - continue; - } + /* Every refspec is a problem refspec for an in-memory remote, OR */ + /* Does the dst part of the refspec follow the expected format? */ + if (!remote->name || + strcmp(git_buf_cstr(&base), spec->string)) { - /* Does the dst part of the refspec follow the extected standard format? */ - if (strcmp(git_buf_cstr(&base), spec->string)) { if (callback(spec->string, payload) < 0) { - error = GIT_EUSER; + error = giterr_user_cancel(); goto cleanup; } - continue; } /* If we do want to move it to the new section */ - if (git_buf_printf(&val, "+refs/heads/*:refs/remotes/%s/*", new_name) < 0) - goto cleanup; - if (git_buf_printf(&var, "remote.%s.fetch", new_name) < 0) - goto cleanup; + git_buf_clear(&val); + git_buf_clear(&var); - if (git_repository_config__weakptr(&config, remote->repo) < 0) + if (git_buf_printf( + &val, "+refs/heads/*:refs/remotes/%s/*", new_name) < 0 || + git_buf_printf(&var, "remote.%s.fetch", new_name) < 0) + { + error = -1; goto cleanup; + } - if (git_config_set_string(config, git_buf_cstr(&var), git_buf_cstr(&val)) < 0) + if ((error = git_config_set_string( + config, git_buf_cstr(&var), git_buf_cstr(&val))) < 0) goto cleanup; } - error = 0; - cleanup: git_buf_free(&base); git_buf_free(&var); @@ -1445,11 +1442,11 @@ int git_remote_rename( new_name, callback, payload)) < 0) - return error; + return error; remote->name = git__strdup(new_name); + GITERR_CHECK_ALLOC(remote->name); - if (!remote->name) return 0; return git_remote_save(remote); } @@ -1476,11 +1473,13 @@ int git_remote_rename( new_name, callback, payload)) < 0) - return error; + return error; } git__free(remote->name); + remote->name = git__strdup(new_name); + GITERR_CHECK_ALLOC(remote->name); return 0; } diff --git a/src/revwalk.c b/src/revwalk.c index 3dd14b419..e8c7f23ec 100644 --- a/src/revwalk.c +++ b/src/revwalk.c @@ -112,12 +112,13 @@ static int process_commit_parents(git_revwalk *walk, git_commit_list_node *commi static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting) { + int error; git_object *obj; git_otype type; git_commit_list_node *commit; - if (git_object_lookup(&obj, walk->repo, oid, GIT_OBJ_ANY) < 0) - return -1; + if ((error = git_object_lookup(&obj, walk->repo, oid, GIT_OBJ_ANY)) < 0) + return error; type = git_object_type(obj); git_object_free(obj); @@ -168,13 +169,15 @@ static int push_ref(git_revwalk *walk, const char *refname, int hide) struct push_cb_data { git_revwalk *walk; int hide; + git_error_state error; }; static int push_glob_cb(const char *refname, void *data_) { struct push_cb_data *data = (struct push_cb_data *)data_; - return push_ref(data->walk, refname, data->hide); + return giterr_capture( + &data->error, push_ref(data->walk, refname, data->hide) ); } static int push_glob(git_revwalk *walk, const char *glob, int hide) @@ -191,6 +194,8 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide) git_buf_joinpath(&buf, GIT_REFS_DIR, glob); else git_buf_puts(&buf, glob); + if (git_buf_oom(&buf)) + return -1; /* If no '?', '*' or '[' exist, we append '/ *' to the glob */ wildcard = strcspn(glob, "?*["); @@ -199,12 +204,12 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide) data.walk = walk; data.hide = hide; + memset(&data.error, 0, sizeof(data.error)); - if (git_buf_oom(&buf)) - error = -1; - else - error = git_reference_foreach_glob( - walk->repo, git_buf_cstr(&buf), push_glob_cb, &data); + error = git_reference_foreach_glob( + walk->repo, git_buf_cstr(&buf), push_glob_cb, &data); + if (error == GIT_EUSER) + error = giterr_restore(&data.error); git_buf_free(&buf); return error; diff --git a/src/stash.c b/src/stash.c index 083c2a4cd..06a7b9a33 100644 --- a/src/stash.c +++ b/src/stash.c @@ -586,8 +586,8 @@ int git_stash_foreach( git_reflog_entry_message(entry), git_reflog_entry_id_new(entry), payload)) { - error = GIT_EUSER; - break; + error = giterr_user_cancel(); + break; } } diff --git a/src/status.c b/src/status.c index fb99fb4e4..777b7964a 100644 --- a/src/status.c +++ b/src/status.c @@ -414,8 +414,7 @@ int git_status_foreach_ext( status_entry->index_to_workdir->old_file.path; if (cb(path, status_entry->status, payload) != 0) { - error = GIT_EUSER; - giterr_clear(); + error = giterr_user_cancel(); break; } } @@ -414,24 +414,29 @@ typedef struct { git_repository *repo; git_tag_foreach_cb cb; void *cb_data; + git_error_state error; } tag_cb_data; static int tags_cb(const char *ref, void *data) { + int error; git_oid oid; tag_cb_data *d = (tag_cb_data *)data; if (git__prefixcmp(ref, GIT_REFS_TAGS_DIR) != 0) return 0; /* no tag */ - if (git_reference_name_to_id(&oid, d->repo, ref) < 0) - return -1; + if (!(error = git_reference_name_to_id(&oid, d->repo, ref))) { + if (d->cb(ref, &oid, d->cb_data)) + error = giterr_user_cancel(); + } - return d->cb(ref, &oid, d->cb_data); + return giterr_capture(&d->error, error); } int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) { + int error; tag_cb_data data; assert(repo && cb); @@ -439,8 +444,14 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) data.cb = cb; data.cb_data = cb_data; data.repo = repo; + memset(&data.error, 0, sizeof(data.error)); - return git_reference_foreach_name(repo, &tags_cb, &data); + error = git_reference_foreach_name(repo, &tags_cb, &data); + + if (error == GIT_EUSER) + error = giterr_restore(&data.error); + + return error; } typedef struct { @@ -455,8 +466,14 @@ static int tag_list_cb(const char *tag_name, git_oid *oid, void *data) tag_filter_data *filter = (tag_filter_data *)data; GIT_UNUSED(oid); - if (!*filter->pattern || p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0) - return git_vector_insert(filter->taglist, git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN)); + if (!*filter->pattern || + p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0) + { + char *matched = git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN); + if (!matched) + return -1; + return git_vector_insert(filter->taglist, matched); + } return 0; } @@ -469,16 +486,23 @@ int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_reposit assert(tag_names && repo && pattern); - if (git_vector_init(&taglist, 8, NULL) < 0) - return -1; + if ((error = git_vector_init(&taglist, 8, NULL)) < 0) + return error; filter.taglist = &taglist; filter.pattern = pattern; error = git_tag_foreach(repo, &tag_list_cb, (void *)&filter); + + /* the only case where callback will return an error is oom */ + if (error == GIT_EUSER) { + giterr_set_oom(); + error = -1; + } + if (error < 0) { git_vector_free(&taglist); - return -1; + return error; } tag_names->strings = (char **)taglist.contents; diff --git a/src/transports/git.c b/src/transports/git.c index 5dcd4eff7..21507c1c7 100644 --- a/src/transports/git.c +++ b/src/transports/git.c @@ -93,18 +93,19 @@ static int git_stream_read( size_t buf_size, size_t *bytes_read) { + int error; git_stream *s = (git_stream *)stream; gitno_buffer buf; *bytes_read = 0; - if (!s->sent_command && send_command(s) < 0) - return -1; + if (!s->sent_command && (error = send_command(s)) < 0) + return error; gitno_buffer_setup(&s->socket, &buf, buffer, buf_size); - if (gitno_recv(&buf) < 0) - return -1; + if ((error = gitno_recv(&buf)) < 0) + return error; *bytes_read = buf.offset; @@ -116,10 +117,11 @@ static int git_stream_write( const char *buffer, size_t len) { + int error; git_stream *s = (git_stream *)stream; - if (!s->sent_command && send_command(s) < 0) - return -1; + if (!s->sent_command && (error = send_command(s)) < 0) + return error; return gitno_send(&s->socket, buffer, len, 0); } @@ -140,7 +142,7 @@ static void git_stream_free(git_smart_subtransport_stream *stream) } git__free(s->url); - git__free(s); + git__free(s); } static int git_stream_alloc( @@ -182,18 +184,21 @@ static int _git_uploadpack_ls( char *host=NULL, *port=NULL, *path=NULL, *user=NULL, *pass=NULL; const char *stream_url = url; git_stream *s; - int error = -1; + int error; *stream = NULL; + if (!git__prefixcmp(url, prefix_git)) stream_url += strlen(prefix_git); - if (git_stream_alloc(t, stream_url, cmd_uploadpack, stream) < 0) - return -1; + if ((error = git_stream_alloc(t, stream_url, cmd_uploadpack, stream)) < 0) + return error; s = (git_stream *)*stream; - if (!(error = gitno_extract_url_parts(&host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT))) { + if (!(error = gitno_extract_url_parts( + &host, &port, &path, &user, &pass, url, GIT_DEFAULT_PORT))) { + if (!(error = gitno_connect(&s->socket, host, port, 0))) t->current_stream = s; diff --git a/src/transports/smart.c b/src/transports/smart.c index 5242beb65..e298f3510 100644 --- a/src/transports/smart.c +++ b/src/transports/smart.c @@ -27,8 +27,7 @@ static int git_smart__recv_cb(gitno_buffer *buf) if (t->packetsize_cb(bytes_read, t->packetsize_payload)) { git_atomic_set(&t->cancelled, 1); - giterr_clear(); - return GIT_EUSER; + return giterr_user_cancel(); } return (int)(buf->offset - old_len); diff --git a/src/tree.c b/src/tree.c index bb59ff82b..8ded007eb 100644 --- a/src/tree.c +++ b/src/tree.c @@ -884,14 +884,12 @@ static int tree_walk( git_vector_foreach(&tree->entries, i, entry) { if (preorder) { error = callback(path->ptr, entry, payload); + if (error < 0) + return giterr_user_cancel(); if (error > 0) { error = 0; continue; } - if (error < 0) { - giterr_clear(); - return GIT_EUSER; - } } if (git_tree_entry__is_tree(entry)) { @@ -918,11 +916,8 @@ static int tree_walk( git_buf_truncate(path, path_len); } - if (!preorder && callback(path->ptr, entry, payload) < 0) { - giterr_clear(); - error = GIT_EUSER; - break; - } + if (!preorder && callback(path->ptr, entry, payload) < 0) + return giterr_user_cancel(); } return error; |