summaryrefslogtreecommitdiff
path: root/src/status.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-12-03 16:45:39 -0800
committerRussell Belfer <rb@github.com>2013-12-11 10:57:49 -0800
commit96869a4edb2872934e0e167a726ab240f4270fea (patch)
tree2d770414acef2d1d45a609e004c0aa6fa56d06d7 /src/status.c
parent9f77b3f6f5ce6944ec49dfc666ef6b8df0af0c6b (diff)
downloadlibgit2-96869a4edb2872934e0e167a726ab240f4270fea.tar.gz
Improve GIT_EUSER handling
This adds giterr_user_cancel to return GIT_EUSER and clear any error message that is sitting around. As a result of using that in places, we need to be more thorough with capturing errors that happen inside a callback when used internally. To help with that, this also adds giterr_capture and giterr_restore so that when we internally use a foreach-type function that clears errors and converts them to GIT_EUSER, it is easier to restore not just the return value, but the actual error message text.
Diffstat (limited to 'src/status.c')
-rw-r--r--src/status.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/status.c b/src/status.c
index 07fdcb5c3..fb99fb4e4 100644
--- a/src/status.c
+++ b/src/status.c
@@ -152,25 +152,32 @@ static git_status_t status_compute(
return st;
}
+struct status_data {
+ git_status_list *status;
+ git_error_state err;
+};
+
static int status_collect(
git_diff_delta *head2idx,
git_diff_delta *idx2wd,
void *payload)
{
- git_status_list *status = payload;
+ struct status_data *data = payload;
git_status_entry *status_entry;
- if (!status_is_included(status, head2idx, idx2wd))
+ if (!status_is_included(data->status, head2idx, idx2wd))
return 0;
status_entry = git__malloc(sizeof(git_status_entry));
- GITERR_CHECK_ALLOC(status_entry);
+ if (!status_entry)
+ return giterr_capture(&data->err, -1);
- status_entry->status = status_compute(status, head2idx, idx2wd);
+ status_entry->status = status_compute(data->status, head2idx, idx2wd);
status_entry->head_to_index = head2idx;
status_entry->index_to_workdir = idx2wd;
- return git_vector_insert(&status->paired, status_entry);
+ return giterr_capture(
+ &data->err, git_vector_insert(&data->status->paired, status_entry));
}
GIT_INLINE(int) status_entry_cmp_base(
@@ -314,9 +321,18 @@ int git_status_list_new(
goto done;
}
- if ((error = git_diff__paired_foreach(
- status->head2idx, status->idx2wd, status_collect, status)) < 0)
- goto done;
+ {
+ struct status_data data = { 0 };
+ data.status = status;
+
+ 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)
git_vector_set_cmp(&status->paired, status_entry_cmp);