Remove converting user error to GIT_EUSER

This changes the behavior of callbacks so that the callback error
code is not converted into GIT_EUSER and instead we propagate the
return value through to the caller.  Instead of using the
giterr_capture and giterr_restore functions, we now rely on all
functions to pass back the return value from a callback.

To avoid having a return value with no error message, the user
can call the public giterr_set_str or some such function to set
an error message.  There is a new helper 'giterr_set_callback'
that functions can invoke after making a callback which ensures
that some error message was set in case the callback did not set
one.

In places where the sign of the callback return value is
meaningful (e.g. positive to skip, negative to abort), only the
negative values are returned back to the caller, obviously, since
the other values allow for continuing the loop.

The hardest parts of this were in the checkout code where positive
return values were overloaded as meaningful values for checkout.
I fixed this by adding an output parameter to many of the internal
checkout functions and removing the overload.  This added some
code, but it is probably a better implementation.

There is some funkiness in the network code where user provided
callbacks could be returning a positive or a negative value and
we want to rely on that to cancel the loop.  There are still a
couple places where an user error might get turned into GIT_EUSER
there, I think, though none exercised by the tests.
This commit is contained in:
Russell Belfer 2013-12-06 15:07:57 -08:00
parent fcd324c625
commit 25e0b1576d
57 changed files with 604 additions and 805 deletions

View File

@ -612,8 +612,8 @@ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value);
GIT_EXTERN(int) git_config_backend_foreach_match( GIT_EXTERN(int) git_config_backend_foreach_match(
git_config_backend *backend, git_config_backend *backend,
const char *regexp, const char *regexp,
int (*fn)(const git_config_entry *, void *), git_config_foreach_cb callback,
void *data); void *payload);
/** @} */ /** @} */

View File

