镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 53 additions & 9 deletions ext/rugged/rugged_repo.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,42 @@ struct rugged_remote_cb_payload
static int rugged__remote_transfer_progress_cb(const git_transfer_progress *stats, void *payload)
{
struct rugged_remote_cb_payload *remote_payload = payload;
VALUE args = rb_ary_new2(4);
VALUE args = rb_ary_new2(5);

rb_ary_push(args, remote_payload->transfer_progress);
rb_ary_push(args, UINT2NUM(stats->total_objects));
rb_ary_push(args, UINT2NUM(stats->indexed_objects));
rb_ary_push(args, UINT2NUM(stats->received_objects));
rb_ary_push(args, INT2FIX(stats->received_bytes));

rb_protect(rugged__block_yield_splat, args, &remote_payload->exception);

return remote_payload->exception ? GIT_ERROR : GIT_OK;
}

static int rugged__remote_progress_cb(const char *str, int len, void *payload)
{
struct rugged_remote_cb_payload *remote_payload = payload;
VALUE args = rb_ary_new2(2);

rb_ary_push(args, remote_payload->progress);
rb_ary_push(args, rb_str_new(str, len));

rb_protect(rugged__block_yield_splat, args, &remote_payload->exception);

return remote_payload->exception ? GIT_ERROR : GIT_OK;
}

static int rugged__remote_update_tips_cb(const char *refname, const git_oid *a, const git_oid *b, void *payload)
{
struct rugged_remote_cb_payload *remote_payload = payload;
VALUE args = rb_ary_new2(4);

rb_ary_push(args, remote_payload->update_tips);
rb_ary_push(args, rb_str_new2(refname));
rb_ary_push(args, rugged_create_oid(a));
rb_ary_push(args, rugged_create_oid(b));

rb_protect(rugged__block_yield_splat, args, &remote_payload->exception);

return remote_payload->exception ? GIT_ERROR : GIT_OK;
Expand All @@ -340,6 +370,15 @@ static void parse_clone_options(git_clone_options *ret, VALUE rb_options_hash, s
git_remote_callbacks remote_callbacks = GIT_REMOTE_CALLBACKS_INIT;
VALUE cb;

cb = rb_hash_aref(val, CSTR2SYM("progress"));
if (RTEST(cb)) {
if (!rb_respond_to(cb, rb_intern("call"))) {
rb_raise(rb_eArgError, "Expected a Proc or an object that responds to call (:progress).");
}
remote_payload->progress = cb;
remote_callbacks.progress = rugged__remote_progress_cb;
}

cb = rb_hash_aref(val, CSTR2SYM("transfer_progress"));
if (RTEST(cb)) {
if (!rb_respond_to(cb, rb_intern("call"))) {
Expand All @@ -350,6 +389,16 @@ static void parse_clone_options(git_clone_options *ret, VALUE rb_options_hash, s
remote_callbacks.transfer_progress = rugged__remote_transfer_progress_cb;
}

cb = rb_hash_aref(val, CSTR2SYM("update_tips"));
if (RTEST(cb)) {
if (!rb_respond_to(cb, rb_intern("call"))) {
rb_raise(rb_eArgError, "Expected a Proc or an object that responds to call (:update_tips).");
}

remote_payload->update_tips = cb;
remote_callbacks.update_tips = rugged__remote_update_tips_cb;
}

remote_callbacks.payload = remote_payload;

ret->remote_callbacks = remote_callbacks;
Expand Down Expand Up @@ -383,20 +432,15 @@ static void parse_clone_options(git_clone_options *ret, VALUE rb_options_hash, s
* the clone operation. Possible callbacks are:
*
* :progress ::
* Not yet implemented.
*
* :completion ::
* Not yet implemented.
*
* :credentials ::
* Not yet implemented.
* A callback that will be executed with the textual progress from the remote.
*
* :transfer_progress ::
* A callback that will be executed to report clone progress information. It will be passed
* the amount of +total_objects+, +indexed_objects+, +received_objects+ and +received_bytes+.
*
* :update_tips ::
* Not yet implemented.
* A callback that is called each time a reference is updated locally. It is passed the fully
* qualified +refname+, the previous +oid+, and the new oid.
*
* Example:
*
Expand Down
25 changes: 24 additions & 1 deletion test/repo_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ def test_clone_bare
end
end

def test_clone_with_progress
def test_clone_with_transfer_progress_callback
total_objects = indexed_objects = received_objects = received_bytes = nil
callsback = 0
repo = Rugged::Repository.clone_at(@source_path, @tmppath,{
Expand All @@ -416,6 +416,29 @@ def test_clone_with_progress
assert_equal 1563, received_bytes
end

def test_clone_with_update_tips_callback
calls = 0
updated_tips = {}

repo = Rugged::Repository.clone_at(@source_path, @tmppath, {
callbacks: {
update_tips: lambda { |refname, a, b|
calls += 1
updated_tips[refname] = [a, b]
}
}
})
repo.close

assert_equal 4, calls
assert_equal({
"refs/remotes/origin/master" => ["0000000000000000000000000000000000000000", "36060c58702ed4c2a40832c51758d5344201d89a"],
"refs/remotes/origin/packed" => ["0000000000000000000000000000000000000000", "41bc8c69075bbdb46c5c6f0566cc8cc5b46e8bd9"],
"refs/tags/v0.9" => ["0000000000000000000000000000000000000000", "5b5b025afb0b4c913b4c338a42934a3863bf3644"],
"refs/tags/v1.0" => ["0000000000000000000000000000000000000000", "0c37a5391bbff43c37f0d0371823a5509eed5b1d"],
}, updated_tips)
end

def test_clone_quits_on_error
begin
Rugged::Repository.clone_at(@source_path, @tmppath, :callbacks => {
Expand Down