Skip to content

Commit 35102c0

Browse files
authored
Merge pull request #787 from libgit2/cmn/status-iter-exception
repo: catch exceptions when iterating through status
2 parents 2e2e1ea + f333dfc commit 35102c0

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

ext/rugged/rugged_repo.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,15 +1502,6 @@ static VALUE flags_to_rb(unsigned int flags)
15021502
return rb_flags;
15031503
}
15041504

1505-
static int rugged__status_cb(const char *path, unsigned int flags, void *payload)
1506-
{
1507-
rb_funcall((VALUE)payload, rb_intern("call"), 2,
1508-
rb_str_new_utf8(path), flags_to_rb(flags)
1509-
);
1510-
1511-
return GIT_OK;
1512-
}
1513-
15141505
static VALUE rb_git_repo_file_status(VALUE self, VALUE rb_path)
15151506
{
15161507
unsigned int flags;
@@ -1527,8 +1518,10 @@ static VALUE rb_git_repo_file_status(VALUE self, VALUE rb_path)
15271518

15281519
static VALUE rb_git_repo_file_each_status(VALUE self)
15291520
{
1530-
int error;
1521+
int error, exception;
1522+
size_t i, nentries;
15311523
git_repository *repo;
1524+
git_status_list *list;
15321525

15331526
Data_Get_Struct(self, git_repository, repo);
15341527

@@ -1537,13 +1530,30 @@ static VALUE rb_git_repo_file_each_status(VALUE self)
15371530
"A block was expected for iterating through "
15381531
"the repository contents.");
15391532

1540-
error = git_status_foreach(
1541-
repo,
1542-
&rugged__status_cb,
1543-
(void *)rb_block_proc()
1544-
);
1545-
1533+
error = git_status_list_new(&list, repo, NULL);
15461534
rugged_exception_check(error);
1535+
1536+
nentries = git_status_list_entrycount(list);
1537+
for (i = 0; i < nentries; i++) {
1538+
const git_status_entry *entry;
1539+
const char *path;
1540+
VALUE args;
1541+
1542+
entry = git_status_byindex(list, i);
1543+
1544+
path = entry->head_to_index ?
1545+
entry->head_to_index->old_file.path :
1546+
entry->index_to_workdir->old_file.path;
1547+
args = rb_ary_new3(2, rb_str_new_utf8(path), flags_to_rb(entry->status));
1548+
rb_protect(rb_yield, args, &exception);
1549+
if (exception != 0)
1550+
break;
1551+
}
1552+
git_status_list_free(list);
1553+
1554+
if (exception != 0)
1555+
rb_jump_tag(exception);
1556+
15471557
return Qnil;
15481558
}
15491559

test/status_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,26 @@ def setup
3333
@repo = FixtureRepo.from_libgit2 "status"
3434
end
3535

36+
class TestException < RuntimeError
37+
end
38+
39+
def test_status_block_raises
40+
assert_raises(TestException) do
41+
@repo.status do |file, status|
42+
raise TestException, "wow"
43+
end
44+
end
45+
end
46+
47+
def test_status_block_breaks
48+
yielded = 0
49+
@repo.status do |file, status|
50+
yielded += 1
51+
break
52+
end
53+
assert_equal 1, yielded
54+
end
55+
3656
def test_status_with_callback
3757
actual_statuses = {}
3858
@repo.status do |file, status|

0 commit comments

Comments
 (0)