@ -71,6 +71,7 @@ typedef enum {
GITERR_SSH, GITERR_SSH,
GITERR_FILTER, GITERR_FILTER,
GITERR_REVERT, GITERR_REVERT,
GITERR_CALLBACK,
} git_error_t; } git_error_t;
/** /**

View File

@ -191,11 +191,10 @@ int git_attr_foreach(
if (error < 0) if (error < 0)
goto cleanup; goto cleanup;
error = callback(assign->name, assign->value, payload); error = GITERR_CALLBACK(
if (error) { callback(assign->name, assign->value, payload) );
error = giterr_user_cancel(); if (error)
goto cleanup; goto cleanup;
}
} }
} }
} }
@ -480,7 +479,6 @@ typedef struct {
const char *workdir; const char *workdir;
git_index *index; git_index *index;
git_vector *files; git_vector *files;
git_error_state error;
} attr_walk_up_info; } attr_walk_up_info;
int git_attr_cache__decide_sources( int git_attr_cache__decide_sources(
@ -524,7 +522,7 @@ static int push_one_attr(void *ref, git_buf *path)
info->repo, path->ptr, GIT_ATTR_FILE, src[i], info->repo, path->ptr, GIT_ATTR_FILE, src[i],
git_attr_file__parse_buffer, NULL, info->files); git_attr_file__parse_buffer, NULL, info->files);
return giterr_capture(&info->error, error); return error;
} }
static int collect_attr_files( static int collect_attr_files(
@ -570,8 +568,6 @@ static int collect_attr_files(
info.files = files; info.files = files;
error = git_path_walk_up(&dir, workdir, push_one_attr, &info); error = git_path_walk_up(&dir, workdir, push_one_attr, &info);
if (error == GIT_EUSER)
error = giterr_restore(&info.error);
if (error < 0) if (error < 0)
goto cleanup; goto cleanup;

View File

@ -83,10 +83,8 @@ static int checkout_notify(
const git_diff_file *baseline = NULL, *target = NULL, *workdir = NULL; const git_diff_file *baseline = NULL, *target = NULL, *workdir = NULL;
const char *path = NULL; const char *path = NULL;
if (!data->opts.notify_cb) if (!data->opts.notify_cb ||
return 0; (why & data->opts.notify_flags) == 0)
if ((why & data->opts.notify_flags) == 0)
return 0; return 0;
if (wditem) { if (wditem) {
@ -125,8 +123,10 @@ static int checkout_notify(
path = delta->old_file.path; path = delta->old_file.path;
} }
return data->opts.notify_cb( return giterr_set_callback(
why, path, baseline, target, workdir, data->opts.notify_payload); data->opts.notify_cb(
why, path, baseline, target, workdir, data->opts.notify_payload),
"git_checkout notification");
} }
static bool checkout_is_workdir_modified( static bool checkout_is_workdir_modified(
@ -186,69 +186,66 @@ static bool checkout_is_workdir_modified(
((data->strategy & GIT_CHECKOUT_##FLAG) ? CHECKOUT_ACTION__##YES : CHECKOUT_ACTION__##NO) ((data->strategy & GIT_CHECKOUT_##FLAG) ? CHECKOUT_ACTION__##YES : CHECKOUT_ACTION__##NO)
static int checkout_action_common( static int checkout_action_common(
int *action,
checkout_data *data, checkout_data *data,
int action,
const git_diff_delta *delta, const git_diff_delta *delta,
const git_index_entry *wd) const git_index_entry *wd)
{ {
git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE; git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;
if (action <= 0)
return action;
if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0) if ((data->strategy & GIT_CHECKOUT_UPDATE_ONLY) != 0)
action = (action & ~CHECKOUT_ACTION__REMOVE); *action = (*action & ~CHECKOUT_ACTION__REMOVE);
if ((action & CHECKOUT_ACTION__UPDATE_BLOB) != 0) { if ((*action & CHECKOUT_ACTION__UPDATE_BLOB) != 0) {
if (S_ISGITLINK(delta->new_file.mode)) if (S_ISGITLINK(delta->new_file.mode))
action = (action & ~CHECKOUT_ACTION__UPDATE_BLOB) | *action = (*action & ~CHECKOUT_ACTION__UPDATE_BLOB) |
CHECKOUT_ACTION__UPDATE_SUBMODULE; CHECKOUT_ACTION__UPDATE_SUBMODULE;
/* to "update" a symlink, we must remove the old one first */ /* to "update" a symlink, we must remove the old one first */
if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL) if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
action |= CHECKOUT_ACTION__REMOVE; *action |= CHECKOUT_ACTION__REMOVE;
notify = GIT_CHECKOUT_NOTIFY_UPDATED; notify = GIT_CHECKOUT_NOTIFY_UPDATED;
} }
if ((action & CHECKOUT_ACTION__CONFLICT) != 0) if ((*action & CHECKOUT_ACTION__CONFLICT) != 0)
notify = GIT_CHECKOUT_NOTIFY_CONFLICT; notify = GIT_CHECKOUT_NOTIFY_CONFLICT;
if (notify != GIT_CHECKOUT_NOTIFY_NONE && return checkout_notify(data, notify, delta, wd);
checkout_notify(data, notify, delta, wd) != 0)
return giterr_user_cancel();
return action;
} }
static int checkout_action_no_wd( static int checkout_action_no_wd(
int *action,
checkout_data *data, checkout_data *data,
const git_diff_delta *delta) const git_diff_delta *delta)
{ {
int action = CHECKOUT_ACTION__NONE; int error = 0;
*action = CHECKOUT_ACTION__NONE;
switch (delta->status) { switch (delta->status) {
case GIT_DELTA_UNMODIFIED: /* case 12 */ case GIT_DELTA_UNMODIFIED: /* case 12 */
if (checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL)) error = checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL);
return giterr_user_cancel(); if (error)
action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, NONE); return error;
*action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, NONE);
break; break;
case GIT_DELTA_ADDED: /* case 2 or 28 (and 5 but not really) */ case GIT_DELTA_ADDED: /* case 2 or 28 (and 5 but not really) */
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
break; break;
case GIT_DELTA_MODIFIED: /* case 13 (and 35 but not really) */ case GIT_DELTA_MODIFIED: /* case 13 (and 35 but not really) */
action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, CONFLICT); *action = CHECKOUT_ACTION_IF(SAFE_CREATE, UPDATE_BLOB, CONFLICT);
break; break;
case GIT_DELTA_TYPECHANGE: /* case 21 (B->T) and 28 (T->B)*/ case GIT_DELTA_TYPECHANGE: /* case 21 (B->T) and 28 (T->B)*/
if (delta->new_file.mode == GIT_FILEMODE_TREE) if (delta->new_file.mode == GIT_FILEMODE_TREE)
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
break; break;
case GIT_DELTA_DELETED: /* case 8 or 25 */ case GIT_DELTA_DELETED: /* case 8 or 25 */
default: /* impossible */ default: /* impossible */
break; break;
} }
return checkout_action_common(data, action, delta, NULL); return checkout_action_common(action, data, delta, NULL);
} }
static int checkout_action_wd_only( static int checkout_action_wd_only(
@ -257,6 +254,7 @@ static int checkout_action_wd_only(
const git_index_entry *wd, const git_index_entry *wd,
git_vector *pathspec) git_vector *pathspec)
{ {
int error = 0;
bool remove = false; bool remove = false;
git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE; git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE;
@ -269,13 +267,13 @@ static int checkout_action_wd_only(
/* check if item is tracked in the index but not in the checkout diff */ /* check if item is tracked in the index but not in the checkout diff */
if (data->index != NULL) { if (data->index != NULL) {
if (wd->mode != GIT_FILEMODE_TREE) { if (wd->mode != GIT_FILEMODE_TREE) {
int error; if (!(error = git_index_find(NULL, data->index, wd->path))) {
if ((error = git_index_find(NULL, data->index, wd->path)) == 0) {
notify = GIT_CHECKOUT_NOTIFY_DIRTY; notify = GIT_CHECKOUT_NOTIFY_DIRTY;
remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0); remove = ((data->strategy & GIT_CHECKOUT_FORCE) != 0);
} else if (error != GIT_ENOTFOUND) } else if (error != GIT_ENOTFOUND)
return error; return error;
else
giterr_clear();
} else { } else {
/* for tree entries, we have to see if there are any index /* for tree entries, we have to see if there are any index
* entries that are contained inside that tree * entries that are contained inside that tree
@ -301,18 +299,16 @@ static int checkout_action_wd_only(
remove = ((data->strategy & GIT_CHECKOUT_REMOVE_UNTRACKED) != 0); remove = ((data->strategy & GIT_CHECKOUT_REMOVE_UNTRACKED) != 0);
} }
if (checkout_notify(data, notify, NULL, wd)) error = checkout_notify(data, notify, NULL, wd);
return giterr_user_cancel();
if (remove) { if (!error && remove) {
char *path = git_pool_strdup(&data->pool, wd->path); char *path = git_pool_strdup(&data->pool, wd->path);
GITERR_CHECK_ALLOC(path); GITERR_CHECK_ALLOC(path);
if (git_vector_insert(&data->removes, path) < 0) error = git_vector_insert(&data->removes, path);
return -1;
} }
return 0; return error;
} }
static bool submodule_is_config_only( static bool submodule_is_config_only(
@ -331,35 +327,35 @@ static bool submodule_is_config_only(
} }
static int checkout_action_with_wd( static int checkout_action_with_wd(
int *action,
checkout_data *data, checkout_data *data,
const git_diff_delta *delta, const git_diff_delta *delta,
const git_index_entry *wd) const git_index_entry *wd)
{ {
int action = CHECKOUT_ACTION__NONE; *action = CHECKOUT_ACTION__NONE;
switch (delta->status) { switch (delta->status) {
case GIT_DELTA_UNMODIFIED: /* case 14/15 or 33 */ case GIT_DELTA_UNMODIFIED: /* case 14/15 or 33 */
if (checkout_is_workdir_modified(data, &delta->old_file, wd)) { if (checkout_is_workdir_modified(data, &delta->old_file, wd)) {
if (checkout_notify( GITERR_CHECK_ERROR(
data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd)) checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
return giterr_user_cancel(); *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, NONE);
action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, NONE);
} }
break; break;
case GIT_DELTA_ADDED: /* case 3, 4 or 6 */ case GIT_DELTA_ADDED: /* case 3, 4 or 6 */
action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
break; break;
case GIT_DELTA_DELETED: /* case 9 or 10 (or 26 but not really) */ case GIT_DELTA_DELETED: /* case 9 or 10 (or 26 but not really) */
if (checkout_is_workdir_modified(data, &delta->old_file, wd)) if (checkout_is_workdir_modified(data, &delta->old_file, wd))
action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
else else
action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE); *action = CHECKOUT_ACTION_IF(SAFE, REMOVE, NONE);
break; break;
case GIT_DELTA_MODIFIED: /* case 16, 17, 18 (or 36 but not really) */ case GIT_DELTA_MODIFIED: /* case 16, 17, 18 (or 36 but not really) */
if (checkout_is_workdir_modified(data, &delta->old_file, wd)) if (checkout_is_workdir_modified(data, &delta->old_file, wd))
action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, UPDATE_BLOB, CONFLICT);
else else
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
break; break;
case GIT_DELTA_TYPECHANGE: /* case 22, 23, 29, 30 */ case GIT_DELTA_TYPECHANGE: /* case 22, 23, 29, 30 */
if (delta->old_file.mode == GIT_FILEMODE_TREE) { if (delta->old_file.mode == GIT_FILEMODE_TREE) {
@ -367,92 +363,93 @@ static int checkout_action_with_wd(
/* either deleting items in old tree will delete the wd dir, /* either deleting items in old tree will delete the wd dir,
* or we'll get a conflict when we attempt blob update... * or we'll get a conflict when we attempt blob update...
*/ */
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
else if (wd->mode == GIT_FILEMODE_COMMIT) { else if (wd->mode == GIT_FILEMODE_COMMIT) {
/* workdir is possibly a "phantom" submodule - treat as a /* workdir is possibly a "phantom" submodule - treat as a
* tree if the only submodule info came from the config * tree if the only submodule info came from the config
*/ */
if (submodule_is_config_only(data, wd->path)) if (submodule_is_config_only(data, wd->path))
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
else else
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
} else } else
action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
} }
else if (checkout_is_workdir_modified(data, &delta->old_file, wd)) else if (checkout_is_workdir_modified(data, &delta->old_file, wd))
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
else else
action = CHECKOUT_ACTION_IF(SAFE, REMOVE_AND_UPDATE, NONE); *action = CHECKOUT_ACTION_IF(SAFE, REMOVE_AND_UPDATE, NONE);
/* don't update if the typechange is to a tree */ /* don't update if the typechange is to a tree */
if (delta->new_file.mode == GIT_FILEMODE_TREE) if (delta->new_file.mode == GIT_FILEMODE_TREE)
action = (action & ~CHECKOUT_ACTION__UPDATE_BLOB); *action = (*action & ~CHECKOUT_ACTION__UPDATE_BLOB);
break; break;
default: /* impossible */ default: /* impossible */
break; break;
} }
return checkout_action_common(data, action, delta, wd); return checkout_action_common(action, data, delta, wd);
} }
static int checkout_action_with_wd_blocker( static int checkout_action_with_wd_blocker(
int *action,
checkout_data *data, checkout_data *data,
const git_diff_delta *delta, const git_diff_delta *delta,
const git_index_entry *wd) const git_index_entry *wd)
{ {
int action = CHECKOUT_ACTION__NONE; *action = CHECKOUT_ACTION__NONE;
switch (delta->status) { switch (delta->status) {
case GIT_DELTA_UNMODIFIED: case GIT_DELTA_UNMODIFIED:
/* should show delta as dirty / deleted */ /* should show delta as dirty / deleted */
if (checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd)) GITERR_CHECK_ERROR(
return giterr_user_cancel(); checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, wd) );
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, NONE);
break; break;
case GIT_DELTA_ADDED: case GIT_DELTA_ADDED:
case GIT_DELTA_MODIFIED: case GIT_DELTA_MODIFIED:
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
break; break;
case GIT_DELTA_DELETED: case GIT_DELTA_DELETED:
action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE, CONFLICT);
break; break;
case GIT_DELTA_TYPECHANGE: case GIT_DELTA_TYPECHANGE:
/* not 100% certain about this... */ /* not 100% certain about this... */
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
break; break;
default: /* impossible */ default: /* impossible */
break; break;
} }
return checkout_action_common(data, action, delta, wd); return checkout_action_common(action, data, delta, wd);
} }
static int checkout_action_with_wd_dir( static int checkout_action_with_wd_dir(
int *action,
checkout_data *data, checkout_data *data,
const git_diff_delta *delta, const git_diff_delta *delta,
const git_index_entry *wd) const git_index_entry *wd)
{ {
int action = CHECKOUT_ACTION__NONE; *action = CHECKOUT_ACTION__NONE;
switch (delta->status) { switch (delta->status) {
case GIT_DELTA_UNMODIFIED: /* case 19 or 24 (or 34 but not really) */ case GIT_DELTA_UNMODIFIED: /* case 19 or 24 (or 34 but not really) */
if (checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL) || GITERR_CHECK_ERROR(
checkout_notify( checkout_notify(data, GIT_CHECKOUT_NOTIFY_DIRTY, delta, NULL));
data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd)) GITERR_CHECK_ERROR(
return giterr_user_cancel(); checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd));
break; break;
case GIT_DELTA_ADDED:/* case 4 (and 7 for dir) */ case GIT_DELTA_ADDED:/* case 4 (and 7 for dir) */
case GIT_DELTA_MODIFIED: /* case 20 (or 37 but not really) */ case GIT_DELTA_MODIFIED: /* case 20 (or 37 but not really) */
if (delta->old_file.mode == GIT_FILEMODE_COMMIT) if (delta->old_file.mode == GIT_FILEMODE_COMMIT)
/* expected submodule (and maybe found one) */; /* expected submodule (and maybe found one) */;
else if (delta->new_file.mode != GIT_FILEMODE_TREE) else if (delta->new_file.mode != GIT_FILEMODE_TREE)
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
break; break;
case GIT_DELTA_DELETED: /* case 11 (and 27 for dir) */ case GIT_DELTA_DELETED: /* case 11 (and 27 for dir) */
if (delta->old_file.mode != GIT_FILEMODE_TREE && if (delta->old_file.mode != GIT_FILEMODE_TREE)
checkout_notify( GITERR_CHECK_ERROR(
data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd)) checkout_notify(data, GIT_CHECKOUT_NOTIFY_UNTRACKED, NULL, wd));
return giterr_user_cancel();
break; break;
case GIT_DELTA_TYPECHANGE: /* case 24 or 31 */ case GIT_DELTA_TYPECHANGE: /* case 24 or 31 */
if (delta->old_file.mode == GIT_FILEMODE_TREE) { if (delta->old_file.mode == GIT_FILEMODE_TREE) {
@ -462,39 +459,41 @@ static int checkout_action_with_wd_dir(
* directory if is it left empty, so we can defer removing the * directory if is it left empty, so we can defer removing the
* dir and it will succeed if no children are left. * dir and it will succeed if no children are left.
*/ */
action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE); *action = CHECKOUT_ACTION_IF(SAFE, UPDATE_BLOB, NONE);
if (action != CHECKOUT_ACTION__NONE) if (*action != CHECKOUT_ACTION__NONE)
action |= CHECKOUT_ACTION__DEFER_REMOVE; *action |= CHECKOUT_ACTION__DEFER_REMOVE;
} }
else if (delta->new_file.mode != GIT_FILEMODE_TREE) else if (delta->new_file.mode != GIT_FILEMODE_TREE)
/* For typechange to dir, dir is already created so no action */ /* For typechange to dir, dir is already created so no action */
action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT); *action = CHECKOUT_ACTION_IF(FORCE, REMOVE_AND_UPDATE, CONFLICT);
break; break;
default: /* impossible */ default: /* impossible */
break; break;
} }
return checkout_action_common(data, action, delta, wd); return checkout_action_common(action, data, delta, wd);
} }
static int checkout_action( static int checkout_action(
int *action,
checkout_data *data, checkout_data *data,
git_diff_delta *delta, git_diff_delta *delta,
git_iterator *workdir, git_iterator *workdir,
const git_index_entry **wditem_ptr, const git_index_entry **wditem,
git_vector *pathspec) git_vector *pathspec)
{ {
const git_index_entry *wd = *wditem_ptr; int cmp = -1, error;
int cmp = -1, act;
int (*strcomp)(const char *, const char *) = data->diff->strcomp; int (*strcomp)(const char *, const char *) = data->diff->strcomp;
int (*pfxcomp)(const char *str, const char *pfx) = data->diff->pfxcomp; int (*pfxcomp)(const char *str, const char *pfx) = data->diff->pfxcomp;
int error; int (*advance)(const git_index_entry **, git_iterator *) = NULL;
/* move workdir iterator to follow along with deltas */ /* move workdir iterator to follow along with deltas */
while (1) { while (1) {
const git_index_entry *wd = *wditem;
if (!wd) if (!wd)
return checkout_action_no_wd(data, delta); return checkout_action_no_wd(action, data, delta);
cmp = strcomp(wd->path, delta->old_file.path); cmp = strcomp(wd->path, delta->old_file.path);
@ -512,79 +511,77 @@ static int checkout_action(
if (cmp == 0) { if (cmp == 0) {
if (wd->mode == GIT_FILEMODE_TREE) { if (wd->mode == GIT_FILEMODE_TREE) {
/* case 2 - entry prefixed by workdir tree */ /* case 2 - entry prefixed by workdir tree */
error = git_iterator_advance_into_or_over(&wd, workdir); error = git_iterator_advance_into_or_over(wditem, workdir);
if (error && error != GIT_ITEROVER) if (error < 0 && error != GIT_ITEROVER)
goto fail; goto done;
*wditem_ptr = wd;
continue; continue;
} }
/* case 3 maybe - wd contains non-dir where dir expected */ /* case 3 maybe - wd contains non-dir where dir expected */
if (delta->old_file.path[strlen(wd->path)] == '/') { if (delta->old_file.path[strlen(wd->path)] == '/') {
act = checkout_action_with_wd_blocker(data, delta, wd); error = checkout_action_with_wd_blocker(
*wditem_ptr = action, data, delta, wd);
git_iterator_advance(&wd, workdir) ? NULL : wd; advance = git_iterator_advance;
return act; goto done;
} }
} }
/* case 1 - handle wd item (if it matches pathspec) */ /* case 1 - handle wd item (if it matches pathspec) */
if (checkout_action_wd_only(data, workdir, wd, pathspec) < 0) error = checkout_action_wd_only(data, workdir, wd, pathspec);
goto fail; if (error)
if ((error = git_iterator_advance(&wd, workdir)) < 0 && goto done;
if ((error = git_iterator_advance(wditem, workdir)) < 0 &&
error != GIT_ITEROVER) error != GIT_ITEROVER)
goto fail; goto done;
*wditem_ptr = wd;
continue; continue;
} }
if (cmp == 0) { if (cmp == 0) {
/* case 4 */ /* case 4 */
act = checkout_action_with_wd(data, delta, wd); error = checkout_action_with_wd(action, data, delta, wd);
*wditem_ptr = git_iterator_advance(&wd, workdir) ? NULL : wd; advance = git_iterator_advance;
return act; goto done;
} }
cmp = pfxcomp(wd->path, delta->old_file.path); cmp = pfxcomp(wd->path, delta->old_file.path);
if (cmp == 0) { /* case 5 */ if (cmp == 0) { /* case 5 */
if (wd->path[strlen(delta->old_file.path)] != '/') if (wd->path[strlen(delta->old_file.path)] != '/')
return checkout_action_no_wd(data, delta); return checkout_action_no_wd(action, data, delta);
if (delta->status == GIT_DELTA_TYPECHANGE) { if (delta->status == GIT_DELTA_TYPECHANGE) {
if (delta->old_file.mode == GIT_FILEMODE_TREE) { if (delta->old_file.mode == GIT_FILEMODE_TREE) {
act = checkout_action_with_wd(data, delta, wd); error = checkout_action_with_wd(action, data, delta, wd);
if ((error = git_iterator_advance_into(&wd, workdir)) < 0 && advance = git_iterator_advance_into;
error != GIT_ENOTFOUND) goto done;
goto fail;
*wditem_ptr = wd;
return act;
} }
if (delta->new_file.mode == GIT_FILEMODE_TREE || if (delta->new_file.mode == GIT_FILEMODE_TREE ||
delta->new_file.mode == GIT_FILEMODE_COMMIT || delta->new_file.mode == GIT_FILEMODE_COMMIT ||
delta->old_file.mode == GIT_FILEMODE_COMMIT) delta->old_file.mode == GIT_FILEMODE_COMMIT)
{ {
act = checkout_action_with_wd(data, delta, wd); error = checkout_action_with_wd(action, data, delta, wd);
if ((error = git_iterator_advance(&wd, workdir)) < 0 && advance = git_iterator_advance;
error != GIT_ITEROVER) goto done;
goto fail;
*wditem_ptr = wd;
return act;
} }
} }
return checkout_action_with_wd_dir(data, delta, wd); return checkout_action_with_wd_dir(action, data, delta, wd);
} }
/* case 6 - wd is after delta */ /* case 6 - wd is after delta */
return checkout_action_no_wd(data, delta); return checkout_action_no_wd(action, data, delta);
} }
fail: done:
*wditem_ptr = NULL; if (!error && advance != NULL &&
return -1; (error = advance(wditem, workdir)) < 0) {
*wditem = NULL;
if (error == GIT_ITEROVER)
error = 0;
}
return error;
} }
static int checkout_remaining_wd_items( static int checkout_remaining_wd_items(
@ -965,7 +962,7 @@ static int checkout_get_actions(
checkout_data *data, checkout_data *data,
git_iterator *workdir) git_iterator *workdir)
{ {
int error = 0; int error = 0, act;
const git_index_entry *wditem; const git_index_entry *wditem;
git_vector pathspec = GIT_VECTOR_INIT, *deltas; git_vector pathspec = GIT_VECTOR_INIT, *deltas;
git_pool pathpool = GIT_POOL_INIT_STRINGPOOL; git_pool pathpool = GIT_POOL_INIT_STRINGPOOL;
@ -992,12 +989,9 @@ static int checkout_get_actions(
} }
git_vector_foreach(deltas, i, delta) { git_vector_foreach(deltas, i, delta) {
int act = checkout_action(data, delta, workdir, &wditem, &pathspec); error = checkout_action(&act, data, delta, workdir, &wditem, &pathspec);
if (error)
if (act < 0) {
error = act;
goto fail; goto fail;
}
actions[i] = act; actions[i] = act;
@ -1012,7 +1006,7 @@ static int checkout_get_actions(
} }
error = checkout_remaining_wd_items(data, workdir, wditem, &pathspec); error = checkout_remaining_wd_items(data, workdir, wditem, &pathspec);
if (error < 0) if (error)
goto fail; goto fail;
counts[CHECKOUT_ACTION__REMOVE] += data->removes.length; counts[CHECKOUT_ACTION__REMOVE] += data->removes.length;

View File

@ -107,7 +107,6 @@ struct head_info {
git_buf branchname; git_buf branchname;
const git_refspec *refspec; const git_refspec *refspec;
bool found; bool found;
git_error_state error;
}; };
static int reference_matches_remote_head( static int reference_matches_remote_head(
@ -147,7 +146,7 @@ static int reference_matches_remote_head(
} }
} }
return giterr_capture(&head_info->error, error); return error;
} }
static int update_head_to_new_branch( static int update_head_to_new_branch(
@ -209,12 +208,8 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote)
/* Check to see if the remote HEAD points to the remote master */ /* Check to see if the remote HEAD points to the remote master */
error = reference_matches_remote_head( error = reference_matches_remote_head(
git_buf_cstr(&remote_master_name), &head_info); git_buf_cstr(&remote_master_name), &head_info);
if (error < 0 && error != GIT_ITEROVER)
if (error < 0) { goto cleanup;
error = giterr_restore(&head_info.error);
if (error < 0 && error != GIT_ITEROVER)
goto cleanup;
}
if (head_info.found) { if (head_info.found) {
error = update_head_to_new_branch( error = update_head_to_new_branch(
@ -227,9 +222,6 @@ static int update_head_to_remote(git_repository *repo, git_remote *remote)
/* Not master. Check all the other refs. */ /* Not master. Check all the other refs. */
error = git_reference_foreach_name( error = git_reference_foreach_name(
repo, reference_matches_remote_head, &head_info); repo, reference_matches_remote_head, &head_info);
if (error == GIT_EUSER)
error = giterr_restore(&head_info.error);
if (error < 0 && error != GIT_ITEROVER) if (error < 0 && error != GIT_ITEROVER)
goto cleanup; goto cleanup;
@ -349,7 +341,7 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_
old_fetchhead = git_remote_update_fetchhead(remote); old_fetchhead = git_remote_update_fetchhead(remote);
git_remote_set_update_fetchhead(remote, 0); git_remote_set_update_fetchhead(remote, 0);
if ((error = git_remote_fetch(remote)) < 0) if ((error = git_remote_fetch(remote)) != 0)
goto cleanup; goto cleanup;
if (branch) if (branch)
@ -363,10 +355,12 @@ int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_
cleanup: cleanup:
git_remote_set_update_fetchhead(remote, old_fetchhead); git_remote_set_update_fetchhead(remote, old_fetchhead);
/* Go back to the original refspecs */ /* Go back to the original refspecs */
if (git_remote_set_fetch_refspecs(remote, &refspecs) < 0) { {
git_strarray_free(&refspecs); int error_alt = git_remote_set_fetch_refspecs(remote, &refspecs);
return -1; if (!error)
error = error_alt;
} }
git_strarray_free(&refspecs); git_strarray_free(&refspecs);

View File

@ -62,7 +62,7 @@
* Check a return value and propogate result if non-zero. * Check a return value and propogate result if non-zero.
*/ */
#define GITERR_CHECK_ERROR(code) \ #define GITERR_CHECK_ERROR(code) \
do { int _err = (code); if (_err < 0) return _err; } while (0) do { int _err = (code); if (_err) return _err; } while (0)
/** /**
* Set the error message for this thread, formatting as needed. * Set the error message for this thread, formatting as needed.
@ -75,6 +75,27 @@ void giterr_set(int error_class, const char *string, ...);
*/ */
int giterr_set_regex(const regex_t *regex, int error_code); int giterr_set_regex(const regex_t *regex, int error_code);
/**
* Set error message for user callback if needed.
*
* If the error code in non-zero and no error message is set, this
* sets a generic error message.
*
* @return This always returns the `error_code` parameter.
*/
GIT_INLINE(int) giterr_set_callback(int error_code, const char *action)
{
if (error_code) {
const git_error *e = giterr_last();
if (!e || !e->message)
giterr_set(e ? e->klass : GITERR_CALLBACK,
"%s callback returned %d", action, error_code);
}
return error_code;
}
#define GITERR_CALLBACK(code) giterr_set_callback((code), __func__)
/** /**
* Gets the system error code for this thread. * Gets the system error code for this thread.
*/ */
@ -85,15 +106,6 @@ int giterr_system_last(void);
*/ */
void giterr_system_set(int code); void giterr_system_set(int code);
/**
* Note that a user cancelled an operation with GIT_EUSER
*/
GIT_INLINE(int) giterr_user_cancel(void)
{
giterr_clear();
return GIT_EUSER;
}
/** /**
* Structure to preserve libgit2 error state * Structure to preserve libgit2 error state
*/ */

View File

@ -480,23 +480,23 @@ int git_config_foreach(
int git_config_backend_foreach_match( int git_config_backend_foreach_match(
git_config_backend *backend, git_config_backend *backend,
const char *regexp, const char *regexp,
int (*fn)(const git_config_entry *, void *), git_config_foreach_cb cb,
void *data) void *payload)
{ {
git_config_entry *entry; git_config_entry *entry;
git_config_iterator* iter; git_config_iterator* iter;
regex_t regex; regex_t regex;
int result = 0; int error = 0;
if (regexp != NULL) { if (regexp != NULL) {
if ((result = regcomp(&regex, regexp, REG_EXTENDED)) < 0) { if ((error = regcomp(&regex, regexp, REG_EXTENDED)) < 0) {
giterr_set_regex(&regex, result); giterr_set_regex(&regex, error);
regfree(&regex); regfree(&regex);
return -1; return -1;
} }
} }
if ((result = backend->iterator(&iter, backend)) < 0) { if ((error = backend->iterator(&iter, backend)) < 0) {
iter = NULL; iter = NULL;
return -1; return -1;
} }
@ -507,10 +507,9 @@ int git_config_backend_foreach_match(
continue; continue;
/* abort iterator on non-zero return value */ /* abort iterator on non-zero return value */
if (fn(entry, data)) { error = GITERR_CALLBACK( cb(entry, payload) );
result = giterr_user_cancel(); if (error)
break; break;
}
} }
if (regexp != NULL) if (regexp != NULL)
@ -518,7 +517,7 @@ int git_config_backend_foreach_match(
iter->free(iter); iter->free(iter);
return result; return error;
} }
int git_config_foreach_match( int git_config_foreach_match(
@ -534,12 +533,9 @@ int git_config_foreach_match(
if ((error = git_config_iterator_glob_new(&iter, cfg, regexp)) < 0) if ((error = git_config_iterator_glob_new(&iter, cfg, regexp)) < 0)
return error; return error;
while ((error = git_config_next(&entry, iter)) == 0) { while (!(error = git_config_next(&entry, iter)) &&
if (cb(entry, payload)) { !(error = GITERR_CALLBACK( cb(entry, payload) )))
error = giterr_user_cancel(); /* make callback on each config */;
break;
}
}
git_config_iterator_free(iter); git_config_iterator_free(iter);
@ -798,10 +794,8 @@ int git_config_get_multivar_foreach(
while ((err = iter->next(&entry, iter)) == 0) { while ((err = iter->next(&entry, iter)) == 0) {
found = 1; found = 1;
if (cb(entry, payload)) { if ((err = GITERR_CALLBACK( cb(entry, payload) )) != 0)
iter->free(iter); break;
return giterr_user_cancel();
}
} }
iter->free(iter); iter->free(iter);
@ -1212,7 +1206,6 @@ struct rename_data {
git_config *config; git_config *config;
git_buf *name; git_buf *name;
size_t old_len; size_t old_len;
git_error_state error;
}; };
static int rename_config_entries_cb( static int rename_config_entries_cb(
@ -1235,8 +1228,7 @@ static int rename_config_entries_cb(
if (!error) if (!error)
error = git_config_delete_entry(data->config, entry->name); error = git_config_delete_entry(data->config, entry->name);
/* capture error message as needed, since it will become EUSER */ return error;
return giterr_capture(&data->error, error);
} }
int git_config_rename_section( int git_config_rename_section(
@ -1257,7 +1249,6 @@ int git_config_rename_section(
if ((error = git_repository_config__weakptr(&config, repo)) < 0) if ((error = git_repository_config__weakptr(&config, repo)) < 0)
goto cleanup; goto cleanup;
memset(&data, 0, sizeof(data));
data.config = config; data.config = config;
data.name = &replace; data.name = &replace;
data.old_len = strlen(old_section_name) + 1; data.old_len = strlen(old_section_name) + 1;
@ -1277,9 +1268,6 @@ int git_config_rename_section(
error = git_config_foreach_match( error = git_config_foreach_match(
config, git_buf_cstr(&pattern), rename_config_entries_cb, &data); config, git_buf_cstr(&pattern), rename_config_entries_cb, &data);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
cleanup: cleanup:
git_buf_free(&pattern); git_buf_free(&pattern);
git_buf_free(&replace); git_buf_free(&replace);

View File

@ -49,16 +49,25 @@ static git_diff_delta *diff_delta__alloc(
return delta; return delta;
} }
static int diff_notify( static int diff_insert_delta(
const git_diff *diff, git_diff *diff, git_diff_delta *delta, const char *matched_pathspec)
const git_diff_delta *delta,
const char *matched_pathspec)
{ {
if (!diff->opts.notify_cb) int error = 0;
return 0;
return diff->opts.notify_cb( if (diff->opts.notify_cb) {
diff, delta, matched_pathspec, diff->opts.notify_payload); error = diff->opts.notify_cb(
diff, delta, matched_pathspec, diff->opts.notify_payload);
if (error) {
git__free(delta);
return (error > 0) ? 0 : giterr_set_callback(error, "git_diff");
}
}
if ((error = git_vector_insert(&diff->deltas, delta)) < 0)
git__free(delta);
return error;
} }
static int diff_delta__from_one( static int diff_delta__from_one(
@ -68,7 +77,6 @@ static int diff_delta__from_one(
{ {
git_diff_delta *delta; git_diff_delta *delta;
const char *matched_pathspec; const char *matched_pathspec;
int notify_res;
if ((entry->flags & GIT_IDXENTRY_VALID) != 0) if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
return 0; return 0;
@ -111,21 +119,12 @@ static int diff_delta__from_one(
!git_oid_iszero(&delta->new_file.oid)) !git_oid_iszero(&delta->new_file.oid))
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_OID; delta->new_file.flags |= GIT_DIFF_FLAG_VALID_OID;
notify_res = diff_notify(diff, delta, matched_pathspec); return diff_insert_delta(diff, delta, matched_pathspec);
if (notify_res)
git__free(delta);
else if (git_vector_insert(&diff->deltas, delta) < 0) {
git__free(delta);
return -1;
}
return notify_res < 0 ? giterr_user_cancel() : 0;
} }
static int diff_delta__from_two( static int diff_delta__from_two(
git_diff *diff, git_diff *diff,
git_delta_t status, git_delta_t status,
const git_index_entry *old_entry, const git_index_entry *old_entry,
uint32_t old_mode, uint32_t old_mode,
const git_index_entry *new_entry, const git_index_entry *new_entry,
@ -134,7 +133,6 @@ static int diff_delta__from_two(
const char *matched_pathspec) const char *matched_pathspec)
{ {
git_diff_delta *delta; git_diff_delta *delta;
int notify_res;
const char *canonical_path = old_entry->path; const char *canonical_path = old_entry->path;
if (status == GIT_DELTA_UNMODIFIED && if (status == GIT_DELTA_UNMODIFIED &&
@ -173,16 +171,7 @@ static int diff_delta__from_two(
if (new_oid || !git_oid_iszero(&new_entry->oid)) if (new_oid || !git_oid_iszero(&new_entry->oid))
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_OID; delta->new_file.flags |= GIT_DIFF_FLAG_VALID_OID;
notify_res = diff_notify(diff, delta, matched_pathspec); return diff_insert_delta(diff, delta, matched_pathspec);
if (notify_res)
git__free(delta);
else if (git_vector_insert(&diff->deltas, delta) < 0) {
git__free(delta);
return -1;
}
return notify_res < 0 ? giterr_user_cancel() : 0;
} }
static git_diff_delta *diff_delta__last_for_item( static git_diff_delta *diff_delta__last_for_item(
@ -654,6 +643,7 @@ static int maybe_modified(
unsigned int nmode = nitem->mode; unsigned int nmode = nitem->mode;
bool new_is_workdir = (info->new_iter->type == GIT_ITERATOR_TYPE_WORKDIR); bool new_is_workdir = (info->new_iter->type == GIT_ITERATOR_TYPE_WORKDIR);
const char *matched_pathspec; const char *matched_pathspec;
int error = 0;
if (!git_pathspec__match( if (!git_pathspec__match(
&diff->pathspec, oitem->path, &diff->pathspec, oitem->path,
@ -688,10 +678,9 @@ static int maybe_modified(
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE)) if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE))
status = GIT_DELTA_TYPECHANGE; status = GIT_DELTA_TYPECHANGE;
else { else {
if (diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem) < 0 || if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem) < 0) error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
return -1; return error;
return 0;
} }
} }
@ -713,8 +702,8 @@ static int maybe_modified(
/* TODO: add check against index file st_mtime to avoid racy-git */ /* TODO: add check against index file st_mtime to avoid racy-git */
if (S_ISGITLINK(nmode)) { if (S_ISGITLINK(nmode)) {
if (maybe_modified_submodule(&status, &noid, diff, info) < 0) if ((error = maybe_modified_submodule(&status, &noid, diff, info)) < 0)
return -1; return error;
} }
/* if the stat data looks different, then mark modified - this just /* if the stat data looks different, then mark modified - this just
@ -741,9 +730,9 @@ static int maybe_modified(
*/ */
if (status == GIT_DELTA_MODIFIED && git_oid_iszero(&nitem->oid)) { if (status == GIT_DELTA_MODIFIED && git_oid_iszero(&nitem->oid)) {
if (git_oid_iszero(&noid)) { if (git_oid_iszero(&noid)) {
if (git_diff__oid_for_file(diff->repo, if ((error = git_diff__oid_for_file(diff->repo,
nitem->path, nitem->mode, nitem->file_size, &noid) < 0) nitem->path, nitem->mode, nitem->file_size, &noid)) < 0)
return -1; return error;
} }
/* if oid matches, then mark unmodified (except submodules, where /* if oid matches, then mark unmodified (except submodules, where
@ -898,7 +887,7 @@ static int handle_unmatched_new_item(
git_diff_delta *last; git_diff_delta *last;
/* attempt to insert record for this directory */ /* attempt to insert record for this directory */
if ((error = diff_delta__from_one(diff, delta_type, nitem)) < 0) if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
return error; return error;
/* if delta wasn't created (because of rules), just skip ahead */ /* if delta wasn't created (because of rules), just skip ahead */
@ -977,7 +966,7 @@ static int handle_unmatched_new_item(
} }
/* Actually create the record for this item if necessary */ /* Actually create the record for this item if necessary */
if ((error = diff_delta__from_one(diff, delta_type, nitem)) < 0) if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
return error; return error;
/* If user requested TYPECHANGE records, then check for that instead of /* If user requested TYPECHANGE records, then check for that instead of
@ -1002,7 +991,7 @@ static int handle_unmatched_old_item(
git_diff *diff, diff_in_progress *info) git_diff *diff, diff_in_progress *info)
{ {
int error = diff_delta__from_one(diff, GIT_DELTA_DELETED, info->oitem); int error = diff_delta__from_one(diff, GIT_DELTA_DELETED, info->oitem);
if (error < 0) if (error != 0)
return error; return error;
/* if we are generating TYPECHANGE records then check for that /* if we are generating TYPECHANGE records then check for that
@ -1399,10 +1388,8 @@ int git_diff__paired_foreach(
i++; j++; i++; j++;
} }
if (cb(h2i, i2w, payload)) { if ((error = GITERR_CALLBACK( cb(h2i, i2w, payload) )) != 0)
error = giterr_user_cancel();
break; break;
}
} }
/* restore case-insensitive delta sort */ /* restore case-insensitive delta sort */

View File

@ -32,7 +32,6 @@ struct git_patch {
git_array_t(git_diff_line) lines; git_array_t(git_diff_line) lines;
size_t content_size, context_size, header_size; size_t content_size, context_size, header_size;
git_pool flattened; git_pool flattened;
git_error_state error;
}; };
enum { enum {
@ -200,11 +199,12 @@ static int diff_patch_invoke_file_callback(
float progress = patch->diff ? float progress = patch->diff ?
((float)patch->delta_index / patch->diff->deltas.length) : 1.0f; ((float)patch->delta_index / patch->diff->deltas.length) : 1.0f;
if (output->file_cb && if (!output->file_cb)
output->file_cb(patch->delta, progress, output->payload) != 0) return 0;
return giterr_user_cancel();
return 0; return giterr_set_callback(
output->file_cb(patch->delta, progress, output->payload),
"git_patch");
} }
static int diff_patch_generate(git_patch *patch, git_diff_output *output) static int diff_patch_generate(git_patch *patch, git_diff_output *output)
@ -291,7 +291,7 @@ int git_diff_foreach(
git_patch_free(&patch); git_patch_free(&patch);
if (error < 0) if (error)
break; break;
} }
@ -331,9 +331,6 @@ static int diff_single_generate(diff_patch_with_delta *pd, git_xdiff_output *xo)
if (!error) if (!error)
error = diff_patch_generate(patch, (git_diff_output *)xo); error = diff_patch_generate(patch, (git_diff_output *)xo);
if (error == GIT_EUSER)
giterr_clear(); /* don't leave error message set invalidly */
return error; return error;
} }
@ -462,9 +459,6 @@ int git_patch_from_blobs(
error = diff_patch_from_blobs( error = diff_patch_from_blobs(
pd, &xo, old_blob, old_path, new_blob, new_path, opts); pd, &xo, old_blob, old_path, new_blob, new_path, opts);
if (error == GIT_EUSER)
error = giterr_restore(&pd->patch.error);
if (!error) if (!error)
*out = (git_patch *)pd; *out = (git_patch *)pd;
else else
@ -576,9 +570,6 @@ int git_patch_from_blob_and_buffer(
error = diff_patch_from_blob_and_buffer( error = diff_patch_from_blob_and_buffer(
pd, &xo, old_blob, old_path, buf, buflen, buf_path, opts); pd, &xo, old_blob, old_path, buf, buflen, buf_path, opts);
if (error == GIT_EUSER)
error = giterr_restore(&pd->patch.error);
if (!error) if (!error)
*out = (git_patch *)pd; *out = (git_patch *)pd;
else else
@ -627,12 +618,9 @@ int git_patch_from_diff(
if (!error) if (!error)
error = diff_patch_generate(patch, &xo.output); error = diff_patch_generate(patch, &xo.output);
if (error == GIT_EUSER)
error = giterr_restore(&patch->error);
if (!error) { if (!error) {
/* if cumulative diff size is < 0.5 total size, flatten the patch */ /* TODO: if cumulative diff size is < 0.5 total size, flatten patch */
/* unload the file content */ /* TODO: and unload the file content */
} }
if (error || !patch_ptr) if (error || !patch_ptr)
@ -640,8 +628,6 @@ int git_patch_from_diff(
else else
*patch_ptr = patch; *patch_ptr = patch;
if (error == GIT_EUSER)
giterr_clear(); /* don't leave error message set invalidly */
return error; return error;
} }
@ -879,8 +865,7 @@ static int diff_patch_hunk_cb(
GIT_UNUSED(delta); GIT_UNUSED(delta);
hunk = git_array_alloc(patch->hunks); hunk = git_array_alloc(patch->hunks);
if (!hunk) GITERR_CHECK_ALLOC(hunk);
return giterr_capture(&patch->error, -1);
memcpy(&hunk->hunk, hunk_, sizeof(hunk->hunk)); memcpy(&hunk->hunk, hunk_, sizeof(hunk->hunk));
@ -909,8 +894,7 @@ static int diff_patch_line_cb(
assert(hunk); /* programmer error if no hunk is available */ assert(hunk); /* programmer error if no hunk is available */
line = git_array_alloc(patch->lines); line = git_array_alloc(patch->lines);
if (!line) GITERR_CHECK_ALLOC(line);
return giterr_capture(&patch->error, -1);
memcpy(line, line_, sizeof(*line)); memcpy(line, line_, sizeof(*line));

View File

@ -18,7 +18,6 @@ typedef struct {
uint32_t flags; uint32_t flags;
int oid_strlen; int oid_strlen;
git_diff_line line; git_diff_line line;
git_error_state error;
} diff_print_info; } diff_print_info;
static int diff_print_info_init( static int diff_print_info_init(
@ -34,7 +33,6 @@ static int diff_print_info_init(
pi->print_cb = cb; pi->print_cb = cb;
pi->payload = payload; pi->payload = payload;
pi->buf = out; pi->buf = out;
memset(&pi->error, 0, sizeof(pi->error));
if (diff) if (diff)
pi->flags = diff->opts.flags; pi->flags = diff->opts.flags;
@ -104,19 +102,16 @@ static int diff_print_one_name_only(
return 0; return 0;
git_buf_clear(out); git_buf_clear(out);
git_buf_puts(out, delta->new_file.path);
if (git_buf_puts(out, delta->new_file.path) < 0 || git_buf_putc(out, '\n');
git_buf_putc(out, '\n')) if (git_buf_oom(out))
return giterr_capture(&pi->error, -1); return -1;
pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
pi->line.content = git_buf_cstr(out); pi->line.content = git_buf_cstr(out);
pi->line.content_len = git_buf_len(out); pi->line.content_len = git_buf_len(out);
if (pi->print_cb(delta, NULL, &pi->line, pi->payload)) return pi->print_cb(delta, NULL, &pi->line, pi->payload);
return giterr_user_cancel();
return 0;
} }
static int diff_print_one_name_status( static int diff_print_one_name_status(
@ -150,18 +145,14 @@ static int diff_print_one_name_status(
git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix); git_buf_printf(out, "%c\t%s%c\n", code, delta->old_file.path, old_suffix);
else else
git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path); git_buf_printf(out, "%c\t%s\n", code, delta->old_file.path);
if (git_buf_oom(out)) if (git_buf_oom(out))
return giterr_capture(&pi->error, -1); return -1;
pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
pi->line.content = git_buf_cstr(out); pi->line.content = git_buf_cstr(out);
pi->line.content_len = git_buf_len(out); pi->line.content_len = git_buf_len(out);
if (pi->print_cb(delta, NULL, &pi->line, pi->payload)) return pi->print_cb(delta, NULL, &pi->line, pi->payload);
return giterr_user_cancel();
return 0;
} }
static int diff_print_one_raw( static int diff_print_one_raw(
@ -198,16 +189,13 @@ static int diff_print_one_raw(
delta->old_file.path : delta->new_file.path); delta->old_file.path : delta->new_file.path);
if (git_buf_oom(out)) if (git_buf_oom(out))
return giterr_capture(&pi->error, -1); return -1;
pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
pi->line.content = git_buf_cstr(out); pi->line.content = git_buf_cstr(out);
pi->line.content_len = git_buf_len(out); pi->line.content_len = git_buf_len(out);
if (pi->print_cb(delta, NULL, &pi->line, pi->payload)) return pi->print_cb(delta, NULL, &pi->line, pi->payload);
return giterr_user_cancel();
return 0;
} }
static int diff_print_oid_range( static int diff_print_oid_range(
@ -234,10 +222,7 @@ static int diff_print_oid_range(
git_buf_printf(out, "index %s..%s\n", start_oid, end_oid); git_buf_printf(out, "index %s..%s\n", start_oid, end_oid);
} }
if (git_buf_oom(out)) return git_buf_oom(out) ? -1 : 0;
return -1;
return 0;
} }
static int diff_delta_format_with_paths( static int diff_delta_format_with_paths(
@ -281,8 +266,7 @@ int git_diff_delta__format_file_header(
git_buf_printf(out, "diff --git %s%s %s%s\n", git_buf_printf(out, "diff --git %s%s %s%s\n",
oldpfx, delta->old_file.path, newpfx, delta->new_file.path); oldpfx, delta->old_file.path, newpfx, delta->new_file.path);
if (diff_print_oid_range(out, delta, oid_strlen) < 0) GITERR_CHECK_ERROR(diff_print_oid_range(out, delta, oid_strlen));
return -1;
if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0) if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
diff_delta_format_with_paths( diff_delta_format_with_paths(
@ -294,6 +278,7 @@ int git_diff_delta__format_file_header(
static int diff_print_patch_file( static int diff_print_patch_file(
const git_diff_delta *delta, float progress, void *data) const git_diff_delta *delta, float progress, void *data)
{ {
int error;
diff_print_info *pi = data; diff_print_info *pi = data;
const char *oldpfx = const char *oldpfx =
pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT; pi->diff ? pi->diff->opts.old_prefix : DIFF_OLD_PREFIX_DEFAULT;
@ -309,36 +294,33 @@ static int diff_print_patch_file(
(pi->flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) == 0)) (pi->flags & GIT_DIFF_SHOW_UNTRACKED_CONTENT) == 0))
return 0; return 0;
if (git_diff_delta__format_file_header( if ((error = git_diff_delta__format_file_header(
pi->buf, delta, oldpfx, newpfx, pi->oid_strlen) < 0) pi->buf, delta, oldpfx, newpfx, pi->oid_strlen)) < 0)
return giterr_capture(&pi->error, -1); return error;
pi->line.origin = GIT_DIFF_LINE_FILE_HDR; pi->line.origin = GIT_DIFF_LINE_FILE_HDR;
pi->line.content = git_buf_cstr(pi->buf); pi->line.content = git_buf_cstr(pi->buf);
pi->line.content_len = git_buf_len(pi->buf); pi->line.content_len = git_buf_len(pi->buf);
if (pi->print_cb(delta, NULL, &pi->line, pi->payload)) if ((error = pi->print_cb(delta, NULL, &pi->line, pi->payload)) != 0)
return giterr_user_cancel(); return error;
if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0) if ((delta->flags & GIT_DIFF_FLAG_BINARY) == 0)
return 0; return 0;
git_buf_clear(pi->buf); git_buf_clear(pi->buf);
if (diff_delta_format_with_paths( if ((error = diff_delta_format_with_paths(
pi->buf, delta, oldpfx, newpfx, pi->buf, delta, oldpfx, newpfx,
"Binary files %s%s and %s%s differ\n") < 0) "Binary files %s%s and %s%s differ\n")) < 0)
return giterr_capture(&pi->error, -1); return error;
pi->line.origin = GIT_DIFF_LINE_BINARY; pi->line.origin = GIT_DIFF_LINE_BINARY;
pi->line.content = git_buf_cstr(pi->buf); pi->line.content = git_buf_cstr(pi->buf);
pi->line.content_len = git_buf_len(pi->buf); pi->line.content_len = git_buf_len(pi->buf);
pi->line.num_lines = 1; pi->line.num_lines = 1;
if (pi->print_cb(delta, NULL, &pi->line, pi->payload)) return pi->print_cb(delta, NULL, &pi->line, pi->payload);
return giterr_user_cancel();
return 0;
} }
static int diff_print_patch_hunk( static int diff_print_patch_hunk(
@ -355,10 +337,7 @@ static int diff_print_patch_hunk(
pi->line.content = h->header; pi->line.content = h->header;
pi->line.content_len = h->header_len; pi->line.content_len = h->header_len;
if (pi->print_cb(d, h, &pi->line, pi->payload)) return pi->print_cb(d, h, &pi->line, pi->payload);
return giterr_user_cancel();
return 0;
} }
static int diff_print_patch_line( static int diff_print_patch_line(
@ -372,10 +351,7 @@ static int diff_print_patch_line(
if (S_ISDIR(delta->new_file.mode)) if (S_ISDIR(delta->new_file.mode))
return 0; return 0;
if (pi->print_cb(delta, hunk, line, pi->payload)) return pi->print_cb(delta, hunk, line, pi->payload);
return giterr_user_cancel();
return 0;
} }
/* print a git_diff to an output callback */ /* print a git_diff to an output callback */
@ -421,8 +397,8 @@ int git_diff_print(
error = git_diff_foreach( error = git_diff_foreach(
diff, print_file, print_hunk, print_line, &pi); diff, print_file, print_hunk, print_line, &pi);
if (error == GIT_EUSER && pi.error.error_code) if (error) /* make sure error message is set */
error = giterr_restore(&pi.error); giterr_set_callback(error, "git_diff_print");
} }
git_buf_free(&buf); git_buf_free(&buf);
@ -450,8 +426,8 @@ int git_patch_print(
patch, diff_print_patch_file, diff_print_patch_hunk, patch, diff_print_patch_file, diff_print_patch_hunk,
diff_print_patch_line, &pi); diff_print_patch_line, &pi);
if (error && error != GIT_EUSER) if (error) /* make sure error message is set */
error = giterr_restore(&pi.error); giterr_set_callback(error, "git_patch_print");
} }
git_buf_free(&temp); git_buf_free(&temp);
@ -484,17 +460,12 @@ int git_patch_to_str(
int error; int error;
git_buf output = GIT_BUF_INIT; git_buf output = GIT_BUF_INIT;
error = git_patch_print(patch, diff_print_to_buffer_cb, &output); if (!(error = git_patch_print(patch, diff_print_to_buffer_cb, &output)))
*string = git_buf_detach(&output);
/* GIT_EUSER means git_buf_put in print_to_buffer_cb returned -1, else {
* meaning a memory allocation failure, so just map to -1... git_buf_free(&output);
*/ *string = NULL;
if (error == GIT_EUSER) {
giterr_set_oom();
error = -1;
} }
*string = git_buf_detach(&output);
return error; return error;
} }

View File

@ -126,8 +126,9 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
info->hunk.header[info->hunk.header_len] = '\0'; info->hunk.header[info->hunk.header_len] = '\0';
if (output->hunk_cb != NULL && if (output->hunk_cb != NULL &&
output->hunk_cb(delta, &info->hunk, output->payload)) (output->error = output->hunk_cb(
return (output->error = giterr_user_cancel()); delta, &info->hunk, output->payload)))
return output->error;
info->old_lineno = info->hunk.old_start; info->old_lineno = info->hunk.old_start;
info->new_lineno = info->hunk.new_start; info->new_lineno = info->hunk.new_start;
@ -150,10 +151,9 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
output->error = diff_update_lines( output->error = diff_update_lines(
info, &line, bufs[1].ptr, bufs[1].size); info, &line, bufs[1].ptr, bufs[1].size);
if (!output->error && if (!output->error && output->data_cb != NULL)
output->data_cb != NULL && output->error = output->data_cb(
output->data_cb(delta, &info->hunk, &line, output->payload)) delta, &info->hunk, &line, output->payload);
output->error = giterr_user_cancel();
} }
if (len == 3 && !output->error) { if (len == 3 && !output->error) {
@ -172,10 +172,9 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
output->error = diff_update_lines( output->error = diff_update_lines(
info, &line, bufs[2].ptr, bufs[2].size); info, &line, bufs[2].ptr, bufs[2].size);
if (!output->error && if (!output->error && output->data_cb != NULL)
output->data_cb != NULL && output->error = output->data_cb(
output->data_cb(delta, &info->hunk, &line, output->payload)) delta, &info->hunk, &line, output->payload);
output->error = giterr_user_cancel();
} }
return output->error; return output->error;

View File

@ -128,9 +128,9 @@ int git_fetch_download_pack(git_remote *remote)
{ {
git_transport *t = remote->transport; git_transport *t = remote->transport;
if(!remote->need_pack) if (!remote->need_pack)
return 0; return 0;
return t->download_pack(t, remote->repo, &remote->stats, return t->download_pack(t, remote->repo, &remote->stats,
remote->callbacks.transfer_progress, remote->callbacks.payload); remote->callbacks.transfer_progress, remote->callbacks.payload);
} }

View File

@ -269,10 +269,10 @@ int git_repository_fetchhead_foreach(git_repository *repo,
else else
ref_name = NULL; ref_name = NULL;
if (cb(ref_name, remote_url, &oid, is_merge, payload) != 0) { error = GITERR_CALLBACK(
error = giterr_user_cancel(); cb(ref_name, remote_url, &oid, is_merge, payload) );
if (error)
goto done; goto done;
}
} }
if (*buffer) { if (*buffer) {

View File

@ -404,7 +404,6 @@ typedef struct {
size_t baselen; size_t baselen;
uint32_t flags; uint32_t flags;
int depth; int depth;
git_error_state error;
} futils__rmdir_data; } futils__rmdir_data;
#define FUTILS_MAX_DEPTH 100 #define FUTILS_MAX_DEPTH 100
@ -474,16 +473,14 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
data->depth++; data->depth++;
error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data); error = git_path_direach(path, 0, futils__rmdir_recurs_foreach, data);
if (error == GIT_EUSER)
return error;
data->depth--; data->depth--;
if (error < 0) if (error < 0)
goto done; return error;
if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0) if (data->depth == 0 && (data->flags & GIT_RMDIR_SKIP_ROOT) != 0)
goto done; return error;
if ((error = p_rmdir(path->ptr)) < 0) { if ((error = p_rmdir(path->ptr)) < 0) {
if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 && if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) != 0 &&
@ -502,8 +499,7 @@ static int futils__rmdir_recurs_foreach(void *opaque, git_buf *path)
else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0) else if ((data->flags & GIT_RMDIR_SKIP_NONEMPTY) == 0)
error = futils__error_cannot_rmdir(path->ptr, "still present"); error = futils__error_cannot_rmdir(path->ptr, "still present");
done: return error;
return giterr_capture(&data->error, error);
} }
static int futils__rmdir_empty_parent(void *opaque, git_buf *path) static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
@ -512,9 +508,9 @@ static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
int error = 0; int error = 0;
if (git_buf_len(path) <= data->baselen) if (git_buf_len(path) <= data->baselen)
return giterr_capture(&data->error, GIT_ITEROVER); error = GIT_ITEROVER;
if (p_rmdir(git_buf_cstr(path)) < 0) { else if (p_rmdir(git_buf_cstr(path)) < 0) {
int en = errno; int en = errno;
if (en == ENOENT || en == ENOTDIR) { if (en == ENOENT || en == ENOTDIR) {
@ -526,7 +522,7 @@ static int futils__rmdir_empty_parent(void *opaque, git_buf *path)
} }
} }
return giterr_capture(&data->error, error); return error;
} }
int git_futils_rmdir_r( int git_futils_rmdir_r(
@ -552,10 +548,10 @@ int git_futils_rmdir_r(
error = git_path_walk_up( error = git_path_walk_up(
&fullpath, base, futils__rmdir_empty_parent, &data); &fullpath, base, futils__rmdir_empty_parent, &data);
if (error == GIT_EUSER) if (error == GIT_ITEROVER) {
error = giterr_restore(&data.error); giterr_clear();
if (error == GIT_ITEROVER)
error = 0; error = 0;
}
git_buf_free(&fullpath); git_buf_free(&fullpath);
@ -859,7 +855,6 @@ typedef struct {
uint32_t flags; uint32_t flags;
uint32_t mkdir_flags; uint32_t mkdir_flags;
mode_t dirmode; mode_t dirmode;
git_error_state error;
} cp_r_info; } cp_r_info;
#define GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT (1u << 10) #define GIT_CPDIR__MKDIR_DONE_FOR_TO_ROOT (1u << 10)
@ -899,19 +894,19 @@ static int _cp_r_callback(void *ref, git_buf *from)
if ((error = git_buf_joinpath( if ((error = git_buf_joinpath(
&info->to, info->to_root, from->ptr + info->from_prefix)) < 0) &info->to, info->to_root, from->ptr + info->from_prefix)) < 0)
goto done; return error;
if (!(error = git_path_lstat(info->to.ptr, &to_st))) if (!(error = git_path_lstat(info->to.ptr, &to_st)))
exists = true; exists = true;
else if (error != GIT_ENOTFOUND) else if (error != GIT_ENOTFOUND)
goto done; return error;
else { else {
giterr_clear(); giterr_clear();
error = 0; error = 0;
} }
if ((error = git_path_lstat(from->ptr, &from_st)) < 0) if ((error = git_path_lstat(from->ptr, &from_st)) < 0)
goto done; return error;
if (S_ISDIR(from_st.st_mode)) { if (S_ISDIR(from_st.st_mode)) {
mode_t oldmode = info->dirmode; mode_t oldmode = info->dirmode;
@ -925,16 +920,13 @@ static int _cp_r_callback(void *ref, git_buf *from)
error = _cp_r_mkdir(info, from); error = _cp_r_mkdir(info, from);
/* recurse onto target directory */ /* recurse onto target directory */
if (!error && (!exists || S_ISDIR(to_st.st_mode))) { if (!error && (!exists || S_ISDIR(to_st.st_mode)))
error = git_path_direach(from, 0, _cp_r_callback, info); error = git_path_direach(from, 0, _cp_r_callback, info);
if (error == GIT_EUSER)
return error;
}
if (oldmode != 0) if (oldmode != 0)
info->dirmode = oldmode; info->dirmode = oldmode;
goto done; return error;
} }
if (exists) { if (exists) {
@ -944,8 +936,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
if (p_unlink(info->to.ptr) < 0) { if (p_unlink(info->to.ptr) < 0) {
giterr_set(GITERR_OS, "Cannot overwrite existing file '%s'", giterr_set(GITERR_OS, "Cannot overwrite existing file '%s'",
info->to.ptr); info->to.ptr);
error = -1; return GIT_EEXISTS;
goto done;
} }
} }
@ -958,7 +949,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
/* Make container directory on demand if needed */ /* Make container directory on demand if needed */
if ((info->flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0 && if ((info->flags & GIT_CPDIR_CREATE_EMPTY_DIRS) == 0 &&
(error = _cp_r_mkdir(info, from)) < 0) (error = _cp_r_mkdir(info, from)) < 0)
goto done; return error;
/* make symlink or regular file */ /* make symlink or regular file */
if (S_ISLNK(from_st.st_mode)) if (S_ISLNK(from_st.st_mode))
@ -972,8 +963,7 @@ static int _cp_r_callback(void *ref, git_buf *from)
error = git_futils_cp(from->ptr, info->to.ptr, usemode); error = git_futils_cp(from->ptr, info->to.ptr, usemode);
} }
done: return error;
return giterr_capture(&info->error, error);
} }
int git_futils_cp_r( int git_futils_cp_r(
@ -1015,9 +1005,6 @@ int git_futils_cp_r(
git_buf_free(&path); git_buf_free(&path);
git_buf_free(&info.to); git_buf_free(&info.to);
if (error == GIT_EUSER)
error = giterr_restore(&info.error);
return error; return error;
} }

View File

@ -74,20 +74,12 @@ static int parse_ignore_file(
#define push_ignore_file(R,IGN,S,B,F) \ #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)) git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,parse_ignore_file,(IGN),(S))
struct ignores_walk_up_data { static int push_one_ignore(void *payload, git_buf *path)
git_ignores *ign;
git_error_state error;
};
static int push_one_ignore(void *ref, git_buf *path)
{ {
struct ignores_walk_up_data *data = ref; git_ignores *ign = payload;
return giterr_capture( return push_ignore_file(
&data->error, ign->repo, ign, &ign->ign_path, path->ptr, GIT_IGNORE_FILE);
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) static int get_internal_ignores(git_attr_file **ign, git_repository *repo)
@ -142,13 +134,8 @@ int git_ignore__for_path(
/* load .gitignore up the path */ /* load .gitignore up the path */
if (workdir != NULL) { if (workdir != NULL) {
struct ignores_walk_up_data data = { ignores };
error = git_path_walk_up( error = git_path_walk_up(
&ignores->dir, workdir, push_one_ignore, &data); &ignores->dir, workdir, push_one_ignore, ignores);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
if (error < 0) if (error < 0)
goto cleanup; goto cleanup;
} }

View File

@ -2036,17 +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); error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data);
if (error == GIT_EUSER) { if (!error) {
giterr_set_oom(); git_vector_sort(&entries);
git_vector_free(&entries); git_index_clear(index);
return -1; git_vector_swap(&entries, &index->entries);
} }
git_vector_sort(&entries);
git_index_clear(index);
git_vector_swap(&entries, &index->entries);
git_vector_free(&entries); git_vector_free(&entries);
return error; return error;
@ -2122,7 +2117,7 @@ int git_index_add_all(
if (error > 0) /* return > 0 means skip this one */ if (error > 0) /* return > 0 means skip this one */
continue; continue;
if (error < 0) { /* return < 0 means abort */ if (error < 0) { /* return < 0 means abort */
error = giterr_user_cancel(); GITERR_CALLBACK(error);
break; break;
} }
} }
@ -2210,7 +2205,7 @@ static int index_apply_to_all(
continue; continue;
} }
if (error < 0) { /* return < 0 means abort */ if (error < 0) { /* return < 0 means abort */
error = giterr_user_cancel(); giterr_set_callback(error, "git_index_matched_path");
break; break;
} }
} }

View File

@ -386,10 +386,10 @@ on_error:
static int do_progress_callback(git_indexer *idx, git_transfer_progress *stats) static int do_progress_callback(git_indexer *idx, git_transfer_progress *stats)
{ {
if (idx->progress_cb && if (idx->progress_cb)
idx->progress_cb(stats, idx->progress_payload)) return giterr_set_callback(
return giterr_user_cancel(); idx->progress_cb(stats, idx->progress_payload),
"indexer progress");
return 0; return 0;
} }
@ -495,7 +495,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
processed = stats->indexed_objects = 0; processed = stats->indexed_objects = 0;
stats->total_objects = total_objects; stats->total_objects = total_objects;
if ((error = do_progress_callback(idx, stats)) < 0) if ((error = do_progress_callback(idx, stats)) != 0)
return error; return error;
} }
@ -520,7 +520,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
return 0; return 0;
} }
if (error < 0) if (error < 0)
return -1; return error;
git_mwindow_close(&w); git_mwindow_close(&w);
idx->entry_start = entry_start; idx->entry_start = entry_start;
@ -533,7 +533,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
return 0; return 0;
} }
if (error < 0) if (error < 0)
return -1; return error;
idx->have_delta = 1; idx->have_delta = 1;
} else { } else {
@ -578,7 +578,7 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
} }
stats->received_objects++; stats->received_objects++;
if ((error = do_progress_callback(idx, stats)) < 0) if ((error = do_progress_callback(idx, stats)) != 0)
goto on_error; goto on_error;
} }

