Commit 530555f3 authored by tyler wanek's avatar tyler wanek

implement unsafe git_remote_ls feature

parent 443ed333
......@@ -1805,6 +1805,9 @@
}
},
"remote": {
"dependencies": [
"../include/remote_head.h"
],
"cType": "git_remote",
"selfFreeing": true,
"functions": {
......@@ -1969,9 +1972,6 @@
}
}
},
"remote_head": {
"ignore": true
},
"repository": {
"dependencies": [
"git2/sys/repository.h"
......
......@@ -126,6 +126,40 @@
},
"group": "rebase"
},
"git_remote_reference_list": {
"args": [
{
"name": "out",
"type": "std::vector<git_remote_head*> *"
},
{
"name": "callbacks",
"type": "git_remote_callbacks *"
},
{
"name": "proxy_opts",
"type": "git_proxy_options *"
},
{
"name": "custom_headers",
"type": "git_strarray *"
},
{
"name": "remote",
"type": "git_remote *"
}
],
"type": "function",
"isManual": true,
"cFile": "generate/templates/manual/remote/ls.cc",
"isAsync": true,
"isPrototypeMethod": true,
"group": "remote",
"return": {
"type": "int",
"isErrorCode": true
}
},
"git_reset": {
"type": "function",
"file": "reset.h",
......@@ -277,6 +311,12 @@
"git_reflog_entry_message"
]
],
[
"remote",
[
"git_remote_reference_list"
]
],
[
"revwalk",
[
......@@ -614,6 +654,39 @@
}
}
],
[
"git_remote_head",
{
"types": "struct",
"fields": [
{
"type": "int",
"name": "local"
},
{
"type": "git_oid",
"name": "oid"
},
{
"type": "git_oid",
"name": "loid"
},
{
"type": "char *",
"name": "name"
},
{
"type": "char *",
"name": "symref_target"
}
],
"used": {
"needs": [
"git_remote_reference_list"
]
}
}
],
[
"git_time_t",
{
......
......@@ -14,6 +14,8 @@ const git_index_time *git_index_time_dup(const git_index_time *arg);
const git_time *git_time_dup(const git_time *arg);
const git_diff_delta *git_diff_delta_dup(const git_diff_delta *arg);
const git_diff_file *git_diff_file_dup(const git_diff_file *arg);
git_remote_head *git_remote_head_dup(const git_remote_head *src);
void git_time_dup(git_time **out, const git_time *arg);
void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_progress *arg);
......
NAN_METHOD(GitRemote::ReferenceList)
{
if (info.Length() == 0 || !info[0]->IsObject()) {
return Nan::ThrowError("RemoteCallbacks callbacks is required.");
}
if (info.Length() == 1 || !info[1]->IsObject()) {
return Nan::ThrowError("ProxyOptions proxy_opts is required.");
}
if (info.Length() == 2 || !(Nan::To<bool>(info[2]).FromJust())) {
return Nan::ThrowError("Array, String Object, or string custom_headers is required.");
}
if (info.Length() == 3 || !info[3]->IsFunction()) {
return Nan::ThrowError("Callback is required and must be a Function.");
}
ReferenceListBaton* baton = new ReferenceListBaton;
baton->error_code = GIT_OK;
baton->error = NULL;
baton->out = new std::vector<git_remote_head*>;
baton->remote = Nan::ObjectWrap::Unwrap<GitRemote>(info.This())->GetValue();
baton->callbacks = Nan::ObjectWrap::Unwrap<GitRemoteCallbacks>(info[0]->ToObject())->GetValue();
baton->proxy_opts = Nan::ObjectWrap::Unwrap<GitProxyOptions>(info[1]->ToObject())->GetValue();
baton->custom_headers = StrArrayConverter::Convert(info[2]);
Nan::Callback *callback = new Nan::Callback(Local<Function>::Cast(info[1]));
ReferenceListWorker *worker = new ReferenceListWorker(baton, callback);
worker->SaveToPersistent("remote", info.This());
if (!info[1]->IsUndefined() && !info[0]->IsNull())
worker->SaveToPersistent("callbacks", info[0]->ToObject());
if (!info[2]->IsUndefined() && !info[1]->IsNull())
worker->SaveToPersistent("proxy_opts", info[1]->ToObject());
if (!info[3]->IsUndefined() && !info[2]->IsNull())
worker->SaveToPersistent("custom_headers", info[2]->ToObject());
Nan::AsyncQueueWorker(worker);
return;
}
void GitRemote::ReferenceListWorker::Execute()
{
giterr_clear();
baton->error_code = git_remote_connect(
baton->remote,
GIT_DIRECTION_FETCH,
baton->callbacks,
baton->proxy_opts,
baton->custom_headers
);
if (baton->error_code != GIT_OK) {
baton->error = git_error_dup(giterr_last());
delete baton->out;
baton->out = NULL;
return;
}
const git_remote_head **remote_heads;
size_t num_remote_heads;
baton->error_code = git_remote_ls(
&remote_heads,
&num_remote_heads,
baton->remote
);
if (baton->error_code != GIT_OK) {
baton->error = git_error_dup(giterr_last());
delete baton->out;
baton->out = NULL;
return;
}
baton->out->reserve(num_remote_heads);
for (unsigned int head_index = 0; head_index < num_remote_heads; ++head_index) {
git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]);
baton->out->push_back(remote_head);
}
git_remote_disconnect(baton->remote);
}
void GitRemote::ReferenceListWorker::HandleOKCallback()
{
if (baton->out != NULL)
{
unsigned int size = baton->out->size();
Local<Array> result = Nan::New<Array>(size);
for (unsigned int i = 0; i < size; i++) {
Nan::Set(result, Nan::New<Number>(i), GitRemoteHead::New(baton->out->at(i), true));
}
delete baton->out;
Local<v8::Value> argv[2] = {
Nan::Null(),
result
};
callback->Call(2, argv);
}
else if (baton->error)
{
Local<v8::Value> argv[1] = {
Nan::Error(baton->error->message)
};
callback->Call(1, argv);
if (baton->error->message)
{
free((void *)baton->error->message);
}
free((void *)baton->error);
}
else if (baton->error_code < 0)
{
Local<v8::Object> err = Nan::Error("Method next has thrown an error.")->ToObject();
err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Local<v8::Value> argv[1] = {
err
};
callback->Call(1, argv);
}
else
{
callback->Call(0, NULL);
}
}
......@@ -20,3 +20,13 @@ void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_p
*out = (git_transfer_progress *)malloc(sizeof(git_transfer_progress));
memcpy(*out, arg, sizeof(git_transfer_progress));
}
git_remote_head *git_remote_head_dup(const git_remote_head *src) {
git_remote_head *dest = (git_remote_head *)malloc(sizeof(git_remote_head));
dest->local = src->local;
git_oid_cpy(&dest->oid, &src->oid);
git_oid_cpy(&dest->loid, &src->loid);
dest->name = strdup(src->name);
dest->symref_target = strdup(src->symref_target);
return dest;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment