summaryrefslogtreecommitdiff
path: root/src/diff.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-05-31 12:18:43 -0700
committerRussell Belfer <rb@github.com>2013-05-31 12:18:43 -0700
commitcee695ae6b9a9f586d32d0b9460a358bfdc4fe1b (patch)
tree33fa5cceec1bbb24ab919ccb21732cd1487d4fec /src/diff.c
parent1ed356dcfef449313bac3ce795f26d19423c744c (diff)
downloadlibgit2-cee695ae6b9a9f586d32d0b9460a358bfdc4fe1b.tar.gz
Make iterators use GIT_ITEROVER & smart advance
1. internal iterators now return GIT_ITEROVER when you go past the last item in the iteration. 2. git_iterator_advance will "advance" to the first item in the iteration if it is called immediately after creating the iterator, which allows a simpler idiom for basic iteration. 3. if git_iterator_advance encounters an error reading data (e.g. a missing tree or an unreadable file), it returns the error but also attempts to advance past the invalid data to prevent an infinite loop. Updated all tests and internal usage of iterators to account for these new behaviors.
Diffstat (limited to 'src/diff.c')
-rw-r--r--src/diff.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/diff.c b/src/diff.c
index b96ff4705..05ef4f16b 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -796,6 +796,9 @@ static int diff_scan_inside_untracked_dir(
done:
git_buf_free(&base);
+ if (error == GIT_ITEROVER)
+ error = 0;
+
return error;
}
@@ -981,8 +984,11 @@ static int handle_matched_item(
{
int error = 0;
- if (!(error = maybe_modified(diff, info)) &&
- !(error = git_iterator_advance(&info->oitem, info->old_iter)))
+ if ((error = maybe_modified(diff, info)) < 0)
+ return error;
+
+ if (!(error = git_iterator_advance(&info->oitem, info->old_iter)) ||
+ error == GIT_ITEROVER)
error = git_iterator_advance(&info->nitem, info->new_iter);
return error;
@@ -1011,15 +1017,22 @@ int git_diff__from_iterators(
/* make iterators have matching icase behavior */
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_DELTAS_ARE_ICASE)) {
- if (!(error = git_iterator_set_ignore_case(old_iter, true)))
- error = git_iterator_set_ignore_case(new_iter, true);
+ if ((error = git_iterator_set_ignore_case(old_iter, true)) < 0 ||
+ (error = git_iterator_set_ignore_case(new_iter, true)) < 0)
+ goto cleanup;
}
/* finish initialization */
- if (!error &&
- !(error = diff_list_apply_options(diff, opts)) &&
- !(error = git_iterator_current(&info.oitem, old_iter)))
- error = git_iterator_current(&info.nitem, new_iter);
+ if ((error = diff_list_apply_options(diff, opts)) < 0)
+ goto cleanup;
+
+ if ((error = git_iterator_current(&info.oitem, old_iter)) < 0 &&
+ error != GIT_ITEROVER)
+ goto cleanup;
+ if ((error = git_iterator_current(&info.nitem, new_iter)) < 0 &&
+ error != GIT_ITEROVER)
+ goto cleanup;
+ error = 0;
/* run iterators building diffs */
while (!error && (info.oitem || info.nitem)) {
@@ -1041,8 +1054,13 @@ int git_diff__from_iterators(
*/
else
error = handle_matched_item(diff, &info);
+
+ /* because we are iterating over two lists, ignore ITEROVER */
+ if (error == GIT_ITEROVER)
+ error = 0;
}
+cleanup:
if (!error)
*diff_ptr = diff;
else