View File

@ -287,10 +287,8 @@ int git_repository_mergehead_foreach(
if ((error = git_oid_fromstr(&oid, line)) < 0) if ((error = git_oid_fromstr(&oid, line)) < 0)
goto cleanup; goto cleanup;
if (cb(&oid, payload) != 0) { if ((error = GITERR_CALLBACK( cb(&oid, payload) )) != 0)
error = giterr_user_cancel();
goto cleanup; goto cleanup;
}
++line_num; ++line_num;
} }

View File

@ -582,12 +582,10 @@ int git_note_foreach(
if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0) if ((error = git_note_iterator_new(&iter, repo, notes_ref)) < 0)
return error; return error;
while (!(error = git_note_next(&note_id, &annotated_id, iter))) { while (!(error = git_note_next(&note_id, &annotated_id, iter)) &&
if (note_cb(&note_id, &annotated_id, payload)) { !(error = GITERR_CALLBACK(
error = giterr_user_cancel(); note_cb(&note_id, &annotated_id, payload))))
break; /* callback for each note */;
}
}
if (error == GIT_ITEROVER) if (error == GIT_ITEROVER)
error = 0; error = 0;

View File

@ -547,8 +547,7 @@ static int locate_object_short_oid(
/* Explore directory to find a unique object matching short_oid */ /* Explore directory to find a unique object matching short_oid */
error = git_path_direach( error = git_path_direach(
object_location, 0, fn_locate_object_short_oid, &state); object_location, 0, fn_locate_object_short_oid, &state);
if (error < 0 && error != GIT_EAMBIGUOUS)
if (error && error != GIT_EUSER)
return error; return error;
if (!state.found) if (!state.found)
@ -696,7 +695,6 @@ struct foreach_state {
size_t dir_len; size_t dir_len;
git_odb_foreach_cb cb; git_odb_foreach_cb cb;
void *data; void *data;
git_error_state cb_error;
}; };
GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr) GIT_INLINE(int) filename_to_oid(git_oid *oid, const char *ptr)
@ -735,19 +733,15 @@ static int foreach_object_dir_cb(void *_state, git_buf *path)
if (filename_to_oid(&oid, path->ptr + state->dir_len) < 0) if (filename_to_oid(&oid, path->ptr + state->dir_len) < 0)
return 0; return 0;
if (state->cb(&oid, state->data)) return giterr_set_callback(
return giterr_user_cancel(); state->cb(&oid, state->data), "git_odb_foreach");
return 0;
} }
static int foreach_cb(void *_state, git_buf *path) static int foreach_cb(void *_state, git_buf *path)
{ {
struct foreach_state *state = (struct foreach_state *) _state; struct foreach_state *state = (struct foreach_state *) _state;
return giterr_capture( return git_path_direach(path, 0, foreach_object_dir_cb, state);
&state->cb_error,
git_path_direach(path, 0, foreach_object_dir_cb, state));
} }
static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data) static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb cb, void *data)
@ -762,9 +756,10 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb
objects_dir = backend->objects_dir; objects_dir = backend->objects_dir;
if (git_buf_sets(&buf, objects_dir) < 0) git_buf_sets(&buf, objects_dir);
return -1;
git_path_to_dir(&buf); git_path_to_dir(&buf);
if (git_buf_oom(&buf))
return -1;
memset(&state, 0, sizeof(state)); memset(&state, 0, sizeof(state));
state.cb = cb; state.cb = cb;
@ -773,9 +768,6 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb
error = git_path_direach(&buf, 0, foreach_cb, &state); error = git_path_direach(&buf, 0, foreach_cb, &state);
if (error == GIT_EUSER)
error = giterr_restore(&state.cb_error);
git_buf_free(&buf); git_buf_free(&buf);
return error; return error;

View File

@ -190,15 +190,9 @@ static int packfile_sort__cb(const void *a_, const void *b_)
} }
struct packfile_load_data { static int packfile_load__cb(void *data, git_buf *path)
struct pack_backend *backend;
git_error_state error;
};
static int packfile_load__cb(void *_data, git_buf *path)
{ {
struct packfile_load_data *data = _data; struct pack_backend *backend = data;
struct pack_backend *backend = data->backend;
struct git_pack_file *pack; struct git_pack_file *pack;
const char *path_str = git_buf_cstr(path); const char *path_str = git_buf_cstr(path);
size_t i, cmp_len = git_buf_len(path); size_t i, cmp_len = git_buf_len(path);
@ -227,7 +221,7 @@ static int packfile_load__cb(void *_data, git_buf *path)
if (!error) if (!error)
error = git_vector_insert(&backend->packs, pack); error = git_vector_insert(&backend->packs, pack);
return giterr_capture(&data->error, error); return error;
} }
@ -328,32 +322,26 @@ static int pack_entry_find_prefix(
* Implement the git_odb_backend API calls * Implement the git_odb_backend API calls
* *
***********************************************************/ ***********************************************************/
static int pack_backend__refresh(git_odb_backend *backend) static int pack_backend__refresh(git_odb_backend *backend_)
{ {
struct packfile_load_data data;
int error; int error;
struct stat st; struct stat st;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
struct pack_backend *backend = (struct pack_backend *)backend_;
memset(&data, 0, sizeof(data)); if (backend->pack_folder == NULL)
data.backend = (struct pack_backend *)backend;
if (data.backend->pack_folder == NULL)
return 0; return 0;
if (p_stat(data.backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode)) if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
return git_odb__error_notfound("failed to refresh packfiles", NULL); return git_odb__error_notfound("failed to refresh packfiles", NULL);
git_buf_sets(&path, data.backend->pack_folder); git_buf_sets(&path, backend->pack_folder);
/* reload all packs */ /* reload all packs */
error = git_path_direach(&path, 0, packfile_load__cb, &data); error = git_path_direach(&path, 0, packfile_load__cb, backend);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
git_buf_free(&path); git_buf_free(&path);
git_vector_sort(&data.backend->packs); git_vector_sort(&backend->packs);
return error; return error;
} }

View File

@ -32,7 +32,6 @@ struct unpacked {
struct tree_walk_context { struct tree_walk_context {
git_packbuilder *pb; git_packbuilder *pb;
git_buf buf; git_buf buf;
git_error_state error;
}; };
struct pack_write_context { struct pack_write_context {
@ -206,14 +205,18 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
po = pb->object_list + pb->nr_objects; po = pb->object_list + pb->nr_objects;
memset(po, 0x0, sizeof(*po)); memset(po, 0x0, sizeof(*po));
if (git_odb_read_header(&po->size, &po->type, pb->odb, oid) < 0) if ((ret = git_odb_read_header(&po->size, &po->type, pb->odb, oid)) < 0)
return -1; return ret;
pb->nr_objects++; pb->nr_objects++;
git_oid_cpy(&po->id, oid); git_oid_cpy(&po->id, oid);
po->hash = name_hash(name); po->hash = name_hash(name);
pos = kh_put(oid, pb->object_ix, &po->id, &ret); pos = kh_put(oid, pb->object_ix, &po->id, &ret);
if (ret < 0) {
giterr_set_oom();
return ret;
}
assert(ret != 0); assert(ret != 0);
kh_value(pb->object_ix, pos) = po; kh_value(pb->object_ix, pos) = po;
@ -226,10 +229,9 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) { if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
pb->last_progress_report_time = current_time; pb->last_progress_report_time = current_time;
if (pb->progress_cb( return GITERR_CALLBACK( pb->progress_cb(
GIT_PACKBUILDER_ADDING_OBJECTS, GIT_PACKBUILDER_ADDING_OBJECTS,
pb->nr_objects, 0, pb->progress_cb_payload)) pb->nr_objects, 0, pb->progress_cb_payload) );
return giterr_user_cancel();
} }
} }
@ -1303,7 +1305,7 @@ static int cb_tree_walk(
error = git_packbuilder_insert( error = git_packbuilder_insert(
ctx->pb, git_tree_entry_id(entry), git_buf_cstr(&ctx->buf)); ctx->pb, git_tree_entry_id(entry), git_buf_cstr(&ctx->buf));
return giterr_capture(&ctx->error, error); return error;
} }
int git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *oid) int git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid *oid)
@ -1331,9 +1333,6 @@ int git_packbuilder_insert_tree(git_packbuilder *pb, const git_oid *oid)
!(error = git_packbuilder_insert(pb, oid, NULL))) !(error = git_packbuilder_insert(pb, oid, NULL)))
error = git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context); error = git_tree_walk(tree, GIT_TREEWALK_PRE, cb_tree_walk, &context);
if (error == GIT_EUSER)
error = giterr_restore(&context.error);
git_tree_free(tree); git_tree_free(tree);
git_buf_free(&context.buf); git_buf_free(&context.buf);
return error; return error;

View File

@ -1082,15 +1082,16 @@ int git_pack_foreach_entry(
git_vector_foreach(&offsets, i, current) git_vector_foreach(&offsets, i, current)
git_vector_insert(&oids, (void*)&current[4]); git_vector_insert(&oids, (void*)&current[4]);
} }
git_vector_free(&offsets); git_vector_free(&offsets);
p->oids = (git_oid **)oids.contents; p->oids = (git_oid **)git_vector_detach(NULL, NULL, &oids);
} }
for (i = 0; i < p->num_objects; i++) for (i = 0; i < p->num_objects; i++)
if (cb(p->oids[i], data)) if ((error = GITERR_CALLBACK( cb(p->oids[i], data) )) != 0)
return giterr_user_cancel(); break;
return 0; return error;
} }
static int pack_entry_find_offset( static int pack_entry_find_offset(

View File

@ -434,11 +434,11 @@ int git_path_walk_up(
iter.asize = path->asize; iter.asize = path->asize;
while (scan >= stop) { while (scan >= stop) {
if (cb(data, &iter)) error = GITERR_CALLBACK( cb(data, &iter) );
error = giterr_user_cancel();
iter.ptr[scan] = oldc; iter.ptr[scan] = oldc;
if (error < 0) if (error)
break; break;
scan = git_buf_rfind_next(&iter, '/'); scan = git_buf_rfind_next(&iter, '/');
if (scan >= 0) { if (scan >= 0) {
scan++; scan++;
@ -874,14 +874,12 @@ int git_path_direach(
if ((error = git_buf_put(path, de_path, de_len)) < 0) if ((error = git_buf_put(path, de_path, de_len)) < 0)
break; break;
error = fn(arg, path); error = GITERR_CALLBACK( fn(arg, path) );
git_buf_truncate(path, wd_len); /* restore path */ git_buf_truncate(path, wd_len); /* restore path */
if (error) { if (error)
error = giterr_user_cancel();
break; break;
}
} }
closedir(dir); closedir(dir);

View File

@ -255,9 +255,10 @@ enum {
* @param flags Combination of GIT_PATH_DIR flags. * @param flags Combination of GIT_PATH_DIR flags.
* @param callback Callback for each entry. Passed the `payload` and each * @param callback Callback for each entry. Passed the `payload` and each
* successive path inside the directory as a full path. This may * successive path inside the directory as a full path. This may
* safely append text to the pathbuf if needed. * safely append text to the pathbuf if needed. Return non-zero to
* cancel iteration (and return value will be propagated back).
* @param payload Passed to callback as first argument. * @param payload Passed to callback as first argument.
* @return 0 on success, GIT_EUSER on non-zero callback, or error code * @return 0 on success or error code from OS error or from callback
*/ */
extern int git_path_direach( extern int git_path_direach(
git_buf *pathbuf, git_buf *pathbuf,
@ -288,7 +289,7 @@ extern int git_path_cmp(
* original input path. * original input path.
* @param callback Function to invoke on each path. Passed the `payload` * @param callback Function to invoke on each path. Passed the `payload`
* and the buffer containing the current path. The path should not * and the buffer containing the current path. The path should not
* be modified in any way. * be modified in any way. Return non-zero to stop iteration.
* @param state Passed to fn as the first ath. * @param state Passed to fn as the first ath.
*/ */
extern int git_path_walk_up( extern int git_path_walk_up(

View File

@ -659,8 +659,8 @@ int git_push_status_foreach(git_push *push,
unsigned int i; unsigned int i;
git_vector_foreach(&push->status, i, status) { git_vector_foreach(&push->status, i, status) {
if (cb(status->ref, status->msg, data) < 0) GITERR_CHECK_ERROR(
return giterr_user_cancel(); GITERR_CALLBACK( cb(status->ref, status->msg, data) ) );
} }
return 0; return 0;

View File

@ -264,14 +264,9 @@ done:
return error; return error;
} }
struct packed_loadloose_data { static int _dirent_loose_load(void *payload, git_buf *full_path)
refdb_fs_backend *backend;
git_error_state error;
};
static int _dirent_loose_load(void *data_, git_buf *full_path)
{ {
struct packed_loadloose_data *data = data_; refdb_fs_backend *backend = payload;
const char *file_path; const char *file_path;
if (git__suffixcmp(full_path->ptr, ".lock") == 0) if (git__suffixcmp(full_path->ptr, ".lock") == 0)
@ -279,12 +274,11 @@ static int _dirent_loose_load(void *data_, git_buf *full_path)
if (git_path_isdir(full_path->ptr)) if (git_path_isdir(full_path->ptr))
return git_path_direach( return git_path_direach(
full_path, data->backend->direach_flags, _dirent_loose_load, data); full_path, backend->direach_flags, _dirent_loose_load, backend);
file_path = full_path->ptr + strlen(data->backend->path); file_path = full_path->ptr + strlen(backend->path);
return giterr_capture( return loose_lookup_to_packfile(backend, file_path);
&data->error, loose_lookup_to_packfile(data->backend, file_path));
} }
/* /*
@ -297,27 +291,20 @@ static int packed_loadloose(refdb_fs_backend *backend)
{ {
int error; int error;
git_buf refs_path = GIT_BUF_INIT; git_buf refs_path = GIT_BUF_INIT;
struct packed_loadloose_data data;
if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0) if (git_buf_joinpath(&refs_path, backend->path, GIT_REFS_DIR) < 0)
return -1; return -1;
memset(&data, 0, sizeof(data));
data.backend = backend;
/* /*
* Load all the loose files from disk into the Packfile table. * Load all the loose files from disk into the Packfile table.
* This will overwrite any old packed entries with their * This will overwrite any old packed entries with their
* updated loose versions * updated loose versions
*/ */
error = git_path_direach( error = git_path_direach(
&refs_path, backend->direach_flags, _dirent_loose_load, &data); &refs_path, backend->direach_flags, _dirent_loose_load, backend);
git_buf_free(&refs_path); git_buf_free(&refs_path);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
return error; return error;
} }

View File

@ -516,12 +516,9 @@ int git_reference_foreach(
if ((error = git_reference_iterator_new(&iter, repo)) < 0) if ((error = git_reference_iterator_new(&iter, repo)) < 0)
return error; return error;
while ((error = git_reference_next(&ref, iter)) == 0) { while (!(error = git_reference_next(&ref, iter)) &&
if (callback(ref, payload)) { !(error = GITERR_CALLBACK( callback(ref, payload) )))
error = giterr_user_cancel(); /* callback on each reference */;
break;
}
}
if (error == GIT_ITEROVER) if (error == GIT_ITEROVER)
error = 0; error = 0;
@ -542,12 +539,9 @@ int git_reference_foreach_name(
if ((error = git_reference_iterator_new(&iter, repo)) < 0) if ((error = git_reference_iterator_new(&iter, repo)) < 0)
return error; return error;
while ((error = git_reference_next_name(&refname, iter)) == 0) { while (!(error = git_reference_next_name(&refname, iter)) &&
if (callback(refname, payload)) { !(error = GITERR_CALLBACK( callback(refname, payload) )))
error = giterr_user_cancel(); /* callback on each reference name */;
break;
}
}
if (error == GIT_ITEROVER) if (error == GIT_ITEROVER)
error = 0; error = 0;
@ -569,12 +563,9 @@ int git_reference_foreach_glob(
if ((error = git_reference_iterator_glob_new(&iter, repo, glob)) < 0) if ((error = git_reference_iterator_glob_new(&iter, repo, glob)) < 0)
return error; return error;
while ((error = git_reference_next_name(&refname, iter)) == 0) { while (!(error = git_reference_next_name(&refname, iter)) &&
if (callback(refname, payload)) { !(error = GITERR_CALLBACK( callback(refname, payload) )))
error = giterr_user_cancel(); /* callback on each matching reference name */;
break;
}
}
if (error == GIT_ITEROVER) if (error == GIT_ITEROVER)
error = 0; error = 0;
@ -621,7 +612,9 @@ void git_reference_iterator_free(git_reference_iterator *iter)
static int cb__reflist_add(const char *ref, void *data) static int cb__reflist_add(const char *ref, void *data)
{ {
return git_vector_insert((git_vector *)data, git__strdup(ref)); char *name = git__strdup(ref);
GITERR_CHECK_ALLOC(name);
return git_vector_insert((git_vector *)data, name);
} }
int git_reference_list( int git_reference_list(
@ -644,8 +637,8 @@ int git_reference_list(
return -1; return -1;
} }
array->strings = (char **)ref_list.contents; array->strings = (char **)git_vector_detach(&array->count, NULL, &ref_list);
array->count = ref_list.length;
return 0; return 0;
} }

View File

@ -251,14 +251,12 @@ int git_remote_create_inmemory(git_remote **out, git_repository *repo, const cha
struct refspec_cb_data { struct refspec_cb_data {
git_remote *remote; git_remote *remote;
int fetch; int fetch;
git_error_state error;
}; };
static int refspec_cb(const git_config_entry *entry, void *payload) static int refspec_cb(const git_config_entry *entry, void *payload)
{ {
struct refspec_cb_data *data = (struct refspec_cb_data *)payload; struct refspec_cb_data *data = (struct refspec_cb_data *)payload;
return giterr_capture( return add_refspec(data->remote, entry->value, data->fetch);
&data->error, add_refspec(data->remote, entry->value, data->fetch));
} }
static int get_optional_config( static int get_optional_config(
@ -316,17 +314,15 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
if ((error = get_check_cert(&remote->check_cert, repo)) < 0) if ((error = get_check_cert(&remote->check_cert, repo)) < 0)
goto cleanup; goto cleanup;
if ((git_vector_init(&remote->refs, 32, NULL) < 0) || if (git_vector_init(&remote->refs, 32, NULL) < 0 ||
(git_vector_init(&remote->refspecs, 2, NULL) < 0) || git_vector_init(&remote->refspecs, 2, NULL) < 0 ||
(git_vector_init(&remote->active_refspecs, 2, NULL) < 0)) { git_vector_init(&remote->active_refspecs, 2, NULL) < 0) {
error = -1; error = -1;
goto cleanup; goto cleanup;
} }
if (git_buf_printf(&buf, "remote.%s.url", name) < 0) { if ((error = git_buf_printf(&buf, "remote.%s.url", name)) < 0)
error = -1;
goto cleanup; goto cleanup;
}
if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0) if ((error = get_optional_config(&found, config, &buf, NULL, (void *)&val)) < 0)
goto cleanup; goto cleanup;
@ -387,9 +383,6 @@ int git_remote_load(git_remote **out, git_repository *repo, const char *name)
cleanup: cleanup:
git_buf_free(&buf); git_buf_free(&buf);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
if (error < 0) if (error < 0)
git_remote_free(remote); git_remote_free(remote);
@ -636,7 +629,7 @@ int git_remote_connect(git_remote *remote, git_direction direction)
if (!remote->check_cert) if (!remote->check_cert)
flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT; flags |= GIT_TRANSPORTFLAGS_NO_CHECK_CERT;
if ((error = t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags)) < 0) if ((error = t->connect(t, url, remote->callbacks.credentials, remote->callbacks.payload, direction, flags)) != 0)
goto on_error; goto on_error;
remote->transport = t; remote->transport = t;
@ -788,7 +781,7 @@ int git_remote_download(git_remote *remote)
git_vector_free(&refs); git_vector_free(&refs);
if (error < 0) if (error < 0)
return -1; return error;
if ((error = git_fetch_negotiate(remote)) < 0) if ((error = git_fetch_negotiate(remote)) < 0)
return error; return error;
@ -801,10 +794,10 @@ int git_remote_fetch(git_remote *remote)
int error; int error;
/* Connect and download everything */ /* Connect and download everything */
if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH)) < 0) if ((error = git_remote_connect(remote, GIT_DIRECTION_FETCH)) != 0)
return error; return error;
if ((error = git_remote_download(remote)) < 0) if ((error = git_remote_download(remote)) != 0)
return error; return error;
/* We don't need to be connected anymore */ /* We don't need to be connected anymore */
@ -1032,7 +1025,6 @@ int git_remote_update_tips(git_remote *remote)
int error; int error;
size_t i; size_t i;
if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0) if (git_refspec__parse(&tagspec, GIT_REFSPEC_TAGS, true) < 0)
return -1; return -1;
@ -1112,14 +1104,9 @@ void git_remote_free(git_remote *remote)
git__free(remote); git__free(remote);
} }
struct remote_list_data {
git_vector list;
git_error_state error;
};
static int remote_list_cb(const git_config_entry *entry, void *payload) static int remote_list_cb(const git_config_entry *entry, void *payload)
{ {
struct remote_list_data *data = payload; git_vector *list = payload;
const char *name = entry->name + strlen("remote."); const char *name = entry->name + strlen("remote.");
size_t namelen = strlen(name); size_t namelen = strlen(name);
char *remote_name; char *remote_name;
@ -1130,42 +1117,35 @@ static int remote_list_cb(const git_config_entry *entry, void *payload)
remote_name = git__strndup(name, namelen - 4); /* strip ".url" */ remote_name = git__strndup(name, namelen - 4); /* strip ".url" */
else else
remote_name = git__strndup(name, namelen - 8); /* strip ".pushurl" */ remote_name = git__strndup(name, namelen - 8); /* strip ".pushurl" */
if (!remote_name) GITERR_CHECK_ALLOC(remote_name);
return giterr_capture(&data->error, -1);
return giterr_capture( return git_vector_insert(list, remote_name);
&data->error, git_vector_insert(&data->list, remote_name));
} }
int git_remote_list(git_strarray *remotes_list, git_repository *repo) int git_remote_list(git_strarray *remotes_list, git_repository *repo)
{ {
int error; int error;
git_config *cfg; git_config *cfg;
struct remote_list_data data; git_vector list = GIT_VECTOR_INIT;
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
return error; return error;
memset(&data, 0, sizeof(data)); if ((error = git_vector_init(&list, 4, git__strcmp_cb)) < 0)
if ((error = git_vector_init(&data.list, 4, git__strcmp_cb)) < 0)
return error; return error;
error = git_config_foreach_match( error = git_config_foreach_match(
cfg, "^remote\\..*\\.(push)?url$", remote_list_cb, &data); cfg, "^remote\\..*\\.(push)?url$", remote_list_cb, &list);
/* cb error is converted to GIT_EUSER by git_config_foreach */
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
if (error < 0) { if (error < 0) {
git_vector_free_all(&data.list); git_vector_free_all(&list);
return error; return error;
} }
git_vector_uniq(&data.list, git__free); git_vector_uniq(&list, git__free);
remotes_list->strings = (char **)data.list.contents; remotes_list->strings =
remotes_list->count = data.list.length; (char **)git_vector_detach(&remotes_list->count, NULL, &list);
return 0; return 0;
} }
@ -1256,7 +1236,6 @@ struct update_data {
git_config *config; git_config *config;
const char *old_remote_name; const char *old_remote_name;
const char *new_remote_name; const char *new_remote_name;
git_error_state error;
}; };
static int update_config_entries_cb( static int update_config_entries_cb(
@ -1268,9 +1247,8 @@ static int update_config_entries_cb(
if (strcmp(entry->value, data->old_remote_name)) if (strcmp(entry->value, data->old_remote_name))
return 0; return 0;
return giterr_capture( return git_config_set_string(
&data->error, git_config_set_string( data->config, entry->name, data->new_remote_name);
data->config, entry->name, data->new_remote_name));
} }
static int update_branch_remote_config_entry( static int update_branch_remote_config_entry(
@ -1287,13 +1265,8 @@ static int update_branch_remote_config_entry(
data.old_remote_name = old_name; data.old_remote_name = old_name;
data.new_remote_name = new_name; data.new_remote_name = new_name;
error = git_config_foreach_match( return git_config_foreach_match(
data.config, "branch\\..+\\.remote", update_config_entries_cb, &data); data.config, "branch\\..+\\.remote", update_config_entries_cb, &data);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
return error;
} }
static int rename_one_remote_reference( static int rename_one_remote_reference(
@ -1357,13 +1330,14 @@ static int rename_fetch_refspecs(
git_buf base = GIT_BUF_INIT, var = GIT_BUF_INIT, val = GIT_BUF_INIT; git_buf base = GIT_BUF_INIT, var = GIT_BUF_INIT, val = GIT_BUF_INIT;
const git_refspec *spec; const git_refspec *spec;
size_t i; size_t i;
int error = -1; int error = 0;
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) if ((error = git_repository_config__weakptr(&config, remote->repo)) < 0)
goto cleanup; return error;
if ((error = git_buf_printf(
&base, "+refs/heads/*:refs/remotes/%s/*", remote->name)) < 0)
return error;
git_vector_foreach(&remote->refspecs, i, spec) { git_vector_foreach(&remote->refspecs, i, spec) {
if (spec->push) if (spec->push)
@ -1374,10 +1348,9 @@ static int rename_fetch_refspecs(
if (!remote->name || if (!remote->name ||
strcmp(git_buf_cstr(&base), spec->string)) { strcmp(git_buf_cstr(&base), spec->string)) {
if (callback(spec->string, payload) < 0) { error = GITERR_CALLBACK( callback(spec->string, payload) );
error = giterr_user_cancel(); if (error)
goto cleanup; break;
}
continue; continue;
} }
@ -1391,15 +1364,14 @@ static int rename_fetch_refspecs(
git_buf_printf(&var, "remote.%s.fetch", new_name) < 0) git_buf_printf(&var, "remote.%s.fetch", new_name) < 0)
{ {
error = -1; error = -1;
goto cleanup; break;
} }
if ((error = git_config_set_string( if ((error = git_config_set_string(
config, git_buf_cstr(&var), git_buf_cstr(&val))) < 0) config, git_buf_cstr(&var), git_buf_cstr(&val))) < 0)
goto cleanup; break;
} }
cleanup:
git_buf_free(&base); git_buf_free(&base);
git_buf_free(&var); git_buf_free(&var);
git_buf_free(&val); git_buf_free(&val);

View File

@ -1608,15 +1608,14 @@ static int at_least_one_cb(const char *refname, void *payload)
{ {
GIT_UNUSED(refname); GIT_UNUSED(refname);
GIT_UNUSED(payload); GIT_UNUSED(payload);
return GIT_PASSTHROUGH;
return GIT_EUSER;
} }
static int repo_contains_no_reference(git_repository *repo) static int repo_contains_no_reference(git_repository *repo)
{ {
int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL); int error = git_reference_foreach_name(repo, &at_least_one_cb, NULL);
if (error == GIT_EUSER) if (error == GIT_PASSTHROUGH)
return 0; return 0;
if (!error) if (!error)

View File

@ -169,15 +169,12 @@ static int push_ref(git_revwalk *walk, const char *refname, int hide)
struct push_cb_data { struct push_cb_data {
git_revwalk *walk; git_revwalk *walk;
int hide; int hide;
git_error_state error;
}; };
static int push_glob_cb(const char *refname, void *data_) static int push_glob_cb(const char *refname, void *data_)
{ {
struct push_cb_data *data = (struct push_cb_data *)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) static int push_glob(git_revwalk *walk, const char *glob, int hide)
@ -204,12 +201,9 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
data.walk = walk; data.walk = walk;
data.hide = hide; data.hide = hide;
memset(&data.error, 0, sizeof(data.error));
error = git_reference_foreach_glob( error = git_reference_foreach_glob(
walk->repo, git_buf_cstr(&buf), push_glob_cb, &data); walk->repo, git_buf_cstr(&buf), push_glob_cb, &data);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
git_buf_free(&buf); git_buf_free(&buf);
return error; return error;

View File

@ -440,7 +440,7 @@ static int is_dirty_cb(const char *path, unsigned int status, void *payload)
GIT_UNUSED(status); GIT_UNUSED(status);
GIT_UNUSED(payload); GIT_UNUSED(payload);
return 1; return GIT_PASSTHROUGH;
} }
static int ensure_there_are_changes_to_stash( static int ensure_there_are_changes_to_stash(
@ -463,7 +463,7 @@ static int ensure_there_are_changes_to_stash(
error = git_status_foreach_ext(repo, &opts, is_dirty_cb, NULL); error = git_status_foreach_ext(repo, &opts, is_dirty_cb, NULL);
if (error == GIT_EUSER) if (error == GIT_PASSTHROUGH)
return 0; return 0;
if (!error) if (!error)
@ -582,13 +582,13 @@ int git_stash_foreach(
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {
entry = git_reflog_entry_byindex(reflog, i); entry = git_reflog_entry_byindex(reflog, i);
if (callback(i, error = GITERR_CALLBACK(
git_reflog_entry_message(entry), callback(i,
git_reflog_entry_id_new(entry), git_reflog_entry_message(entry),
payload)) { git_reflog_entry_id_new(entry),
error = giterr_user_cancel(); payload) );
if (error)
break; break;
}
} }
cleanup: cleanup:

View File

@ -152,32 +152,25 @@ static git_status_t status_compute(
return st; return st;
} }
struct status_data {
git_status_list *status;
git_error_state err;
};
static int status_collect( static int status_collect(
git_diff_delta *head2idx, git_diff_delta *head2idx,
git_diff_delta *idx2wd, git_diff_delta *idx2wd,
void *payload) void *payload)
{ {
struct status_data *data = payload; git_status_list *status = payload;
git_status_entry *status_entry; git_status_entry *status_entry;
if (!status_is_included(data->status, head2idx, idx2wd)) if (!status_is_included(status, head2idx, idx2wd))
return 0; return 0;
status_entry = git__malloc(sizeof(git_status_entry)); status_entry = git__malloc(sizeof(git_status_entry));
if (!status_entry) GITERR_CHECK_ALLOC(status_entry);
return giterr_capture(&data->err, -1);
status_entry->status = status_compute(data->status, head2idx, idx2wd); status_entry->status = status_compute(status, head2idx, idx2wd);
status_entry->head_to_index = head2idx; status_entry->head_to_index = head2idx;
status_entry->index_to_workdir = idx2wd; status_entry->index_to_workdir = idx2wd;
return giterr_capture( return git_vector_insert(&status->paired, status_entry);
&data->err, git_vector_insert(&data->status->paired, status_entry));
} }
GIT_INLINE(int) status_entry_cmp_base( GIT_INLINE(int) status_entry_cmp_base(
@ -321,18 +314,10 @@ int git_status_list_new(
goto done; goto done;
} }
{ error = git_diff__paired_foreach(
struct status_data data = { 0 }; status->head2idx, status->idx2wd, status_collect, status);
data.status = status; if (error < 0)
goto done;
error = git_diff__paired_foreach(
status->head2idx, status->idx2wd, status_collect, &data);
if (error == GIT_EUSER)
error = giterr_restore(&data.err);
if (error < 0)
goto done;
}
if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY) if (flags & GIT_STATUS_OPT_SORT_CASE_SENSITIVELY)
git_vector_set_cmp(&status->paired, status_entry_cmp); git_vector_set_cmp(&status->paired, status_entry_cmp);
@ -407,10 +392,9 @@ int git_status_foreach_ext(
status_entry->head_to_index->old_file.path : status_entry->head_to_index->old_file.path :
status_entry->index_to_workdir->old_file.path; status_entry->index_to_workdir->old_file.path;
if (cb(path, status_entry->status, payload) != 0) { error = GITERR_CALLBACK( cb(path, status_entry->status, payload) );
error = giterr_user_cancel(); if (error)
break; break;
}
} }
git_status_list_free(status); git_status_list_free(status);

View File

@ -71,11 +71,6 @@ __KHASH_IMPL(
str, static kh_inline, const char *, void *, 1, str, static kh_inline, const char *, void *, 1,
str_hash_no_trailing_slash, str_equal_no_trailing_slash); str_hash_no_trailing_slash, str_equal_no_trailing_slash);
struct submodule_callback_payload {
git_repository *repo;
git_error_state error;
};
static int load_submodule_config(git_repository *repo); static int load_submodule_config(git_repository *repo);
static git_config_backend *open_gitmodules(git_repository *, bool, const git_oid *); static git_config_backend *open_gitmodules(git_repository *, bool, const git_oid *);
static int lookup_head_remote(git_buf *url, git_repository *repo); static int lookup_head_remote(git_buf *url, git_repository *repo);
@ -173,10 +168,8 @@ int git_submodule_foreach(
break; break;
} }
if (callback(sm, sm->name, payload)) { if ((error = GITERR_CALLBACK(callback(sm, sm->name, payload))) != 0)
error = giterr_user_cancel();
break; break;
}
}); });
git_vector_free(&seen); git_vector_free(&seen);
@ -825,7 +818,6 @@ int git_submodule_reload(git_submodule *submodule)
{ {
int error = 0; int error = 0;
git_config_backend *mods; git_config_backend *mods;
struct submodule_callback_payload p;
assert(submodule); assert(submodule);
@ -838,9 +830,6 @@ int git_submodule_reload(git_submodule *submodule)
return error; return error;
/* refresh config data */ /* refresh config data */
memset(&p, 0, sizeof(p));
p.repo = submodule->repo;
mods = open_gitmodules(submodule->repo, false, NULL); mods = open_gitmodules(submodule->repo, false, NULL);
if (mods != NULL) { if (mods != NULL) {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
@ -851,13 +840,9 @@ int git_submodule_reload(git_submodule *submodule)
if (git_buf_oom(&path)) if (git_buf_oom(&path))
error = -1; error = -1;
else { else
error = git_config_file_foreach_match( error = git_config_file_foreach_match(
mods, path.ptr, submodule_load_from_config, &p); mods, path.ptr, submodule_load_from_config, submodule->repo);
if (error == GIT_EUSER)
error = giterr_restore(&p.error);
}
git_buf_free(&path); git_buf_free(&path);
git_config_file_free(mods); git_config_file_free(mods);
@ -867,15 +852,11 @@ int git_submodule_reload(git_submodule *submodule)
} }
/* refresh wd data */ /* refresh wd data */
submodule->flags = submodule->flags & submodule->flags = submodule->flags &
~(GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_OID_VALID); ~(GIT_SUBMODULE_STATUS_IN_WD | GIT_SUBMODULE_STATUS__WD_OID_VALID);
error = submodule_load_from_wd_lite(submodule, submodule->path, &p); return submodule_load_from_wd_lite(
if (error) submodule, submodule->path, submodule->repo);
error = giterr_restore(&p.error);
return error;
} }
static void submodule_copy_oid_maybe( static void submodule_copy_oid_maybe(
@ -1100,8 +1081,8 @@ int git_submodule_parse_update(git_submodule_update_t *out, const char *value)
static int submodule_load_from_config( static int submodule_load_from_config(
const git_config_entry *entry, void *payload) const git_config_entry *entry, void *payload)
{ {
struct submodule_callback_payload *p = payload; git_repository *repo = payload;
git_strmap *smcfg = p->repo->submodules; git_strmap *smcfg = repo->submodules;
const char *namestart, *property, *alternate = NULL; const char *namestart, *property, *alternate = NULL;
const char *key = entry->name, *value = entry->value, *path; const char *key = entry->name, *value = entry->value, *path;
git_buf name = GIT_BUF_INIT; git_buf name = GIT_BUF_INIT;
@ -1121,7 +1102,7 @@ static int submodule_load_from_config(
path = !strcasecmp(property, "path") ? value : NULL; path = !strcasecmp(property, "path") ? value : NULL;
if ((error = git_buf_set(&name, namestart, property - namestart - 1)) < 0 || if ((error = git_buf_set(&name, namestart, property - namestart - 1)) < 0 ||
(error = submodule_get(&sm, p->repo, name.ptr, path)) < 0) (error = submodule_get(&sm, repo, name.ptr, path)) < 0)
goto done; goto done;
sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG; sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;
@ -1197,22 +1178,21 @@ static int submodule_load_from_config(
done: done:
git_buf_free(&name); git_buf_free(&name);
return giterr_capture(&p->error, error); return error;
} }
static int submodule_load_from_wd_lite( static int submodule_load_from_wd_lite(
git_submodule *sm, const char *name, void *payload) git_submodule *sm, const char *name, void *payload)
{ {
struct submodule_callback_payload *p = payload;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
GIT_UNUSED(name); GIT_UNUSED(name); GIT_UNUSED(payload);
if (git_repository_is_bare(sm->repo)) if (git_repository_is_bare(sm->repo))
return 0; return 0;
if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0) if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0)
return giterr_capture(&p->error, -1); return -1;
if (git_path_isdir(path.ptr)) if (git_path_isdir(path.ptr))
sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED; sm->flags |= GIT_SUBMODULE_STATUS__WD_SCANNED;
@ -1355,14 +1335,11 @@ static int load_submodule_config(git_repository *repo)
int error; int error;
git_oid gitmodules_oid; git_oid gitmodules_oid;
git_config_backend *mods = NULL; git_config_backend *mods = NULL;
struct submodule_callback_payload p;
if (repo->submodules) if (repo->submodules)
return 0; return 0;
memset(&gitmodules_oid, 0, sizeof(gitmodules_oid)); memset(&gitmodules_oid, 0, sizeof(gitmodules_oid));
memset(&p, 0, sizeof(p));
p.repo = repo;
/* Submodule data is kept in a hashtable keyed by both name and path. /* Submodule data is kept in a hashtable keyed by both name and path.
* These are usually the same, but that is not guaranteed. * These are usually the same, but that is not guaranteed.
@ -1386,21 +1363,18 @@ static int load_submodule_config(git_repository *repo)
if ((mods = open_gitmodules(repo, false, &gitmodules_oid)) != NULL && if ((mods = open_gitmodules(repo, false, &gitmodules_oid)) != NULL &&
(error = git_config_file_foreach( (error = git_config_file_foreach(
mods, submodule_load_from_config, &p)) < 0) mods, submodule_load_from_config, repo)) < 0)
goto cleanup; goto cleanup;
/* shallow scan submodules in work tree */ /* shallow scan submodules in work tree */
if (!git_repository_is_bare(repo)) if (!git_repository_is_bare(repo))
error = git_submodule_foreach(repo, submodule_load_from_wd_lite, &p); error = git_submodule_foreach(repo, submodule_load_from_wd_lite, NULL);
cleanup: cleanup:
if (mods != NULL) if (mods != NULL)
git_config_file_free(mods); git_config_file_free(mods);
if (error == GIT_EUSER)
error = giterr_restore(&p.error);
if (error) if (error)
git_submodule_config_free(repo); git_submodule_config_free(repo);

View File

@ -414,7 +414,6 @@ typedef struct {
git_repository *repo; git_repository *repo;
git_tag_foreach_cb cb; git_tag_foreach_cb cb;
void *cb_data; void *cb_data;
git_error_state error;
} tag_cb_data; } tag_cb_data;
static int tags_cb(const char *ref, void *data) static int tags_cb(const char *ref, void *data)
@ -427,16 +426,15 @@ static int tags_cb(const char *ref, void *data)
return 0; /* no tag */ return 0; /* no tag */
if (!(error = git_reference_name_to_id(&oid, d->repo, ref))) { if (!(error = git_reference_name_to_id(&oid, d->repo, ref))) {
if (d->cb(ref, &oid, d->cb_data)) error = d->cb(ref, &oid, d->cb_data);
error = giterr_user_cancel(); giterr_set_callback(error, "git_tag_foreach");
} }
return giterr_capture(&d->error, error); return error;
} }
int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data) int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data)
{ {
int error;
tag_cb_data data; tag_cb_data data;
assert(repo && cb); assert(repo && cb);
@ -444,14 +442,8 @@ int git_tag_foreach(git_repository *repo, git_tag_foreach_cb cb, void *cb_data)
data.cb = cb; data.cb = cb;
data.cb_data = cb_data; data.cb_data = cb_data;
data.repo = repo; data.repo = repo;
memset(&data.error, 0, sizeof(data.error));
error = git_reference_foreach_name(repo, &tags_cb, &data); return git_reference_foreach_name(repo, &tags_cb, &data);
if (error == GIT_EUSER)
error = giterr_restore(&data.error);
return error;
} }
typedef struct { typedef struct {
@ -470,8 +462,8 @@ static int tag_list_cb(const char *tag_name, git_oid *oid, void *data)
p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0) p_fnmatch(filter->pattern, tag_name + GIT_REFS_TAGS_DIR_LEN, 0) == 0)
{ {
char *matched = git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN); char *matched = git__strdup(tag_name + GIT_REFS_TAGS_DIR_LEN);
if (!matched) GITERR_CHECK_ALLOC(matched);
return -1;
return git_vector_insert(filter->taglist, matched); return git_vector_insert(filter->taglist, matched);
} }
@ -494,19 +486,12 @@ int git_tag_list_match(git_strarray *tag_names, const char *pattern, git_reposit
error = git_tag_foreach(repo, &tag_list_cb, (void *)&filter); error = git_tag_foreach(repo, &tag_list_cb, (void *)&filter);
/* the only case where callback will return an error is oom */ if (error < 0)
if (error == GIT_EUSER) {
giterr_set_oom();
error = -1;
}
if (error < 0) {
git_vector_free(&taglist); git_vector_free(&taglist);
return error;
}
tag_names->strings = (char **)taglist.contents; tag_names->strings =
tag_names->count = taglist.length; (char **)git_vector_detach(&tag_names->count, NULL, &taglist);
return 0; return 0;
} }

View File

@ -382,9 +382,6 @@ static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len)
static void clear_parser_state(http_subtransport *t) static void clear_parser_state(http_subtransport *t)
{ {
unsigned i;
char *entry;
http_parser_init(&t->parser, HTTP_RESPONSE); http_parser_init(&t->parser, HTTP_RESPONSE);
gitno_buffer_setup(&t->socket, gitno_buffer_setup(&t->socket,
&t->parse_buffer, &t->parse_buffer,
@ -407,10 +404,7 @@ static void clear_parser_state(http_subtransport *t)
git__free(t->location); git__free(t->location);
t->location = NULL; t->location = NULL;
git_vector_foreach(&t->www_authenticate, i, entry) git_vector_free_all(&t->www_authenticate);
git__free(entry);
git_vector_free(&t->www_authenticate);
} }
static int write_chunk(gitno_socket *socket, const char *buffer, size_t len) static int write_chunk(gitno_socket *socket, const char *buffer, size_t len)

View File

@ -43,43 +43,43 @@ typedef struct {
static int add_ref(transport_local *t, const char *name) static int add_ref(transport_local *t, const char *name)
{ {
const char peeled[] = "^{}"; const char peeled[] = "^{}";
git_oid head_oid;
git_remote_head *head; git_remote_head *head;
git_object *obj = NULL, *target = NULL; git_object *obj = NULL, *target = NULL;
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
int error; int error;
error = git_reference_name_to_id(&head_oid, t->repo, name);
if (error < 0) {
if (!strcmp(name, GIT_HEAD_FILE) && error == GIT_ENOTFOUND) {
/* This is actually okay. Empty repos often have a HEAD that
* points to a nonexistent "refs/heads/master". */
giterr_clear();
return 0;
}
return error;
}
head = git__calloc(1, sizeof(git_remote_head)); head = git__calloc(1, sizeof(git_remote_head));
GITERR_CHECK_ALLOC(head); GITERR_CHECK_ALLOC(head);
head->name = git__strdup(name); head->name = git__strdup(name);
GITERR_CHECK_ALLOC(head->name); GITERR_CHECK_ALLOC(head->name);
error = git_reference_name_to_id(&head->oid, t->repo, name); git_oid_cpy(&head->oid, &head_oid);
if (error < 0) {
git__free(head->name);
git__free(head);
if (!strcmp(name, GIT_HEAD_FILE) && error == GIT_ENOTFOUND) {
/* This is actually okay. Empty repos often have a HEAD that points to
* a nonexistent "refs/heads/master". */
giterr_clear();
return 0;
}
return error;
}
if (git_vector_insert(&t->refs, head) < 0) if ((error = git_vector_insert(&t->refs, head)) < 0) {
{
git__free(head->name); git__free(head->name);
git__free(head); git__free(head);
return -1; return error;
} }
/* If it's not a tag, we don't need to try to peel it */ /* If it's not a tag, we don't need to try to peel it */
if (git__prefixcmp(name, GIT_REFS_TAGS_DIR)) if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
return 0; return 0;
if (git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY) < 0) if ((error = git_object_lookup(&obj, t->repo, &head->oid, GIT_OBJ_ANY)) < 0)
return -1; return error;
head = NULL; head = NULL;
@ -94,27 +94,24 @@ static int add_ref(transport_local *t, const char *name)
/* And if it's a tag, peel it, and add it to the list */ /* And if it's a tag, peel it, and add it to the list */
head = git__calloc(1, sizeof(git_remote_head)); head = git__calloc(1, sizeof(git_remote_head));
GITERR_CHECK_ALLOC(head); GITERR_CHECK_ALLOC(head);
if (git_buf_join(&buf, 0, name, peeled) < 0) if (git_buf_join(&buf, 0, name, peeled) < 0)
return -1; return -1;
head->name = git_buf_detach(&buf); head->name = git_buf_detach(&buf);
if (git_tag_peel(&target, (git_tag *) obj) < 0) if (!(error = git_tag_peel(&target, (git_tag *)obj))) {
goto on_error; git_oid_cpy(&head->oid, git_object_id(target));
if ((error = git_vector_insert(&t->refs, head)) < 0) {
git__free(head->name);
git__free(head);
}
}
git_oid_cpy(&head->oid, git_object_id(target));
git_object_free(obj); git_object_free(obj);
git_object_free(target); git_object_free(target);
if (git_vector_insert(&t->refs, head) < 0) return error;
return -1;
return 0;
on_error:
git_object_free(obj);
git_object_free(target);
return -1;
} }
static int store_refs(transport_local *t) static int store_refs(transport_local *t)
@ -222,7 +219,7 @@ static int local_ls(const git_remote_head ***out, size_t *size, git_transport *t
return -1; return -1;
} }
*out = (const git_remote_head **) t->refs.contents; *out = (const git_remote_head **)t->refs.contents;
*size = t->refs.length; *size = t->refs.length;
return 0; return 0;
@ -529,7 +526,7 @@ static int local_download_pack(
} }
} }
if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) < 0) if ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0)
goto cleanup; goto cleanup;
/* Write the data to the ODB */ /* Write the data to the ODB */
@ -540,7 +537,7 @@ static int local_download_pack(
data.progress_payload = progress_payload; data.progress_payload = progress_payload;
data.writepack = writepack; data.writepack = writepack;
if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) < 0) if ((error = git_packbuilder_foreach(pack, foreach_cb, &data)) != 0)
goto cleanup; goto cleanup;
} }
error = writepack->commit(writepack, stats); error = writepack->commit(writepack, stats);

View File

@ -23,12 +23,13 @@ static int git_smart__recv_cb(gitno_buffer *buf)
buf->offset += bytes_read; buf->offset += bytes_read;
if (t->packetsize_cb && !t->cancelled.val) if (t->packetsize_cb && !t->cancelled.val) {
if (t->packetsize_cb(bytes_read, t->packetsize_payload)) { error = t->packetsize_cb(bytes_read, t->packetsize_payload);
if (error) {
git_atomic_set(&t->cancelled, 1); git_atomic_set(&t->cancelled, 1);
return GIT_EUSER;
return giterr_user_cancel();
} }
}
return (int)(buf->offset - old_len); return (int)(buf->offset - old_len);
} }

View File

@ -45,7 +45,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
error = GIT_EBUFS; error = GIT_EBUFS;
if (error < 0 && error != GIT_EBUFS) if (error < 0 && error != GIT_EBUFS)
return -1; return error;
if (error == GIT_EBUFS) { if (error == GIT_EBUFS) {
if ((recvd = gitno_recv(buf)) < 0) if ((recvd = gitno_recv(buf)) < 0)
@ -209,12 +209,13 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
git_strarray refs; git_strarray refs;
unsigned int i; unsigned int i;
git_reference *ref; git_reference *ref;
int error;
if (git_reference_list(&refs, repo) < 0) if ((error = git_reference_list(&refs, repo)) < 0)
return -1; return error;
if (git_revwalk_new(&walk, repo) < 0) if ((error = git_revwalk_new(&walk, repo)) < 0)
return -1; return error;
git_revwalk_sorting(walk, GIT_SORT_TIME); git_revwalk_sorting(walk, GIT_SORT_TIME);
@ -223,13 +224,13 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
if (!git__prefixcmp(refs.strings[i], GIT_REFS_TAGS_DIR)) if (!git__prefixcmp(refs.strings[i], GIT_REFS_TAGS_DIR))
continue; continue;
if (git_reference_lookup(&ref, repo, refs.strings[i]) < 0) if ((error = git_reference_lookup(&ref, repo, refs.strings[i])) < 0)
goto on_error; goto on_error;
if (git_reference_type(ref) == GIT_REF_SYMBOLIC) if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
continue; continue;
if (git_revwalk_push(walk, git_reference_target(ref)) < 0) if ((error = git_revwalk_push(walk, git_reference_target(ref))) < 0)
goto on_error; goto on_error;
git_reference_free(ref); git_reference_free(ref);
@ -242,7 +243,7 @@ static int fetch_setup_walk(git_revwalk **out, git_repository *repo)
on_error: on_error:
git_reference_free(ref); git_reference_free(ref);
git_strarray_free(&refs); git_strarray_free(&refs);
return -1; return error;
} }
static int wait_while_ack(gitno_buffer *buf) static int wait_while_ack(gitno_buffer *buf)
@ -503,7 +504,7 @@ int git_smart__download_pack(
} }
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 || if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) < 0)) ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) != 0))
goto done; goto done;
/* /*
@ -539,11 +540,9 @@ int git_smart__download_pack(
if (pkt->type == GIT_PKT_PROGRESS) { if (pkt->type == GIT_PKT_PROGRESS) {
if (t->progress_cb) { if (t->progress_cb) {
git_pkt_progress *p = (git_pkt_progress *) pkt; git_pkt_progress *p = (git_pkt_progress *) pkt;
if (t->progress_cb(p->data, p->len, t->message_cb_payload)) { error = t->progress_cb(p->data, p->len, t->message_cb_payload);
giterr_clear(); if (error)
error = GIT_EUSER;
goto done; goto done;
}
} }
git__free(pkt); git__free(pkt);
} else if (pkt->type == GIT_PKT_DATA) { } else if (pkt->type == GIT_PKT_DATA) {
@ -551,7 +550,7 @@ int git_smart__download_pack(
error = writepack->append(writepack, p->data, p->len, stats); error = writepack->append(writepack, p->data, p->len, stats);
git__free(pkt); git__free(pkt);
if (error < 0) if (error != 0)
goto done; goto done;
} else if (pkt->type == GIT_PKT_FLUSH) { } else if (pkt->type == GIT_PKT_FLUSH) {
/* A flush indicates the end of the packfile */ /* A flush indicates the end of the packfile */
@ -570,11 +569,9 @@ int git_smart__download_pack(
* correct last received_bytes value is reported. * correct last received_bytes value is reported.
*/ */
if (npp.callback && npp.stats->received_bytes > npp.last_fired_bytes) { if (npp.callback && npp.stats->received_bytes > npp.last_fired_bytes) {
if (npp.callback(npp.stats, npp.payload) < 0) { error = npp.callback(npp.stats, npp.payload);
giterr_clear(); if (error != 0)
error = GIT_EUSER;
goto done; goto done;
}
} }
error = writepack->commit(writepack, stats); error = writepack->commit(writepack, stats);

View File

@ -667,9 +667,11 @@ replay:
if (allowed_types && if (allowed_types &&
(!t->cred || 0 == (t->cred->credtype & allowed_types))) { (!t->cred || 0 == (t->cred->credtype & allowed_types))) {
if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types, int error = t->owner->cred_acquire_cb(
t->owner->cred_acquire_payload) < 0) &t->cred, t->owner->url, t->connection_data.user,
return GIT_EUSER; allowed_types, t->owner->cred_acquire_payload);
if (error < 0)
return error;
assert(t->cred); assert(t->cred);

View File

@ -883,9 +883,8 @@ static int tree_walk(
git_vector_foreach(&tree->entries, i, entry) { git_vector_foreach(&tree->entries, i, entry) {
if (preorder) { if (preorder) {
error = callback(path->ptr, entry, payload); if ((error = callback(path->ptr, entry, payload)) < 0)
if (error < 0) return giterr_set_callback(error, "git_tree_walk");
return giterr_user_cancel();
if (error > 0) { if (error > 0) {
error = 0; error = 0;
continue; continue;
@ -896,8 +895,8 @@ static int tree_walk(
git_tree *subtree; git_tree *subtree;
size_t path_len = git_buf_len(path); size_t path_len = git_buf_len(path);
if ((error = git_tree_lookup( error = git_tree_lookup(&subtree, tree->object.repo, &entry->oid);
&subtree, tree->object.repo, &entry->oid)) < 0) if (error < 0)
break; break;
/* append the next entry to the path */ /* append the next entry to the path */
@ -905,19 +904,22 @@ static int tree_walk(
git_buf_putc(path, '/'); git_buf_putc(path, '/');
if (git_buf_oom(path)) if (git_buf_oom(path))
return -1; error = -1;
else
error = tree_walk(subtree, callback, path, payload, preorder);
error = tree_walk(subtree, callback, path, payload, preorder);
git_tree_free(subtree); git_tree_free(subtree);
if (error != 0) if (error != 0)
break; break;
git_buf_truncate(path, path_len); git_buf_truncate(path, path_len);
} }
if (!preorder && callback(path->ptr, entry, payload) < 0) if (!preorder) {
return giterr_user_cancel(); if ((error = callback(path->ptr, entry, payload)) < 0)
return giterr_set_callback(error, "git_tree_walk");
error = 0;
}
} }
return error; return error;

View File

@ -104,6 +104,22 @@ int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp)
return resize_vector(v, max(initial_size, MIN_ALLOCSIZE)); return resize_vector(v, max(initial_size, MIN_ALLOCSIZE));
} }
void **git_vector_detach(size_t *size, size_t *asize, git_vector *v)
{
void **data = v->contents;
if (size)
*size = v->length;
if (asize)
*asize = v->_alloc_size;
v->_alloc_size = 0;
v->length = 0;
v->contents = NULL;
return data;
}
int git_vector_insert(git_vector *v, void *element) int git_vector_insert(git_vector *v, void *element)
{ {
assert(v); assert(v);

View File

@ -28,6 +28,8 @@ void git_vector_clear(git_vector *v);
int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp); int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp);
void git_vector_swap(git_vector *a, git_vector *b); void git_vector_swap(git_vector *a, git_vector *b);
void **git_vector_detach(size_t *size, size_t *asize, git_vector *v);
void git_vector_sort(git_vector *v); void git_vector_sort(git_vector *v);
/** Linear search for matching entry using internal comparison function */ /** Linear search for matching entry using internal comparison function */

View File

@ -129,6 +129,8 @@ static int count_attrs(
return 0; return 0;
} }
#define CANCEL_VALUE 12345
static int cancel_iteration( static int cancel_iteration(
const char *name, const char *name,
const char *value, const char *value,
@ -140,7 +142,7 @@ static int cancel_iteration(
*((int *)payload) -= 1; *((int *)payload) -= 1;
if (*((int *)payload) < 0) if (*((int *)payload) < 0)
return -1; return CANCEL_VALUE;
return 0; return 0;
} }
@ -166,7 +168,7 @@ void test_attr_repo__foreach(void)
count = 2; count = 2;
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_attr_foreach( CANCEL_VALUE, git_attr_foreach(
g_repo, 0, "sub/subdir_test1", &cancel_iteration, &count) g_repo, 0, "sub/subdir_test1", &cancel_iteration, &count)
); );
} }

View File

@ -247,7 +247,7 @@ void test_config_read__foreach(void)
count = 3; count = 3;
cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count)); cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
cl_assert_equal_i(GIT_EUSER, ret); cl_assert_equal_i(-100, ret);
git_config_free(cfg); git_config_free(cfg);
} }

View File

@ -44,7 +44,6 @@ void test_config_rename__can_rename(void)
void test_config_rename__prevent_overwrite(void) void test_config_rename__prevent_overwrite(void)
{ {
const git_config_entry *ce; const git_config_entry *ce;
const git_error *err;
cl_git_pass(git_config_set_string( cl_git_pass(git_config_set_string(
g_config, "branch.local-track.remote", "yellow")); g_config, "branch.local-track.remote", "yellow"));
@ -60,8 +59,12 @@ void test_config_rename__prevent_overwrite(void)
&ce, g_config, "branch.local-track.remote")); &ce, g_config, "branch.local-track.remote"));
cl_assert_equal_s(".", ce->value); cl_assert_equal_s(".", ce->value);
// cl_assert((err = giterr_last()) != NULL); /* so, we don't currently prevent overwrite... */
// cl_assert(err->message != NULL); /* {
const git_error *err;
cl_assert((err = giterr_last()) != NULL);
cl_assert(err->message != NULL);
} */
} }
static void assert_invalid_config_section_name( static void assert_invalid_config_section_name(

View File

@ -354,13 +354,15 @@ typedef struct {
char **expect; char **expect;
} check_walkup_info; } check_walkup_info;
#define CANCEL_VALUE 1234
static int check_one_walkup_step(void *ref, git_buf *path) static int check_one_walkup_step(void *ref, git_buf *path)
{ {
check_walkup_info *info = (check_walkup_info *)ref; check_walkup_info *info = (check_walkup_info *)ref;
if (!info->cancel_after) { if (!info->cancel_after) {
cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]"); cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]");
return -1; return CANCEL_VALUE;
} }
info->cancel_after--; info->cancel_after--;
@ -435,7 +437,7 @@ void test_core_path__11a_walkup_cancel(void)
info.expect_idx = i; info.expect_idx = i;
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, CANCEL_VALUE,
git_path_walk_up(&p, root[j], check_one_walkup_step, &info) git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
); );

View File

@ -128,9 +128,7 @@ void test_diff_index__1(void)
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, NULL, &opts));
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, 1, git_diff_foreach(diff, diff_stop_after_2_files, NULL, NULL, &exp) );
git_diff_foreach(diff, diff_stop_after_2_files, NULL, NULL, &exp)
);
cl_assert_equal_i(2, exp.files); cl_assert_equal_i(2, exp.files);

View File

@ -20,7 +20,7 @@ static int assert_called_notifications(
{ {
bool found = false; bool found = false;
notify_expected *exp = (notify_expected*)payload; notify_expected *exp = (notify_expected*)payload;
notify_expected *e;; notify_expected *e;
GIT_UNUSED(diff_so_far); GIT_UNUSED(diff_so_far);

View File

@ -111,6 +111,28 @@ void test_diff_rename__match_oid(void)
git_diff_free(diff); git_diff_free(diff);
cl_git_pass(git_diff_tree_to_tree(
&diff, g_repo, old_tree, new_tree, &diffopts));
/* git diff --find-copies-harder -M100 -B100 \
* 31e47d8c1fa36d7f8d537b96158e3f024de0a9f2 \
* 2bc7f351d20b53f1c72c16c4b036e491c478c49a
*/
opts.flags = GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED |
GIT_DIFF_FIND_EXACT_MATCH_ONLY;
cl_git_pass(git_diff_find_similar(diff, &opts));
memset(&exp, 0, sizeof(exp));
cl_git_pass(git_diff_foreach(
diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
cl_assert_equal_i(3, exp.files);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_UNMODIFIED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_COPIED]);
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_RENAMED]);
git_diff_free(diff);
git_tree_free(old_tree); git_tree_free(old_tree);
git_tree_free(new_tree); git_tree_free(new_tree);
} }

View File

@ -129,7 +129,7 @@ void test_notes_notes__can_cancel_foreach(void)
create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n"); create_note(&note_oid4, "refs/notes/i-can-see-dead-notes", "4a202b346bb0fb0db7eff3cffeb3c70babbd2045", "I decorate 9fd7 and 4a20\n");
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, 1,
git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes", git_note_foreach(_repo, "refs/notes/i-can-see-dead-notes",
note_cancel_cb, &retrieved_notes)); note_cancel_cb, &retrieved_notes));
} }

View File

@ -59,7 +59,7 @@ static int treewalk_stop_cb(
(*count) += 1; (*count) += 1;
return (*count == 2) ? -1 : 0; return (*count == 2) ? -123 : 0;
} }
static int treewalk_stop_immediately_cb( static int treewalk_stop_immediately_cb(
@ -83,20 +83,20 @@ void test_object_tree_walk__1(void)
ct = 0; ct = 0;
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_stop_cb, &ct)); -123, git_tree_walk(tree, GIT_TREEWALK_PRE, treewalk_stop_cb, &ct));
cl_assert_equal_i(2, ct); cl_assert_equal_i(2, ct);
ct = 0; ct = 0;
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_stop_cb, &ct)); -123, git_tree_walk(tree, GIT_TREEWALK_POST, treewalk_stop_cb, &ct));
cl_assert_equal_i(2, ct); cl_assert_equal_i(2, ct);
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_tree_walk( -100, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_stop_immediately_cb, NULL)); tree, GIT_TREEWALK_PRE, treewalk_stop_immediately_cb, NULL));
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_tree_walk( -100, git_tree_walk(
tree, GIT_TREEWALK_POST, treewalk_stop_immediately_cb, NULL)); tree, GIT_TREEWALK_POST, treewalk_stop_immediately_cb, NULL));
git_tree_free(tree); git_tree_free(tree);
@ -152,7 +152,7 @@ void test_object_tree_walk__2(void)
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.stop = "3.txt"; data.stop = "3.txt";
cl_assert_equal_i(GIT_EUSER, git_tree_walk( cl_assert_equal_i(-1, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data)); tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(3, data.files); cl_assert_equal_i(3, data.files);
cl_assert_equal_i(2, data.dirs); cl_assert_equal_i(2, data.dirs);
@ -168,7 +168,7 @@ void test_object_tree_walk__2(void)
memset(&data, 0, sizeof(data)); memset(&data, 0, sizeof(data));
data.stop = "new.txt"; data.stop = "new.txt";
cl_assert_equal_i(GIT_EUSER, git_tree_walk( cl_assert_equal_i(-1, git_tree_walk(
tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data)); tree, GIT_TREEWALK_PRE, treewalk_skip_de_cb, &data));
cl_assert_equal_i(7, data.files); cl_assert_equal_i(7, data.files);
cl_assert_equal_i(4, data.dirs); cl_assert_equal_i(4, data.dirs);

View File

@ -5,7 +5,6 @@
static git_odb *_odb; static git_odb *_odb;
static git_repository *_repo; static git_repository *_repo;
static int nobj;
void test_odb_foreach__cleanup(void) void test_odb_foreach__cleanup(void)
{ {
@ -18,10 +17,10 @@ void test_odb_foreach__cleanup(void)
static int foreach_cb(const git_oid *oid, void *data) static int foreach_cb(const git_oid *oid, void *data)
{ {
GIT_UNUSED(data); int *nobj = data;
GIT_UNUSED(oid); (*nobj)++;
nobj++; GIT_UNUSED(oid);
return 0; return 0;
} }
@ -38,43 +37,46 @@ static int foreach_cb(const git_oid *oid, void *data)
*/ */
void test_odb_foreach__foreach(void) void test_odb_foreach__foreach(void)
{ {
int nobj = 0;
cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
git_repository_odb(&_odb, _repo); git_repository_odb(&_odb, _repo);
cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL)); cl_git_pass(git_odb_foreach(_odb, foreach_cb, &nobj));
cl_assert_equal_i(47 + 1640, nobj); /* count + in-pack */ cl_assert_equal_i(47 + 1640, nobj); /* count + in-pack */
} }
void test_odb_foreach__one_pack(void) void test_odb_foreach__one_pack(void)
{ {
git_odb_backend *backend = NULL; git_odb_backend *backend = NULL;
int nobj = 0;
cl_git_pass(git_odb_new(&_odb)); cl_git_pass(git_odb_new(&_odb));
cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx"))); cl_git_pass(git_odb_backend_one_pack(&backend, cl_fixture("testrepo.git/objects/pack/pack-a81e489679b7d3418f9ab594bda8ceb37dd4c695.idx")));
cl_git_pass(git_odb_add_backend(_odb, backend, 1)); cl_git_pass(git_odb_add_backend(_odb, backend, 1));
_repo = NULL; _repo = NULL;
nobj = 0; cl_git_pass(git_odb_foreach(_odb, foreach_cb, &nobj));
cl_git_pass(git_odb_foreach(_odb, foreach_cb, NULL));
cl_assert(nobj == 1628); cl_assert(nobj == 1628);
} }
static int foreach_stop_cb(const git_oid *oid, void *data) static int foreach_stop_cb(const git_oid *oid, void *data)
{ {
GIT_UNUSED(data); int *nobj = data;
(*nobj)++;
GIT_UNUSED(oid); GIT_UNUSED(oid);
nobj++; return (*nobj == 1000) ? -321 : 0;
return (nobj == 1000);
} }
void test_odb_foreach__interrupt_foreach(void) void test_odb_foreach__interrupt_foreach(void)
{ {
nobj = 0; int nobj = 0;
cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git"))); cl_git_pass(git_repository_open(&_repo, cl_fixture("testrepo.git")));
git_repository_odb(&_odb, _repo); git_repository_odb(&_odb, _repo);
cl_assert_equal_i(GIT_EUSER, git_odb_foreach(_odb, foreach_stop_cb, NULL)); cl_assert_equal_i(-321, git_odb_foreach(_odb, foreach_stop_cb, &nobj));
cl_assert(nobj == 1000); cl_assert(nobj == 1000);
} }

View File

@ -273,7 +273,7 @@ static int cancel_at_half(const git_transfer_progress *stats, void *payload)
GIT_UNUSED(payload); GIT_UNUSED(payload);
if (stats->received_objects > (stats->total_objects/2)) if (stats->received_objects > (stats->total_objects/2))
return 1; return 4321;
return 0; return 0;
} }
@ -281,7 +281,8 @@ void test_online_clone__can_cancel(void)
{ {
g_options.remote_callbacks.transfer_progress = cancel_at_half; g_options.remote_callbacks.transfer_progress = cancel_at_half;
cl_git_fail_with(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options), GIT_EUSER); cl_git_fail_with(
git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options), 4321);
} }

View File

@ -129,7 +129,7 @@ static int cancel_at_half(const git_transfer_progress *stats, void *payload)
GIT_UNUSED(payload); GIT_UNUSED(payload);
if (stats->received_objects > (stats->total_objects/2)) if (stats->received_objects > (stats->total_objects/2))
return -1; return -4321;
return 0; return 0;
} }
@ -147,7 +147,7 @@ void test_online_fetch__can_cancel(void)
git_remote_set_callbacks(remote, &callbacks); git_remote_set_callbacks(remote, &callbacks);
cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH)); cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
cl_git_fail_with(git_remote_download(remote), GIT_EUSER); cl_git_fail_with(git_remote_download(remote), -4321);
git_remote_disconnect(remote); git_remote_disconnect(remote);
git_remote_free(remote); git_remote_free(remote);
} }

View File

@ -81,14 +81,14 @@ static int interrupt_cb(const char *reference_name, void *payload)
(*count)++; (*count)++;
return (*count == 11); return (*count == 11) ? -1000 : 0;
} }
void test_refs_foreachglob__can_cancel(void) void test_refs_foreachglob__can_cancel(void)
{ {
int count = 0; int count = 0;
cl_assert_equal_i(GIT_EUSER, git_reference_foreach_glob( cl_assert_equal_i(-1000, git_reference_foreach_glob(
repo, "*", interrupt_cb, &count) ); repo, "*", interrupt_cb, &count) );
cl_assert_equal_i(11, count); cl_assert_equal_i(11, count);

View File

@ -552,7 +552,7 @@ static int cb_status__interrupt(const char *p, unsigned int s, void *payload)
(*count)++; (*count)++;
return (*count == 8); return (*count == 8) ? -111 : 0;
} }
void test_status_worktree__interruptable_foreach(void) void test_status_worktree__interruptable_foreach(void)
@ -561,7 +561,7 @@ void test_status_worktree__interruptable_foreach(void)
git_repository *repo = cl_git_sandbox_init("status"); git_repository *repo = cl_git_sandbox_init("status");
cl_assert_equal_i( cl_assert_equal_i(
GIT_EUSER, git_status_foreach(repo, cb_status__interrupt, &count) -111, git_status_foreach(repo, cb_status__interrupt, &count)
); );
cl_assert_equal_i(8, count); cl_assert_equal_i(8, count);