From 985a437b89d85c7cfff1ade193ac972e7779e3b3 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Fri, 8 Mar 2013 00:31:02 +1300 Subject: [PATCH 001/120] Updated initialization --- include/oid.h | 4 +++- src/oid.cc | 28 ++++++++++++++-------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/include/oid.h b/include/oid.h index da782eddb..cfab6db64 100755 --- a/include/oid.h +++ b/include/oid.h @@ -15,7 +15,9 @@ using namespace v8; class GitOid : public ObjectWrap { public: - static Persistent constructor_template; + + static Persistent constructor_template; + static void Initialize (Handle target); Handle WrapObj(Local obj); git_oid GetValue(); diff --git a/src/oid.cc b/src/oid.cc index 064457918..72cea524e 100755 --- a/src/oid.cc +++ b/src/oid.cc @@ -15,22 +15,22 @@ using namespace node; void GitOid::Initialize(Handle target) { HandleScope scope; - Local t = FunctionTemplate::New(New); + Local tpl = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Oid")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("Oid")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "mkstr", Mkstr); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "mkraw", Mkraw); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "fmt", Fmt); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "pathFmt", PathFmt); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "allocFmt", AllocFmt); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "toString", ToString); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "cpy", Cpy); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "cmp", Cmp); + NODE_SET_PROTOTYPE_METHOD(tpl, "mkstr", Mkstr); + NODE_SET_PROTOTYPE_METHOD(tpl, "mkraw", Mkraw); + NODE_SET_PROTOTYPE_METHOD(tpl, "fmt", Fmt); + NODE_SET_PROTOTYPE_METHOD(tpl, "pathFmt", PathFmt); + NODE_SET_PROTOTYPE_METHOD(tpl, "allocFmt", AllocFmt); + NODE_SET_PROTOTYPE_METHOD(tpl, "toString", ToString); + NODE_SET_PROTOTYPE_METHOD(tpl, "cpy", Cpy); + NODE_SET_PROTOTYPE_METHOD(tpl, "cmp", Cmp); - target->Set(String::NewSymbol("Oid"), constructor_template->GetFunction()); + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("Oid"), constructor_template); } git_oid GitOid::GetValue() { @@ -195,4 +195,4 @@ Handle GitOid::Cmp(const Arguments& args) { return scope.Close( Integer::New(cmp) ); } -Persistent GitOid::constructor_template; +Persistent GitOid::constructor_template; From ae6d06d09b6c83ad4ef035235e7eb9e96a1e6c68 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Fri, 8 Mar 2013 01:13:28 +1300 Subject: [PATCH 002/120] Added FetchDetails async methods. Commented sync getters for now, pending future deletion. Updated initializer --- include/commit.h | 61 +++++++++++----- lib/commit.js | 133 +++++++++++++--------------------- src/commit.cc | 184 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 246 insertions(+), 132 deletions(-) diff --git a/include/commit.h b/include/commit.h index ac63ae59c..803165640 100755 --- a/include/commit.h +++ b/include/commit.h @@ -8,6 +8,7 @@ #include #include +#include #include "../vendor/libgit2/include/git2.h" @@ -40,16 +41,17 @@ class GitCommit : public ObjectWrap { void SetValue(git_commit* commit); int Lookup(git_repository* repo, git_oid* oid); void Close(); - const git_oid* Id(); - const char* MessageShort(); - const char* Message(); - time_t Time(); - int TimeOffset(); - const git_signature* Committer(); - const git_signature* Author(); - int Tree(git_tree** tree); - unsigned int ParentCount(); - int Parent(git_commit** commit, int pos); + + // const git_oid* Id(); + // const char* MessageShort(); + // const char* Message(); + // time_t Time(); + // int TimeOffset(); + // const git_signature* Committer(); + // const git_signature* Author(); + // int Tree(git_tree** tree); + // unsigned int ParentCount(); + // int Parent(git_commit** commit, int pos); protected: GitCommit() {} @@ -58,6 +60,10 @@ class GitCommit : public ObjectWrap { static Handle New(const Arguments& args); static Handle NewInstance(); + static Handle FetchDetails(const Arguments& args); + static void FetchDetailsWork(uv_work_t *req); + static void FetchDetailsAfterWork(uv_work_t *req); + static Handle Lookup(const Arguments& args); static void LookupWork(uv_work_t *req); static void LookupAfterWork(uv_work_t *req); @@ -95,10 +101,32 @@ class GitCommit : public ObjectWrap { }; /** - * Struct: parent_request - * Contains references to the current commit, parent commit (output) - * parent commit's index, also contains references to an error code post - * lookup, and a callback function to execute. + * Struct containing details for a commit. + */ + struct FetchDetailsBaton { + uv_work_t request; + int errorCode; + const char* errorMessage; + + git_commit* rawCommit; + + const git_oid *oid; + char sha[GIT_OID_HEXSZ + 1]; + const char* message; + time_t time; + int timeOffset; + const git_signature* committer; + const git_signature* author; + unsigned int parentCount; + std::vector parentShas; + + Persistent callback; + }; + + /** + * Contains references to the current commit, parent commit (output) + * parent commit's index, also contains references to an error code post + * lookup, and a callback function to execute. */ struct ParentBaton { uv_work_t request; @@ -106,8 +134,9 @@ class GitCommit : public ObjectWrap { const char* errorMessage; int index; - GitCommit *commit; - git_commit *rawParentCommit; + GitCommit* commit; + git_commit* rawParentCommit; + Persistent callback; }; diff --git a/lib/commit.js b/lib/commit.js index 4d7efeb32..3831eac78 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -1,7 +1,13 @@ -var git = require( '../' ) - , events = require( 'events' ); - -var _Commit = function( obj ) { +var git = require( '../' ), + events = require( 'events' ); + +/** + * Convenience commit constructor. + * + * @param {RawCommit} obj + * @return {Commit} + */ +var _Commit = function(obj) { var self = { _cache: {} }; if( obj instanceof git.raw.Commit ) { @@ -11,80 +17,32 @@ var _Commit = function( obj ) { self.commit = new git.raw.Commit(); } - Object.defineProperty( self, 'id', { - get: function() { - var oid = new git.raw.Oid(); - self.commit.id( oid ); - - return oid; - }, - enumerable: true - }); - - Object.defineProperty(self, 'sha', { - get: function() { - var oid = new git.raw.Oid(); - self.commit.id(oid); - - return oid.toString(40); - }, - enumerable: true - }); - - Object.defineProperty( self, 'msg', { - get: function() { - return self.commit.messageShort(); - }, - enumerable: true - }); - - Object.defineProperty( self, 'message', { - get: function() { - return self.commit.message(); - }, - enumerable: true - }); - - Object.defineProperty( self, 'time', { - get: function() { - return new Date( self.commit.time() * 1000 ); - }, - enumerable: true - }); - - Object.defineProperty( self, 'offset', { - get: function() { - return self.commit.timeOffset(); - }, - enumerable: true - }); - - Object.defineProperty(self, 'parentCount', { - get: function() { - return self.commit.parentCount(); - }, - enumerable: true - }); - - Object.defineProperty( self, 'author', { - get: function() { - var sig = new git.raw.Sig(); - - self.commit.author( sig ); - - return git.sig( sig ); - }, - enumerable: true - }); + /** + * Fetch the commit's details asynchronously. + * + * @param {Function} callback + */ + self.fetchDetails = function(callback) { + var error = null; + self.commit.fetchDetails(function(errorCode, details) { + if (errorCode) { + error = git.error(errorCode); + } + if (details) { + // @todo add details to commit + } + callback(error); + }); + }; - self.lookup = function( repo, oid, callback ) { + self.lookup = function(repo, oid, callback) { self.repo = repo; - self.commit.lookup( repo, oid, function() { - var args = Array.prototype.slice.call( arguments ); - - args[0] = git.util().error( args[0] ); - - callback.apply( self, args.concat( self ) ); + self.commit.lookup(repo, oid, function() { + var args = Array.prototype.slice.call(arguments); + args[0] = git.util().error(args[0]); + self.fetchDetails(function(error) { + callback.apply(self, args.concat(self)); + }); }); }; @@ -100,7 +58,7 @@ var _Commit = function( obj ) { return git.tree( self.repo, tree ); }; - self.file = function( path ) { + self.file = function(path) { return self.tree().entry( path ); }; @@ -127,9 +85,7 @@ var _Commit = function( obj ) { }; /** - * Retrieve the commit's parent at the given position. - * - * @todo implement async + * Retrieve the commit's parent at the given position asynchronously. * * @param {Integer} position */ @@ -139,14 +95,25 @@ var _Commit = function( obj ) { var error = null; if (errorCode !== git.error.GIT_SUCCESS) { error = git.error(errorCode); + return callback(error, null); } - callback(error, new _Commit(parent)); + var parentCommit = new _Commit(parent); + parentCommit.fetchDetails(function(error) { + callback(error, parentCommit); + }); }); - }; + /** + * Retrieve the commit's parent at the given positino synchronously. + * + * @param {Integer} position + * @return {Commit} + */ self.parentSync = function(position) { - return new _Commit(self.commit.parentSync(position)); + var parent = new _Commit(self.commit.parentSync(position)); + parent.fetchDetailsSync(); + return parent; }; return self; diff --git a/src/commit.cc b/src/commit.cc index a91773de1..f08ef5950 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -18,6 +18,7 @@ #include "../include/commit.h" using namespace v8; +using namespace cvv8; using namespace node; void GitCommit::Initialize(Handle target) { @@ -30,16 +31,19 @@ void GitCommit::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup); NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); - NODE_SET_PROTOTYPE_METHOD(tpl, "id", Id); - NODE_SET_PROTOTYPE_METHOD(tpl, "messageShort", MessageShort); - NODE_SET_PROTOTYPE_METHOD(tpl, "message", Message); - NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); - NODE_SET_PROTOTYPE_METHOD(tpl, "timeOffset", TimeOffset); - NODE_SET_PROTOTYPE_METHOD(tpl, "author", Author); + + // NODE_SET_PROTOTYPE_METHOD(tpl, "id", Id); + // NODE_SET_PROTOTYPE_METHOD(tpl, "messageShort", MessageShort); + // NODE_SET_PROTOTYPE_METHOD(tpl, "message", Message); + // NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); + // NODE_SET_PROTOTYPE_METHOD(tpl, "timeOffset", TimeOffset); + // NODE_SET_PROTOTYPE_METHOD(tpl, "author", Author); + NODE_SET_PROTOTYPE_METHOD(tpl, "tree", Tree); NODE_SET_PROTOTYPE_METHOD(tpl, "parentCount", ParentCount); NODE_SET_PROTOTYPE_METHOD(tpl, "parent", Parent); NODE_SET_PROTOTYPE_METHOD(tpl, "parentSync", ParentSync); + NODE_SET_PROTOTYPE_METHOD(tpl, "fetchDetails", FetchDetails); constructor_template = Persistent::New(tpl->GetFunction()); target->Set(String::NewSymbol("Commit"), constructor_template); @@ -64,34 +68,34 @@ void GitCommit::Close() { this->commit = NULL; } -const git_oid* GitCommit::Id() { - return git_commit_id(this->commit); -} +// const git_oid* GitCommit::Id() { +// return git_commit_id(this->commit); +// } -const char* GitCommit::MessageShort() { - return ""; - //return git_commit_message_short(this->commit); -} +// const char* GitCommit::MessageShort() { +// return ""; +// //return git_commit_message_short(this->commit); +// } -const char* GitCommit::Message() { - return git_commit_message(this->commit); -} +// const char* GitCommit::Message() { +// return git_commit_message(this->commit); +// } -time_t GitCommit::Time() { - return git_commit_time(this->commit); -} +// time_t GitCommit::Time() { +// return git_commit_time(this->commit); +// } -int GitCommit::TimeOffset() { - return git_commit_time_offset(this->commit); -} +// int GitCommit::TimeOffset() { +// return git_commit_time_offset(this->commit); +// } -const git_signature* GitCommit::Committer() { - return git_commit_author(this->commit); -} +// const git_signature* GitCommit::Committer() { +// return git_commit_author(this->commit); +// } -const git_signature* GitCommit::Author() { - return git_commit_author(this->commit); -} +// const git_signature* GitCommit::Author() { +// return git_commit_author(this->commit); +// } int GitCommit::Tree(git_tree** tree) { return git_commit_tree(tree, this->commit); @@ -123,6 +127,122 @@ Handle GitCommit::NewInstance() { return scope.Close(instance); } +Handle GitCommit::FetchDetails(const Arguments& args) { + HandleScope scope; + + if(args.Length() == 0 || !args[0]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); + } + + FetchDetailsBaton* baton = new FetchDetailsBaton(); + baton->request.data = baton; + baton->rawCommit = ObjectWrap::Unwrap(args.This())->commit; + baton->callback = Persistent::New(Local::Cast(args[0])); + + uv_queue_work(uv_default_loop(), &baton->request, FetchDetailsWork, FetchDetailsAfterWork); + + return Undefined(); +} + +void GitCommit::FetchDetailsWork(uv_work_t *req) { + FetchDetailsBaton* baton = static_cast(req->data); + + baton->oid = git_commit_id(baton->rawCommit); + + baton->sha[GIT_OID_HEXSZ] = '\0'; + + git_oid_fmt(baton->sha, baton->oid); + + baton->message = git_commit_message(baton->rawCommit); + baton->time = git_commit_time(baton->rawCommit); + baton->timeOffset = git_commit_time_offset(baton->rawCommit); + baton->committer = git_commit_committer(baton->rawCommit); + baton->author = git_commit_author(baton->rawCommit); + baton->parentCount = git_commit_parentcount(baton->rawCommit); + + int parentCount = baton->parentCount; + while (parentCount > 0) { + int parentIndex = parentCount -1; + char sha[GIT_OID_HEXSZ + 1]; + sha[GIT_OID_HEXSZ] = '\0'; + const git_oid *parentOid = git_commit_parent_oid(baton->rawCommit, parentIndex); + git_oid_fmt(sha, parentOid); + baton->parentShas.push_back(sha); + parentCount--; + } +} + +void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { + HandleScope scope; + + FetchDetailsBaton* baton = static_cast(req->data); + delete req; + + if (baton->errorCode) { + Local argv[1] = { + Exception::Error(String::New(baton->errorMessage)) + }; + + TryCatch try_catch; + + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { + + Local details = Object::New(); + + Handle oid = GitOid::constructor_template->NewInstance(); + GitOid *oidInstance = ObjectWrap::Unwrap(oid); + oidInstance->SetValue(*const_cast(baton->oid)); + + details->Set(String::NewSymbol("id"), oid); + details->Set(String::NewSymbol("sha"), String::New(baton->sha)); + details->Set(String::NewSymbol("message"), cvv8::CastToJS(baton->message)); + details->Set(String::NewSymbol("time"), cvv8::CastToJS(baton->time)); + details->Set(String::NewSymbol("timeOffset"), cvv8::CastToJS(baton->timeOffset)); + + + Local committer = Object::New(); + committer->Set(String::NewSymbol("name"), cvv8::CastToJS(baton->committer->name)); + committer->Set(String::NewSymbol("email"), cvv8::CastToJS(baton->committer->email)); + + Local committerWhen = Object::New(); + committerWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(baton->committer->when.time)); + committerWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(baton->committer->when.offset)); + committer->Set(String::NewSymbol("when"), cvv8::CastToJS(committerWhen)); + + details->Set(String::NewSymbol("committer"), committer); + + Local author = Object::New(); + author->Set(String::NewSymbol("name"), cvv8::CastToJS(baton->author->name)); + author->Set(String::NewSymbol("email"), cvv8::CastToJS(baton->author->email)); + + Local authorWhen = Object::New(); + authorWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(baton->author->when.time)); + authorWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(baton->author->when.offset)); + author->Set(String::NewSymbol("when"), authorWhen); + + details->Set(String::NewSymbol("author"), author); + + details->Set(String::NewSymbol("parentCount"), cvv8::CastToJS(baton->parentCount)); + details->Set(String::NewSymbol("parentShas"), cvv8::CastToJS(baton->parentShas)); + + Handle argv[2] = { + Local::New(Null()), + details + }; + + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } +} + Handle GitCommit::Lookup(const Arguments& args) { HandleScope scope; @@ -155,7 +275,7 @@ Handle GitCommit::Lookup(const Arguments& args) { req->data = ar; uv_queue_work(uv_default_loop(), req, LookupWork, LookupAfterWork); - return scope.Close( Undefined() ); + return scope.Close(Undefined()); } void GitCommit::LookupWork(uv_work_t *req) { @@ -344,18 +464,16 @@ Handle GitCommit::Parent(const Arguments& args) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - Local callback = Local::Cast(args[1]); - ParentBaton* baton = new ParentBaton(); baton->request.data = baton; baton->commit = ObjectWrap::Unwrap(args.This()); baton->commit->Ref(); baton->index = args[0]->ToInteger()->Value(); - baton->callback = Persistent::New(callback); + baton->callback = Persistent::New(Local::Cast(args[1])); uv_queue_work(uv_default_loop(), &baton->request, ParentWork, ParentAfterWork); - return Undefined(); + return Undefined(); } void GitCommit::ParentWork(uv_work_t* req) { From 8560aed15e5350f690d2cc38bbc111a8d732f216 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 22:11:33 +1300 Subject: [PATCH 003/120] Updated example --- example/raw-commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/example/raw-commit.js b/example/raw-commit.js index bb0ff3986..07212061d 100644 --- a/example/raw-commit.js +++ b/example/raw-commit.js @@ -1,5 +1,5 @@ -var git = require( '../' ).raw - , path = require( 'path' ); +var git = require( '../' ).raw, + path = require( 'path' ); var repo = new git.Repo(); repo.open( path.resolve( '../.git' ), function() { From f72f01a8626735b2ac91716c1d8d4fbb6804b065 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 22:13:04 +1300 Subject: [PATCH 004/120] Removed sync lookup method --- include/commit.h | 1 - src/commit.cc | 6 ------ 2 files changed, 7 deletions(-) diff --git a/include/commit.h b/include/commit.h index 803165640..40e342597 100755 --- a/include/commit.h +++ b/include/commit.h @@ -39,7 +39,6 @@ class GitCommit : public ObjectWrap { git_commit* GetValue(); void SetValue(git_commit* commit); - int Lookup(git_repository* repo, git_oid* oid); void Close(); // const git_oid* Id(); diff --git a/src/commit.cc b/src/commit.cc index f08ef5950..e199f9cb4 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -57,12 +57,6 @@ void GitCommit::SetValue(git_commit* commit) { this->commit = commit; } -int GitCommit::Lookup(git_repository* repo, git_oid* oid) { - int err = git_commit_lookup(&this->commit, repo, oid); - - return err; -} - void GitCommit::Close() { git_commit_close(this->commit); this->commit = NULL; From 1bd8d8136f4fd8d8bda6c99a2183f68034868c71 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 22:14:30 +1300 Subject: [PATCH 005/120] Removed sync prototype methods --- src/commit.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index e199f9cb4..06622c5f9 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -32,13 +32,6 @@ void GitCommit::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup); NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); - // NODE_SET_PROTOTYPE_METHOD(tpl, "id", Id); - // NODE_SET_PROTOTYPE_METHOD(tpl, "messageShort", MessageShort); - // NODE_SET_PROTOTYPE_METHOD(tpl, "message", Message); - // NODE_SET_PROTOTYPE_METHOD(tpl, "time", Time); - // NODE_SET_PROTOTYPE_METHOD(tpl, "timeOffset", TimeOffset); - // NODE_SET_PROTOTYPE_METHOD(tpl, "author", Author); - NODE_SET_PROTOTYPE_METHOD(tpl, "tree", Tree); NODE_SET_PROTOTYPE_METHOD(tpl, "parentCount", ParentCount); NODE_SET_PROTOTYPE_METHOD(tpl, "parent", Parent); From 48e7f4af6646d1fa757e8d5ca1e7235ab79c7f57 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:38:49 +1300 Subject: [PATCH 006/120] Removed sync accessors --- include/commit.h | 13 ++---- src/commit.cc | 109 ----------------------------------------------- 2 files changed, 3 insertions(+), 119 deletions(-) diff --git a/include/commit.h b/include/commit.h index 40e342597..56c41cbcd 100755 --- a/include/commit.h +++ b/include/commit.h @@ -48,9 +48,9 @@ class GitCommit : public ObjectWrap { // int TimeOffset(); // const git_signature* Committer(); // const git_signature* Author(); - // int Tree(git_tree** tree); - // unsigned int ParentCount(); - // int Parent(git_commit** commit, int pos); + int Tree(git_tree** tree); + unsigned int ParentCount(); + int Parent(git_commit** commit, int pos); protected: GitCommit() {} @@ -68,13 +68,6 @@ class GitCommit : public ObjectWrap { static void LookupAfterWork(uv_work_t *req); static Handle Close(const Arguments& args); - static Handle Id(const Arguments& args); - static Handle MessageShort(const Arguments& args); - static Handle Message(const Arguments& args); - static Handle Time(const Arguments& args); - static Handle TimeOffset(const Arguments& args); - static Handle Committer(const Arguments& args); - static Handle Author(const Arguments& args); static Handle Tree(const Arguments& args); static void TreeWork(uv_work_t* req); diff --git a/src/commit.cc b/src/commit.cc index 06622c5f9..b96538247 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -55,35 +55,6 @@ void GitCommit::Close() { this->commit = NULL; } -// const git_oid* GitCommit::Id() { -// return git_commit_id(this->commit); -// } - -// const char* GitCommit::MessageShort() { -// return ""; -// //return git_commit_message_short(this->commit); -// } - -// const char* GitCommit::Message() { -// return git_commit_message(this->commit); -// } - -// time_t GitCommit::Time() { -// return git_commit_time(this->commit); -// } - -// int GitCommit::TimeOffset() { -// return git_commit_time_offset(this->commit); -// } - -// const git_signature* GitCommit::Committer() { -// return git_commit_author(this->commit); -// } - -// const git_signature* GitCommit::Author() { -// return git_commit_author(this->commit); -// } - int GitCommit::Tree(git_tree** tree) { return git_commit_tree(tree, this->commit); } @@ -305,86 +276,6 @@ Handle GitCommit::Close(const Arguments& args) { return scope.Close(Undefined()); } -Handle GitCommit::Id(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Oid is required and must be an Object."))); - } - - GitOid *oid = ObjectWrap::Unwrap(args[0]->ToObject()); - - oid->SetValue(*const_cast(commit->Id())); - - return scope.Close(Undefined()); -} - -Handle GitCommit::MessageShort(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - return scope.Close( String::New(commit->MessageShort()) ); -} - -Handle GitCommit::Message(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - return scope.Close(String::New(commit->Message())); -} - -Handle GitCommit::Time(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - return scope.Close( Integer::New(commit->Time()) ); -} - -Handle GitCommit::TimeOffset(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - return scope.Close( Integer::New(commit->TimeOffset()) ); -} - -Handle GitCommit::Committer(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Signature is required and must be an Object."))); - } - - GitSig *sig = ObjectWrap::Unwrap(args[0]->ToObject()); - - sig->SetValue(const_cast(commit->Committer())); - - return scope.Close( Undefined() ); -} - -Handle GitCommit::Author(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Signature is required and must be an Object."))); - } - - GitSig *sig = ObjectWrap::Unwrap(args[0]->ToObject()); - - sig->SetValue(const_cast(commit->Author())); - - return scope.Close( Undefined() ); -} - Handle GitCommit::Tree(const Arguments& args) { HandleScope scope; From b7f27c31fe2863698e0692eccc064829acd6162e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:43:03 +1300 Subject: [PATCH 007/120] Refactored lookup --- include/commit.h | 10 ++++--- src/commit.cc | 68 +++++++++++++++++++++++++++--------------------- 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/include/commit.h b/include/commit.h index 56c41cbcd..80a4f54d0 100755 --- a/include/commit.h +++ b/include/commit.h @@ -84,11 +84,15 @@ class GitCommit : public ObjectWrap { git_commit* commit; git_oid* oid; - struct lookup_request { - GitCommit* commit; + struct LookupBaton { + uv_work_t request; + int errorCode; + const char* errorMessage; + GitRepo* repo; GitOid* oid; - int err; + git_commit* rawCommit; + Persistent callback; }; diff --git a/src/commit.cc b/src/commit.cc index b96538247..356852c42 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -204,9 +204,6 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { Handle GitCommit::Lookup(const Arguments& args) { HandleScope scope; - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - Local callback; - if(args.Length() == 0 || !args[0]->IsObject()) { return ThrowException(Exception::Error(String::New("Repo is required and must be an Object."))); } @@ -219,52 +216,63 @@ Handle GitCommit::Lookup(const Arguments& args) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - callback = Local::Cast(args[2]); - - lookup_request *ar = new lookup_request(); - ar->commit = commit; - ar->repo = ObjectWrap::Unwrap(args[0]->ToObject()); - ar->oid = ObjectWrap::Unwrap(args[1]->ToObject()); - ar->callback = Persistent::New(callback); - - commit->Ref(); + LookupBaton *baton = new LookupBaton(); + baton->request.data = baton; + baton->repo = ObjectWrap::Unwrap(args[0]->ToObject()); + baton->oid = ObjectWrap::Unwrap(args[1]->ToObject()); + baton->callback = Persistent::New(Local::Cast(args[2])); - uv_work_t *req = new uv_work_t; - req->data = ar; - uv_queue_work(uv_default_loop(), req, LookupWork, LookupAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, LookupWork, LookupAfterWork); - return scope.Close(Undefined()); + return Undefined(); } void GitCommit::LookupWork(uv_work_t *req) { - lookup_request *ar = static_cast(req->data); + LookupBaton *baton = static_cast(req->data); - git_oid oid = ar->oid->GetValue(); - ar->err = ar->commit->Lookup(ar->repo->GetValue(), &oid); + baton->rawCommit = NULL; + git_oid oid = baton->oid->GetValue(); + baton->errorCode = git_commit_lookup(&baton->rawCommit, baton->repo->GetValue(), &oid); + if (baton->errorCode) { + baton->errorMessage = git_lasterror(); + } } void GitCommit::LookupAfterWork(uv_work_t *req) { HandleScope scope; - lookup_request *ar = static_cast(req->data); + LookupBaton *baton = static_cast(req->data); delete req; - ar->commit->Unref(); + if (baton->errorCode) { + Local argv[1] = { + Exception::Error(String::New(baton->errorMessage)) + }; - Handle argv[1]; - argv[0] = Integer::New(ar->err); + TryCatch try_catch; - TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - ar->callback->Call(Context::GetCurrent()->Global(), 1, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { - if(try_catch.HasCaught()) { - FatalException(try_catch); - } + Local commit = GitCommit::constructor_template->NewInstance(); + GitCommit *commitInstance = ObjectWrap::Unwrap(commit); + commitInstance->SetValue(baton->rawCommit); - ar->callback.Dispose(); + Handle argv[2] = { + Local::New(Null()), + commit + }; - delete ar; + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } } Handle GitCommit::Close(const Arguments& args) { From f31b1a3825dc07f17a3c2b84bf7b221ccb293541 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:43:53 +1300 Subject: [PATCH 008/120] Updated parent --- include/commit.h | 7 ------- src/commit.cc | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/commit.h b/include/commit.h index 80a4f54d0..f08dacc6d 100755 --- a/include/commit.h +++ b/include/commit.h @@ -41,13 +41,6 @@ class GitCommit : public ObjectWrap { void SetValue(git_commit* commit); void Close(); - // const git_oid* Id(); - // const char* MessageShort(); - // const char* Message(); - // time_t Time(); - // int TimeOffset(); - // const git_signature* Committer(); - // const git_signature* Author(); int Tree(git_tree** tree); unsigned int ParentCount(); int Parent(git_commit** commit, int pos); diff --git a/src/commit.cc b/src/commit.cc index 356852c42..3117e93ee 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -394,8 +394,8 @@ void GitCommit::ParentAfterWork(uv_work_t* req) { } else { Local parent = GitCommit::constructor_template->NewInstance(); - GitCommit *parentCommit = ObjectWrap::Unwrap(parent); - parentCommit->SetValue(baton->rawParentCommit); + GitCommit *parentInstance = ObjectWrap::Unwrap(parent); + parentInstance->SetValue(baton->rawParentCommit); Handle argv[2] = { Local::New(Null()), From 70680511c9a4559bd12a5d4fdd83385074428ab9 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:44:51 +1300 Subject: [PATCH 009/120] Added fetch details sync --- include/commit.h | 2 +- src/commit.cc | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/include/commit.h b/include/commit.h index f08dacc6d..69a7f01da 100755 --- a/include/commit.h +++ b/include/commit.h @@ -52,6 +52,7 @@ class GitCommit : public ObjectWrap { static Handle New(const Arguments& args); static Handle NewInstance(); + static Handle FetchDetailsSync(const Arguments& args); static Handle FetchDetails(const Arguments& args); static void FetchDetailsWork(uv_work_t *req); static void FetchDetailsAfterWork(uv_work_t *req); @@ -98,7 +99,6 @@ class GitCommit : public ObjectWrap { const char* errorMessage; git_commit* rawCommit; - const git_oid *oid; char sha[GIT_OID_HEXSZ + 1]; const char* message; diff --git a/src/commit.cc b/src/commit.cc index 3117e93ee..83e8e62f8 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -37,6 +37,7 @@ void GitCommit::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(tpl, "parent", Parent); NODE_SET_PROTOTYPE_METHOD(tpl, "parentSync", ParentSync); NODE_SET_PROTOTYPE_METHOD(tpl, "fetchDetails", FetchDetails); + NODE_SET_PROTOTYPE_METHOD(tpl, "fetchDetailsSync", FetchDetailsSync); constructor_template = Persistent::New(tpl->GetFunction()); target->Set(String::NewSymbol("Commit"), constructor_template); @@ -85,6 +86,70 @@ Handle GitCommit::NewInstance() { return scope.Close(instance); } +Handle GitCommit::FetchDetailsSync(const Arguments& args) { + HandleScope scope; + + GitCommit *commit = ObjectWrap::Unwrap(args.This()); + + Local details = Object::New(); + + Handle oid = GitOid::constructor_template->NewInstance(); + + char sha[GIT_OID_HEXSZ + 1]; + sha[GIT_OID_HEXSZ] = '\0'; + GitOid *oidInstance = ObjectWrap::Unwrap(oid); + const git_oid* rawOid = git_commit_id(commit->commit); + oidInstance->SetValue(*const_cast(rawOid)); + git_oid_fmt(sha, rawOid); + + details->Set(String::NewSymbol("id"), oid); + details->Set(String::NewSymbol("sha"), String::New(sha)); + details->Set(String::NewSymbol("message"), cvv8::CastToJS(git_commit_message(commit->commit))); + details->Set(String::NewSymbol("time"), cvv8::CastToJS(git_commit_time(commit->commit))); + details->Set(String::NewSymbol("timeOffset"), cvv8::CastToJS(git_commit_time_offset(commit->commit))); + + const git_signature *rawCommitter = git_commit_committer(commit->commit); + Local committer = Object::New(); + committer->Set(String::NewSymbol("name"), cvv8::CastToJS(rawCommitter->name)); + committer->Set(String::NewSymbol("email"), cvv8::CastToJS(rawCommitter->email)); + + Local committerWhen = Object::New(); + committerWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(rawCommitter->when.time)); + committerWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(rawCommitter->when.offset)); + committer->Set(String::NewSymbol("when"), cvv8::CastToJS(committerWhen)); + + details->Set(String::NewSymbol("committer"), committer); + + const git_signature* rawAuthor = git_commit_author(commit->commit); + Local author = Object::New(); + author->Set(String::NewSymbol("name"), cvv8::CastToJS(rawAuthor->name)); + author->Set(String::NewSymbol("email"), cvv8::CastToJS(rawAuthor->email)); + + Local authorWhen = Object::New(); + authorWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(rawAuthor->when.time)); + authorWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(rawAuthor->when.offset)); + author->Set(String::NewSymbol("when"), authorWhen); + + details->Set(String::NewSymbol("author"), author); + + int parentCount = git_commit_parentcount(commit->commit); + std::vector parentShas; + while (parentCount > 0) { + int parentIndex = parentCount -1; + char sha[GIT_OID_HEXSZ + 1]; + sha[GIT_OID_HEXSZ] = '\0'; + const git_oid *parentOid = git_commit_parent_oid(commit->commit, parentIndex); + git_oid_fmt(sha, parentOid); + parentShas.push_back(sha); + parentCount--; + } + + details->Set(String::NewSymbol("parentCount"), cvv8::CastToJS(parentCount)); + details->Set(String::NewSymbol("parentShas"), cvv8::CastToJS(parentShas)); + + return scope.Close(details); +} + Handle GitCommit::FetchDetails(const Arguments& args) { HandleScope scope; From 5601098e0881045b29428e5565b7c363ea18776d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:46:09 +1300 Subject: [PATCH 010/120] Updated fetch details methods --- lib/commit.js | 58 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 3831eac78..4a26b9c32 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -1,6 +1,22 @@ var git = require( '../' ), events = require( 'events' ); +/** + * Apply given details to the context. + * + * @param {Object} details + * @param {Object} context + * @return {Object} The modified context. + */ +function applyDetails(details, context) { + if (details) { + for (var detailKey in details) { + context[detailKey] = details[detailKey]; + } + } + return context; +} + /** * Convenience commit constructor. * @@ -10,7 +26,7 @@ var git = require( '../' ), var _Commit = function(obj) { var self = { _cache: {} }; - if( obj instanceof git.raw.Commit ) { + if(obj instanceof git.raw.Commit) { self.commit = obj; } else { @@ -28,20 +44,39 @@ var _Commit = function(obj) { if (errorCode) { error = git.error(errorCode); } - if (details) { - // @todo add details to commit - } + applyDetails(details, self); callback(error); }); }; + /** + * Fetch the commit's details synchronously. + */ + self.fetchDetailsSync = function(callback) { + var details = self.commit.fetchDetailsSync(); + return applyDetails(details, self); + }; + + /** + * Look up the commit referenced by oid, replace self.commit + * with the result. + * + * @param {Repo} repo + * @param {Oid} oid + * @param {Function} callback + */ self.lookup = function(repo, oid, callback) { self.repo = repo; - self.commit.lookup(repo, oid, function() { - var args = Array.prototype.slice.call(arguments); - args[0] = git.util().error(args[0]); + self.commit.lookup(repo, oid, function(error, commit) { + if (error) { + return callback(error, null); + } + self.commit = commit; self.fetchDetails(function(error) { - callback.apply(self, args.concat(self)); + if (error) { + return callback(error, null); + } + callback(null, self); }); }); }; @@ -90,10 +125,10 @@ var _Commit = function(obj) { * @param {Integer} position */ self.parent = function(position, callback) { - var parent = + var parent = null; self.commit.parent(position, function(errorCode, parent) { var error = null; - if (errorCode !== git.error.GIT_SUCCESS) { + if (errorCode) { error = git.error(errorCode); return callback(error, null); } @@ -112,8 +147,7 @@ var _Commit = function(obj) { */ self.parentSync = function(position) { var parent = new _Commit(self.commit.parentSync(position)); - parent.fetchDetailsSync(); - return parent; + return parent.fetchDetailsSync(); }; return self; From b1041d291c8f1f4c49c71f3ef3d4f1c72baa461d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:47:35 +1300 Subject: [PATCH 011/120] Updated convenience-commit tests --- test/convenience-commit.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index ee56240d8..f003cabec 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -45,8 +45,8 @@ exports.improperCommitId = function(test) { test.expect(2); git.repo('../.git', function(error, repository) { repository.commit('not a proper commit sha', function(error, commit) { - test.equals(error.code, git.error.GIT_ENOTFOUND, 'Correct error should occur'); - test.equals(error.message, 'Object does not exist in the scope searched.', 'Attempting to get commit by invalid SHA should error'); + test.notEqual(error.code, git.error.GIT_SUCCESS, 'Error should occur'); + test.notEqual(error.message, null, 'Attempting to get commit by invalid SHA should error'); test.done(); }); @@ -63,10 +63,8 @@ var historyCountKnownSHA = 'fce88902e66c72b5b93e75bdb5ae717038b221f6'; exports.history = function(test) { test.expect(368); git.repo('../.git', function(error, repository) { - repository.commit(historyCountKnownSHA, function(error, commit) { - test.equals(error, 0, 'Getting latest branch commit should not error'); - + test.equals(error, null, 'Getting latest branch commit should not error'); var historyCount = 0; var expectedHistoryCount = 364; commit.history().on('commit', function(error, commit) { @@ -94,11 +92,11 @@ exports.masterHead = function(test) { git.repo('../.git', function(error, repository) { repository.branch('master', function(error, branch) { - test.equals(error, 0, 'Getting branch should not error'); + test.equals(error, null, 'Getting branch should not error'); repository.commit(branch.sha, function(error, commit) { - test.equals(error, 0, 'Getting latest branch commit should not error'); + test.equals(error, null, 'Getting latest branch commit should not error'); test.done(); }); @@ -116,7 +114,7 @@ exports.parentSync = function(test) { git.repo('../.git', function(error, repository) { repository.commit('2d71044741412280370cb0326c96d3a5a7b5dca1', function(error, commit) { test.equals(commit.parentCount, 1, 'Commit has exactly one parent'); - var parent = commit.parentSync(0) + var parent = commit.parentSync(0); test.equals(parent.sha, 'e8876707938abf94d5cc02b0c4017c4fec2aa44e', 'Parent SHA should match expected value'); test.done(); }); @@ -154,7 +152,7 @@ exports.tree = function(test) { repository.commit(historyCountKnownSHA, function(error, commit) { - test.equals(error, 0, 'Getting latest branch commit should not error'); + test.equals(error, null, 'Getting latest branch commit should not error'); var commitTreeEntryCount = 0; var expectedCommitTreeEntryCount = 200; From 8100692c66c6aba456d1b38230005def532f94be Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:48:58 +1300 Subject: [PATCH 012/120] Whitespace --- test/raw-commit.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/raw-commit.js b/test/raw-commit.js index e1a3c23a6..ede5323e0 100644 --- a/test/raw-commit.js +++ b/test/raw-commit.js @@ -13,7 +13,7 @@ var helper = { // This ensures the repo is actually a derivative of the Function [[Class]] test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); }, - // Test code and handle exception thrown + // Test code and handle exception thrown testException: function( test, fun, label ) { try { fun(); @@ -31,7 +31,7 @@ exports.constructor = function( test ){ // Test for function helper.testFunction( test.equals, git.Commit, 'Commit' ); - + testRepo.open( path.resolve( '../.git' ), function( err ) { // Ensure we get an instance of Commit test.ok( new git.Commit( testRepo ) instanceof git.Commit, 'Invocation returns an instance of Commit' ); @@ -47,10 +47,10 @@ exports.lookup = function( test ) { testOid.mkstr( 'cb09e99e91d41705197e0fb60823fdc7df776691' ); - test.expect( 8 ); + test.expect(8); // Test for function - helper.testFunction( test.equals, testCommit.lookup, 'Commit::Lookup' ); + helper.testFunction(test.equals, testCommit.lookup, 'Commit::Lookup'); // Test repo argument existence helper.testException( test.ok, function() { @@ -77,11 +77,11 @@ exports.lookup = function( test ) { testOid.mkstr( '100644' ); testCommit.lookup( testRepo, testOid, function( err ) { test.notEqual( 0, err, 'Not a valid commit' ); - + // Test valid commit testOid.mkstr( 'cb76e3c030ab29db332aff3b297dc39451a84762' ); testCommit.lookup( testRepo, testOid, function( err ) { - test.equals( 0, err, 'Valid commit'); + test.equals(null, err, 'Valid commit'); //test.equals( 'Updated gitignore and raw-commit test', testCommit.messageShort(), 'Commit message is valid' ); From b5e774af7ae54a666ce25418d8f3dafd9866fbef Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:49:19 +1300 Subject: [PATCH 013/120] Tidied oid --- lib/oid.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/oid.js b/lib/oid.js index dedc686c4..cda090b15 100644 --- a/lib/oid.js +++ b/lib/oid.js @@ -1,19 +1,17 @@ var git = require( '../' ); -var _Oid = function( obj ) { +var _Oid = function(obj) { var self = {}; - if( obj instanceof git.raw.Oid ) { + if(obj instanceof git.raw.Oid) { self.oid = obj; - } - else { + } else { self.oid = new git.raw.Oid(); - if( typeof obj === 'string' ) { - self.oid.mkstr( obj ); + if (typeof obj === 'string') { + self.oid.mkstr(obj); } } - return self; }; From a41e262ef5be44c8ec1d20de8e736f75b1ad598a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sat, 9 Mar 2013 23:52:00 +1300 Subject: [PATCH 014/120] Updated repo commit method --- lib/repo.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/repo.js b/lib/repo.js index 4e05f3276..64313ed38 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -40,13 +40,12 @@ exports.repo = function(dir, async) { }; // Find a single commit - self.commit = function(sha, async) { - if (!async) { - // TODO: Implement Sync API - return; - } + self.commit = function(sha, callback) { + git.commit().lookup(self.repo, git.oid(sha).oid, callback); + }; - git.commit().lookup(self.repo, git.oid(sha).oid, async); + self.commitSync = function(sha) { + throw new Error('commitSync not yet implemented'); }; self.init = function(dir, isBare, async) { @@ -62,10 +61,10 @@ exports.repo = function(dir, async) { return self; }; - self.free = function() { + self.free = function() { self.repo.free(); delete self.repo; }; - + return self; }; From 5c710db407ed905a6daec18c4826bb5520ecd7f7 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 00:25:07 +1300 Subject: [PATCH 015/120] Changed committerWhen.when to .time --- src/commit.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index 83e8e62f8..c19c5161c 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -233,7 +233,7 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { committer->Set(String::NewSymbol("email"), cvv8::CastToJS(baton->committer->email)); Local committerWhen = Object::New(); - committerWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(baton->committer->when.time)); + committerWhen->Set(String::NewSymbol("time"), cvv8::CastToJS(baton->committer->when.time)); committerWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(baton->committer->when.offset)); committer->Set(String::NewSymbol("when"), cvv8::CastToJS(committerWhen)); @@ -244,7 +244,7 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { author->Set(String::NewSymbol("email"), cvv8::CastToJS(baton->author->email)); Local authorWhen = Object::New(); - authorWhen->Set(String::NewSymbol("when"), cvv8::CastToJS(baton->author->when.time)); + authorWhen->Set(String::NewSymbol("time"), cvv8::CastToJS(baton->author->when.time)); authorWhen->Set(String::NewSymbol("offset"), cvv8::CastToJS(baton->author->when.offset)); author->Set(String::NewSymbol("when"), authorWhen); From bb49d036e2812e107b92d9c406ac80cecc2cf075 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 00:25:26 +1300 Subject: [PATCH 016/120] Updated raw-commit test to include commit.fetchDetails tests --- test/raw-commit.js | 81 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/test/raw-commit.js b/test/raw-commit.js index ede5323e0..fdba39915 100644 --- a/test/raw-commit.js +++ b/test/raw-commit.js @@ -26,7 +26,7 @@ var helper = { }; // Commit -exports.constructor = function( test ){ +exports.constructor = function(test){ test.expect( 3 ); // Test for function @@ -41,11 +41,11 @@ exports.constructor = function( test ){ }; // Commit::Lookup -exports.lookup = function( test ) { +exports.lookup = function(test) { var testOid = new git.Oid(), testCommit = new git.Commit(); - testOid.mkstr( 'cb09e99e91d41705197e0fb60823fdc7df776691' ); + testOid.mkstr('cb09e99e91d41705197e0fb60823fdc7df776691'); test.expect(8); @@ -58,29 +58,29 @@ exports.lookup = function( test ) { }, 'Throw an exception if no repo' ); // Test oid argument existence - helper.testException( test.ok, function() { - testCommit.lookup( testRepo ); + helper.testException(test.ok, function() { + testCommit.lookup(testRepo); }, 'Throw an exception if no oid' ); // Test callback argument existence - helper.testException( test.ok, function() { - testCommit.lookup( testOid ); + helper.testException(test.ok, function() { + testCommit.lookup(testOid); }, 'Throw an exception if no callback' ); // Test that all arguments result correctly - helper.testException( test.ifError, function() { - testCommit.lookup( testRepo, testOid, function() {} ); + helper.testException(test.ifError, function() { + testCommit.lookup(testRepo, testOid, function() {} ); }, 'No exception is thrown with proper arguments' ); - testRepo.open( path.resolve( '../.git' ), function() { + testRepo.open( path.resolve('../.git'), function() { // Test invalid commit - testOid.mkstr( '100644' ); - testCommit.lookup( testRepo, testOid, function( err ) { - test.notEqual( 0, err, 'Not a valid commit' ); + testOid.mkstr('100644'); + testCommit.lookup(testRepo, testOid, function(err) { + test.notEqual(0, err, 'Not a valid commit'); // Test valid commit - testOid.mkstr( 'cb76e3c030ab29db332aff3b297dc39451a84762' ); - testCommit.lookup( testRepo, testOid, function( err ) { + testOid.mkstr('cb76e3c030ab29db332aff3b297dc39451a84762'); + testCommit.lookup( testRepo, testOid, function(err) { test.equals(null, err, 'Valid commit'); //test.equals( 'Updated gitignore and raw-commit test', testCommit.messageShort(), 'Commit message is valid' ); @@ -90,3 +90,54 @@ exports.lookup = function( test ) { }); }); }; + +exports.fetchDetails = function(test) { + + test.expect(14); + + var testOid = new git.Oid(); + testOid.mkstr('cb76e3c030ab29db332aff3b297dc39451a84762'); + testRepo.open(path.resolve('../.git'), function() { + var testCommit = new git.Commit(); + testCommit.lookup(testRepo, testOid, function(error, commit) { + commit.fetchDetails(function(error, details) { + + var expected = { + sha: 'cb76e3c030ab29db332aff3b297dc39451a84762', + message: 'bumped package.json up\n', + time: 1300145116, + timeOffset: -240, + committer: + { name: 'Tim Branyen', + email: 'tim.branyen@gmail.com', + when: { when: 1300145116, offset: -240 } }, + author: + { name: 'Tim Branyen', + email: 'tim.branyen@gmail.com', + when: { when: 1300145116, offset: -240 } }, + parentCount: 1, + parentShas: [ 'b1f941c62f508db5f392a6bb0ea1d591753a045b' ] }; + + test.equals(expected.sha, details.sha, 'Expected SHA does not match result'); + test.equals(expected.message, details.message, 'Expected message does not match result'); + test.equals(expected.time, details.time, 'Expected time does not match result'); + test.equals(expected.offset, details.offset, 'Expected offset does not match result'); + + test.equals(expected.committer.name, details.committer.name, 'Expected committer.name does not match result'); + test.equals(expected.committer.email, details.committer.email, 'Expected committer.email does not match result'); + test.equals(expected.committer.when.time, details.committer.when.time, 'Expected committer.when.time does not match result'); + test.equals(expected.committer.when.offset, details.committer.when.offset, 'Expected committer.when.offset does not match result'); + + test.equals(expected.author.name, details.author.name, 'Expected author.name does not match result'); + test.equals(expected.author.email, details.author.email, 'Expected author.email does not match result'); + test.equals(expected.author.when.time, details.author.when.time, 'Expected author.when.time does not match result'); + test.equals(expected.author.when.offset, details.author.when.offset, 'Expected author.when.offset does not match result'); + + test.equals(expected.parentCount, details.parentCount, 'Expected parentCount does not match result'); + test.equals(expected.parentShas[0], details.parentShas[0], 'Expected parentShas[0] does not match result'); + + test.done(); + }); + }); + }); +}; From 9c6952791f239b79db24be24a100df0de82b4d71 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 01:10:30 +1300 Subject: [PATCH 017/120] Tidy rev walk test --- test/raw-revwalk.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/test/raw-revwalk.js b/test/raw-revwalk.js index 4e7ef0f3b..ddf92aa91 100644 --- a/test/raw-revwalk.js +++ b/test/raw-revwalk.js @@ -1,4 +1,5 @@ var git = require( '../' ).raw, + path = require('path'), rimraf = require('rimraf'); var testRepo = new git.Repo(); @@ -12,7 +13,7 @@ var helper = { // This ensures the repo is actually a derivative of the Function [[Class]] test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); }, - // Test code and handle exception thrown + // Test code and handle exception thrown testException: function( test, fun, label ) { try { fun(); @@ -25,15 +26,15 @@ var helper = { }; // RevWalk -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.RevWalk, 'RevWalk' ); - + helper.testFunction(test.equals, git.RevWalk, 'RevWalk'); + // Ensure we get an instance of Oid - testRepo.open( './dummyrepo/.git', function( err, path ) { - test.ok( new git.RevWalk( testRepo ) instanceof git.RevWalk, 'Invocation returns an instance of RevWalk' ); + testRepo.open( './dummyrepo/.git', function(error, path) { + test.ok(new git.RevWalk(testRepo) instanceof git.RevWalk, 'Invocation returns an instance of RevWalk'); test.done(); }); From 13de84a5304beb761ae620cc3deb24f987c0f9a5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 01:10:46 +1300 Subject: [PATCH 018/120] Refactor revwalk.next --- lib/revwalk.js | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/revwalk.js b/lib/revwalk.js index f5ef4de1d..e12da98d4 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -11,29 +11,48 @@ var _RevWalk = function( obj ) { self.revwalk = obj; } - // Walk will map to the next method - self.walk = function( oid, callback ) { - if( !callback ) { return; } + /** + * Walk the history from the given oid. + * + * @param {Oid} oid + * @param {Function} callback Callback accepting the following arguments: + * error, index, commit, noMoreCommits + */ + self.walk = function(oid, callback ) { + if(!callback) { return; } - self.revwalk.push( oid ); + self.revwalk.push(oid); - var cont = true, i = 0; + var shouldContinue = true, index = 0; function walk() { - if( !cont ) { return; } + if(!shouldContinue) { + return; + } var _tmp = git.oid(); - self.revwalk.next( _tmp.oid, function( err ) { - if( err ) { callback.apply( this, [ err ] ); return; } + self.revwalk.next( _tmp.oid, function(errorCode) { + if(errorCode) { + // Finished walking history, apply callback with noMoreCommits = true + if (errorCode === git.error.GIT_EREVWALKOVER) { + callback.apply(this, [null, index, null, true]); + return; + } + callback.apply(this, [git.error(errorCode)]); + return; + } - git.commit( self.repo ).lookup( self.repo, _tmp.oid, function( err ) { - if( err ) { callback.apply( this, [ err, i, this ] ); } + git.commit(self.repo).lookup(self.repo, _tmp.oid, function(errorCode, commit) { + if(errorCode) { + callback.apply(this, [git.error(errorCode), index, commit]); + return; + } - if( callback.apply( this, [ err, i, this ] ) === false ) { - cont = false; + if(callback.apply(this, [null, index, commit]) === false) { + shouldContinue = false; } - i = i + 1; + index++; walk(); }); }); From 992e677a73516806c6b5e797db2046ce2e155a78 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 01:11:00 +1300 Subject: [PATCH 019/120] Update commit.history --- lib/commit.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 4a26b9c32..c24ac71d3 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -97,23 +97,30 @@ var _Commit = function(obj) { return self.tree().entry( path ); }; - self.history = function(start, end) { + /** + * Walk the history of this commit. + * + * @return {Event} Event emits 'commit', with error, commit and 'end', with + * error, commits[] + */ + self.history = function() { var revwalk = git.revwalk(self.repo), event = new events.EventEmitter(), commits = []; - revwalk.walk(self.id, function(error, index, commit) { + revwalk.walk(self.id, function(error, index, commit, noMoreCommits) { if(error) { - if (error === git.error.GIT_EREVWALKOVER) { - event.emit('end', null, commits); - return; - } else { - event.emit('commit', new git.error(error), commit); - return; - } + event.emit('end', error, commits); + return false; } + + if (noMoreCommits) { + event.emit('end', null, commits); + } + event.emit('commit', null, commit); commits.push(commit); + }); return event; From 6bc1a8d1aab48fc7fa334c86d9f0c87e024c1eb0 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 01:20:46 +1300 Subject: [PATCH 020/120] Return on noMoreCommits --- lib/commit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/commit.js b/lib/commit.js index c24ac71d3..c84137bfa 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -116,6 +116,7 @@ var _Commit = function(obj) { if (noMoreCommits) { event.emit('end', null, commits); + return; } event.emit('commit', null, commit); From 1b030a71e257fde520ca6e368b80ef2fc5edc91a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Sun, 10 Mar 2013 22:22:25 +1300 Subject: [PATCH 021/120] Updated to libgit2 v0.17.0 --- vendor/libgit2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/libgit2 b/vendor/libgit2 index 3eaf34f4c..5b9fac39d 160000 --- a/vendor/libgit2 +++ b/vendor/libgit2 @@ -1 +1 @@ -Subproject commit 3eaf34f4c602b9e155e2f4c6ae26c9250ac37d50 +Subproject commit 5b9fac39d8a76b9139667c26a63e6b3f204b3977 From 54b85269c4bc622087935a8a86df4ec60926ff9b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 11 Mar 2013 01:32:04 +1300 Subject: [PATCH 022/120] Use free instead of close --- src/blob.cc | 2 +- src/commit.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blob.cc b/src/blob.cc index ff56275b5..c627a3ff2 100755 --- a/src/blob.cc +++ b/src/blob.cc @@ -57,7 +57,7 @@ int GitBlob::RawSize() { } void GitBlob::Close() { - git_blob_close(this->blob); + git_blob_free(this->blob); } int CreateFromFile(git_oid* oid, git_repository* repo, const char* path) { diff --git a/src/commit.cc b/src/commit.cc index c19c5161c..102eccd69 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -52,7 +52,7 @@ void GitCommit::SetValue(git_commit* commit) { } void GitCommit::Close() { - git_commit_close(this->commit); + git_commit_free(this->commit); this->commit = NULL; } From 0d04f634294f3824d7295ff2433a24e2cfda59c2 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 11 Mar 2013 01:33:00 +1300 Subject: [PATCH 023/120] Refactor error to thinly wrap git_error, magic happens in lib/error.js --- include/error.h | 41 ++++++++--------------- lib/error.js | 29 ++++++++-------- src/error.cc | 89 +++++++++++++++++-------------------------------- 3 files changed, 59 insertions(+), 100 deletions(-) diff --git a/include/error.h b/include/error.h index 0ca2bddd0..87c3e593a 100755 --- a/include/error.h +++ b/include/error.h @@ -10,6 +10,7 @@ #include "../vendor/libgit2/include/git2.h" +using namespace v8; using namespace node; /** @@ -22,28 +23,21 @@ class GitError : public ObjectWrap { * Variable: constructor_template * Used to create Node.js constructor. */ - static v8::Persistent constructor_template; + static Persistent constructor_template; /** * Function: Initialize * Used to intialize the EventEmitter from Node.js * * Parameters: - * target - v8::Object the Node.js global module object + * target - Object the Node.js global module object */ - static void Initialize(v8::Handle target); - /** - * Function: StrError - * Get a read-only buffer with the raw content of a blob. - * - * Parameters: - * err - A signed int error code - * - * Returns: - * a string explaining the error code. - */ - const char* StrError(int err); + static void Initialize(Handle target); + + static Local WrapError(const git_error* error); protected: + const git_error* error; + /** * Constructor: GitError */ @@ -52,26 +46,17 @@ class GitError : public ObjectWrap { * Deconstructor: GitError */ ~GitError() {}; + /** * Function: New * * Parameters: - * args v8::Arguments function call - * - * Returns: - * v8::Object args.This() - */ - static v8::Handle New(const v8::Arguments& args); - /** - * Function: StrError - * - * Parameters: - * args v8::Arguments function call + * args Arguments function call * * Returns: - * v8::Object args.This() + * Object args.This() */ - static v8::Handle StrError(const v8::Arguments& args); + static Handle New(const Arguments& args); }; - + #endif diff --git a/lib/error.js b/lib/error.js index de7716670..c431fcb83 100644 --- a/lib/error.js +++ b/lib/error.js @@ -2,28 +2,31 @@ var git = require('../'), util = require('util'); /** - * Initialise an Error object + * GitError constructor. * - * @param {mixed} obj A git.raw.Error object or a string describing the error. - * @return {Object} + * @param {String} message giterr_last->message + * @param {Integer} code giterr_last->klass */ -var GitError = function(object) { - var error = null; - var gitError = new git.raw.Error(); - if (typeof object === 'number') { - error = new Error(gitError.strError(object)); - error.code = object; - } - return error; +var GitError = function(message, code) { + Error.call(this); + Error.captureStackTrace(this, exports.error); + + this.name = this.constructor.name; + this.message = message; + this.code = code; }; +util.inherits(GitError, Error); + /** * Add libgit2 error codes to git.error object. * * Refer to vendor/libgit2/include/git2/errors.h for error code definitions. */ for (var errorName in git.raw.Error.codes) { - GitError[errorName] = git.raw.Error.codes[errorName]; + GitError.prototype[errorName] = git.raw.Error.codes[errorName]; } -exports.error = GitError; +exports.error = function(error) { + return new GitError(error.message, error.code); +}; diff --git a/src/error.cc b/src/error.cc index 586163731..0ba904050 100755 --- a/src/error.cc +++ b/src/error.cc @@ -17,64 +17,49 @@ using namespace node; namespace cvv8 { template <> - struct NativeToJS : NativeToJS {}; + struct NativeToJS : NativeToJS {}; } void GitError::Initialize (Handle target) { HandleScope scope; - Local t = FunctionTemplate::New(New); + Local tpl = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Error")); - - NODE_SET_PROTOTYPE_METHOD(constructor_template, "strError", StrError); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("Error")); // Add libgit2 error codes to error object Local libgit2Errors = Object::New(); - libgit2Errors->Set(String::NewSymbol("GIT_SUCCESS"), cvv8::CastToJS(GIT_SUCCESS), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ERROR"), cvv8::CastToJS(GIT_ERROR), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOTOID"), cvv8::CastToJS(GIT_ENOTOID), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOTFOUND"), cvv8::CastToJS(GIT_ENOTFOUND), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOMEM"), cvv8::CastToJS(GIT_ENOMEM), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EOSERR"), cvv8::CastToJS(GIT_EOSERR), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EOBJTYPE"), cvv8::CastToJS(GIT_EOBJTYPE), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOTAREPO"), cvv8::CastToJS(GIT_ENOTAREPO), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EINVALIDTYPE"), cvv8::CastToJS(GIT_EINVALIDTYPE), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EMISSINGOBJDATA"), cvv8::CastToJS(GIT_EMISSINGOBJDATA), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EPACKCORRUPTED"), cvv8::CastToJS(GIT_EPACKCORRUPTED), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EFLOCKFAIL"), cvv8::CastToJS(GIT_EFLOCKFAIL), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EZLIB"), cvv8::CastToJS(GIT_EZLIB), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EBUSY"), cvv8::CastToJS(GIT_EBUSY), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EBAREINDEX"), cvv8::CastToJS(GIT_EBAREINDEX), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EINVALIDREFNAME"), cvv8::CastToJS(GIT_EINVALIDREFNAME), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EREFCORRUPTED"), cvv8::CastToJS(GIT_EREFCORRUPTED), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ETOONESTEDSYMREF"), cvv8::CastToJS(GIT_ETOONESTEDSYMREF), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EPACKEDREFSCORRUPTED"), cvv8::CastToJS(GIT_EPACKEDREFSCORRUPTED), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EINVALIDPATH"), cvv8::CastToJS(GIT_EINVALIDPATH), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EREVWALKOVER"), cvv8::CastToJS(GIT_EREVWALKOVER), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EINVALIDREFSTATE"), cvv8::CastToJS(GIT_EINVALIDREFSTATE), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOTIMPLEMENTED"), cvv8::CastToJS(GIT_ENOTIMPLEMENTED), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EEXISTS"), cvv8::CastToJS(GIT_EEXISTS), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EOVERFLOW"), cvv8::CastToJS(GIT_EOVERFLOW), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOTNUM"), cvv8::CastToJS(GIT_ENOTNUM), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ESTREAM"), cvv8::CastToJS(GIT_ESTREAM), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EINVALIDARGS"), cvv8::CastToJS(GIT_EINVALIDARGS), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EOBJCORRUPTED"), cvv8::CastToJS(GIT_EOBJCORRUPTED), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EAMBIGUOUSOIDPREFIX"), cvv8::CastToJS(GIT_EAMBIGUOUSOIDPREFIX), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_EPASSTHROUGH"), cvv8::CastToJS(GIT_EPASSTHROUGH), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ENOMATCH"), cvv8::CastToJS(GIT_ENOMATCH), ReadOnly); - libgit2Errors->Set(String::NewSymbol("GIT_ESHORTBUFFER"), cvv8::CastToJS(GIT_ESHORTBUFFER), ReadOnly); - + libgit2Errors->Set(String::NewSymbol("GITERR_NOMEMORY"), cvv8::CastToJS(GITERR_NOMEMORY), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_OS"), cvv8::CastToJS(GITERR_OS), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_INVALID"), cvv8::CastToJS(GITERR_INVALID), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_REFERENCE"), cvv8::CastToJS(GITERR_REFERENCE), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_ZLIB"), cvv8::CastToJS(GITERR_ZLIB), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_REPOSITORY"), cvv8::CastToJS(GITERR_REPOSITORY), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_CONFIG"), cvv8::CastToJS(GITERR_CONFIG), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_REGEX"), cvv8::CastToJS(GITERR_REGEX), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_ODB"), cvv8::CastToJS(GITERR_ODB), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_INDEX"), cvv8::CastToJS(GITERR_INDEX), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_OBJECT"), cvv8::CastToJS(GITERR_OBJECT), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_NET"), cvv8::CastToJS(GITERR_NET), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_TAG"), cvv8::CastToJS(GITERR_TAG), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_TREE"), cvv8::CastToJS(GITERR_TREE), ReadOnly); + libgit2Errors->Set(String::NewSymbol("GITERR_INDEXER"), cvv8::CastToJS(GITERR_INDEXER), ReadOnly); + + constructor_template = Persistent::New(tpl->GetFunction()); constructor_template->Set(String::NewSymbol("codes"), libgit2Errors, ReadOnly); - target->Set(String::NewSymbol("Error"), constructor_template->GetFunction()); + target->Set(String::NewSymbol("Error"), constructor_template); } -const char* GitError::StrError(int err) { - return git_strerror(err); +Local GitError::WrapError(const git_error* error) { + Local gitError = GitError::constructor_template->NewInstance(); + Local stackTrace = StackTrace::CurrentStackTrace(10); + gitError->Set(String::NewSymbol("stackTrace"), cvv8::CastToJS(stackTrace->AsArray())); + gitError->Set(String::NewSymbol("message"), String::New(error->message)); + gitError->Set(String::NewSymbol("code"), Integer::New(error->klass)); + return gitError; } Handle GitError::New(const Arguments& args) { @@ -86,18 +71,4 @@ Handle GitError::New(const Arguments& args) { return scope.Close( args.This() ); } -Handle GitError::StrError(const Arguments& args) { - HandleScope scope; - - GitError* error = ObjectWrap::Unwrap(args.This()); - - if(args.Length() == 0 || !args[0]->IsNumber()) { - return ThrowException(Exception::Error(String::New("Error is required and must be a Number."))); - } - - Local err = Local::Cast(args[0]); - - return scope.Close( String::New(error->StrError(err->Value())) ); -} - -Persistent GitError::constructor_template; +Persistent GitError::constructor_template; From 8fd2aab062de05528968e44d205f237025b57459 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 11 Mar 2013 01:33:45 +1300 Subject: [PATCH 024/120] Updated convenience-commit tests --- test/convenience-commit.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index f003cabec..846b120cc 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -42,12 +42,10 @@ exports.method = function(test){ * @param {Object} test */ exports.improperCommitId = function(test) { - test.expect(2); + test.expect(1); git.repo('../.git', function(error, repository) { repository.commit('not a proper commit sha', function(error, commit) { - test.notEqual(error.code, git.error.GIT_SUCCESS, 'Error should occur'); - test.notEqual(error.message, null, 'Attempting to get commit by invalid SHA should error'); - + test.notEqual(error, null, 'Error should occur'); test.done(); }); }); From df1484e64a0013b91a5e1ccda0a23fd504d3bdce Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 11 Mar 2013 01:34:02 +1300 Subject: [PATCH 025/120] Upgrading from 0.15-0.17 changes --- src/oid.cc | 2 +- src/tree.cc | 2 +- src/tree_entry.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/oid.cc b/src/oid.cc index 72cea524e..d66c0df28 100755 --- a/src/oid.cc +++ b/src/oid.cc @@ -62,7 +62,7 @@ char* GitOid::AllocFmt() { } char* GitOid::ToString(char* buffer, size_t bufferSize) { - return git_oid_to_string(buffer, bufferSize, &this->oid); + return git_oid_tostr(buffer, bufferSize, &this->oid); } void GitOid::Cpy(git_oid* out) { diff --git a/src/tree.cc b/src/tree.cc index 6a985b967..591f9bdc4 100755 --- a/src/tree.cc +++ b/src/tree.cc @@ -69,7 +69,7 @@ Handle GitTree::New(const Arguments& args) { tree->Wrap(args.This()); - return scope.Close( args.This() ); + return scope.Close(args.This()); } Handle GitTree::Lookup(const Arguments& args) { diff --git a/src/tree_entry.cc b/src/tree_entry.cc index bc35a78eb..cd677008f 100755 --- a/src/tree_entry.cc +++ b/src/tree_entry.cc @@ -53,7 +53,7 @@ const git_oid* GitTreeEntry::Id() { } int GitTreeEntry::ToObject(git_repository* repo, git_object** obj) { - return git_tree_entry_2object(obj, repo, this->entry); + return git_tree_entry_to_object(obj, repo, this->entry); } Handle GitTreeEntry::New(const Arguments& args) { From 7ffef1e29f4075a06f5564e72ab1e1468d101d8f Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 11 Mar 2013 01:35:15 +1300 Subject: [PATCH 026/120] Updated commit --- include/commit.h | 9 +++------ lib/commit.js | 22 ++++++++++------------ src/commit.cc | 34 ++++++++++++++++++---------------- test/raw-commit.js | 9 ++++++--- 4 files changed, 37 insertions(+), 37 deletions(-) diff --git a/include/commit.h b/include/commit.h index 69a7f01da..45951f10f 100755 --- a/include/commit.h +++ b/include/commit.h @@ -80,8 +80,7 @@ class GitCommit : public ObjectWrap { struct LookupBaton { uv_work_t request; - int errorCode; - const char* errorMessage; + const git_error* error; GitRepo* repo; GitOid* oid; @@ -95,8 +94,7 @@ class GitCommit : public ObjectWrap { */ struct FetchDetailsBaton { uv_work_t request; - int errorCode; - const char* errorMessage; + const git_error* error; git_commit* rawCommit; const git_oid *oid; @@ -119,8 +117,7 @@ class GitCommit : public ObjectWrap { */ struct ParentBaton { uv_work_t request; - int errorCode; - const char* errorMessage; + const git_error* error; int index; GitCommit* commit; diff --git a/lib/commit.js b/lib/commit.js index c84137bfa..1a838cc78 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -24,7 +24,7 @@ function applyDetails(details, context) { * @return {Commit} */ var _Commit = function(obj) { - var self = { _cache: {} }; + var self = {}; if(obj instanceof git.raw.Commit) { self.commit = obj; @@ -69,12 +69,12 @@ var _Commit = function(obj) { self.repo = repo; self.commit.lookup(repo, oid, function(error, commit) { if (error) { - return callback(error, null); + return callback(git.error(error), null); } self.commit = commit; self.fetchDetails(function(error) { if (error) { - return callback(error, null); + return callback(git.error(error), null); } callback(null, self); }); @@ -82,19 +82,17 @@ var _Commit = function(obj) { }; self.tree = function() { - var tree = new git.raw.Tree( self.repo ); - if( tree.error ) { - return git.error( tree.error ); - } - else { - self.commit.tree( tree ); + var tree = new git.raw.Tree(self.repo); + if(tree.error) { + return git.error(tree.error); + } else { + self.commit.tree(tree); } - - return git.tree( self.repo, tree ); + return git.tree(self.repo, tree); }; self.file = function(path) { - return self.tree().entry( path ); + return self.tree().entry(path); }; /** diff --git a/src/commit.cc b/src/commit.cc index 102eccd69..f32ebaf8f 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -16,6 +16,7 @@ #include "../include/oid.h" #include "../include/tree.h" #include "../include/commit.h" + #include "../include/error.h" using namespace v8; using namespace cvv8; @@ -201,9 +202,9 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { FetchDetailsBaton* baton = static_cast(req->data); delete req; - if (baton->errorCode) { + if (baton->error) { Local argv[1] = { - Exception::Error(String::New(baton->errorMessage)) + GitError::WrapError(baton->error) }; TryCatch try_catch; @@ -227,7 +228,6 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { details->Set(String::NewSymbol("time"), cvv8::CastToJS(baton->time)); details->Set(String::NewSymbol("timeOffset"), cvv8::CastToJS(baton->timeOffset)); - Local committer = Object::New(); committer->Set(String::NewSymbol("name"), cvv8::CastToJS(baton->committer->name)); committer->Set(String::NewSymbol("email"), cvv8::CastToJS(baton->committer->email)); @@ -283,6 +283,7 @@ Handle GitCommit::Lookup(const Arguments& args) { LookupBaton *baton = new LookupBaton(); baton->request.data = baton; + baton->error = NULL; baton->repo = ObjectWrap::Unwrap(args[0]->ToObject()); baton->oid = ObjectWrap::Unwrap(args[1]->ToObject()); baton->callback = Persistent::New(Local::Cast(args[2])); @@ -297,9 +298,9 @@ void GitCommit::LookupWork(uv_work_t *req) { baton->rawCommit = NULL; git_oid oid = baton->oid->GetValue(); - baton->errorCode = git_commit_lookup(&baton->rawCommit, baton->repo->GetValue(), &oid); - if (baton->errorCode) { - baton->errorMessage = git_lasterror(); + int returnCode = git_commit_lookup(&baton->rawCommit, baton->repo->GetValue(), &oid); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); } } @@ -309,9 +310,9 @@ void GitCommit::LookupAfterWork(uv_work_t *req) { LookupBaton *baton = static_cast(req->data); delete req; - if (baton->errorCode) { + if (baton->error) { Local argv[1] = { - Exception::Error(String::New(baton->errorMessage)) + GitError::WrapError(baton->error) }; TryCatch try_catch; @@ -387,10 +388,10 @@ Handle GitCommit::ParentSync(const Arguments& args) { GitCommit *commit = ObjectWrap::Unwrap(args.This()); git_commit *parentCommitValue ; - int errorCode = git_commit_parent(&parentCommitValue, commit->commit, args[0]->ToInteger()->Value()); + int returnCode = git_commit_parent(&parentCommitValue, commit->commit, args[0]->ToInteger()->Value()); - if (errorCode) { - return ThrowException(Exception::Error(String::New(git_lasterror()))); + if (returnCode != GIT_OK) { + return ThrowException(Exception::Error(String::New(giterr_last()->message))); } Local parent = GitCommit::constructor_template->NewInstance(); @@ -419,6 +420,7 @@ Handle GitCommit::Parent(const Arguments& args) { baton->request.data = baton; baton->commit = ObjectWrap::Unwrap(args.This()); baton->commit->Ref(); + baton->error = NULL; baton->index = args[0]->ToInteger()->Value(); baton->callback = Persistent::New(Local::Cast(args[1])); @@ -431,10 +433,10 @@ void GitCommit::ParentWork(uv_work_t* req) { ParentBaton* baton = static_cast(req->data); baton->rawParentCommit = NULL; - baton->errorCode = git_commit_parent(&baton->rawParentCommit, baton->commit->commit, baton->index); + int returnCode = git_commit_parent(&baton->rawParentCommit, baton->commit->commit, baton->index); - if (baton->errorCode) { - baton->errorMessage = git_lasterror(); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); } } @@ -444,9 +446,9 @@ void GitCommit::ParentAfterWork(uv_work_t* req) { ParentBaton* baton = static_cast(req->data); delete req; - if (baton->errorCode) { + if (baton->error) { Local argv[1] = { - Exception::Error(String::New(baton->errorMessage)) + GitError::WrapError(baton->error) }; TryCatch try_catch; diff --git a/test/raw-commit.js b/test/raw-commit.js index fdba39915..c563bdd18 100644 --- a/test/raw-commit.js +++ b/test/raw-commit.js @@ -4,7 +4,6 @@ var git = require( '../' ).raw, var testRepo = new git.Repo(); -// Helper functions var helper = { // Test if obj is a true function testFunction: function( test, obj, label ) { @@ -25,7 +24,9 @@ var helper = { } }; -// Commit +/** + * Commit + */ exports.constructor = function(test){ test.expect( 3 ); @@ -40,7 +41,9 @@ exports.constructor = function(test){ }); }; -// Commit::Lookup +/** + * Commit::Lookup + */ exports.lookup = function(test) { var testOid = new git.Oid(), testCommit = new git.Commit(); From 1e9bed54b2e73117a95d4f996e1bf12ff8831f9e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 21:53:50 +1300 Subject: [PATCH 027/120] Whitespace --- src/commit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commit.cc b/src/commit.cc index f32ebaf8f..b7982178f 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -418,7 +418,7 @@ Handle GitCommit::Parent(const Arguments& args) { ParentBaton* baton = new ParentBaton(); baton->request.data = baton; - baton->commit = ObjectWrap::Unwrap(args.This()); + baton->commit = ObjectWrap::Unwrap(args.This()); baton->commit->Ref(); baton->error = NULL; baton->index = args[0]->ToInteger()->Value(); From e8447340fd6900d1cca5bea80609a3c0bd853c2e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 21:56:10 +1300 Subject: [PATCH 028/120] Tidied up commit js --- lib/commit.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 1a838cc78..7ef8bd094 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -40,9 +40,9 @@ var _Commit = function(obj) { */ self.fetchDetails = function(callback) { var error = null; - self.commit.fetchDetails(function(errorCode, details) { - if (errorCode) { - error = git.error(errorCode); + self.commit.fetchDetails(function(error, details) { + if (error) { + error = git.error(error); } applyDetails(details, self); callback(error); @@ -73,7 +73,7 @@ var _Commit = function(obj) { } self.commit = commit; self.fetchDetails(function(error) { - if (error) { + if (error) { return callback(git.error(error), null); } callback(null, self); @@ -108,18 +108,16 @@ var _Commit = function(obj) { revwalk.walk(self.id, function(error, index, commit, noMoreCommits) { if(error) { - event.emit('end', error, commits); - return false; + event.emit('end', error, commits); + return false; } if (noMoreCommits) { event.emit('end', null, commits); return; } - event.emit('commit', null, commit); commits.push(commit); - }); return event; From 12bf8737d54a6b3a45165916a5b79e7771945a38 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 21:56:37 +1300 Subject: [PATCH 029/120] Refactored error classes to work with libgit2 0.17's git_error --- lib/error.js | 11 ++++++++++- src/error.cc | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/error.js b/lib/error.js index c431fcb83..3edd99493 100644 --- a/lib/error.js +++ b/lib/error.js @@ -11,7 +11,7 @@ var GitError = function(message, code) { Error.call(this); Error.captureStackTrace(this, exports.error); - this.name = this.constructor.name; + this.name = 'GitError'; this.message = message; this.code = code; }; @@ -27,6 +27,15 @@ for (var errorName in git.raw.Error.codes) { GitError.prototype[errorName] = git.raw.Error.codes[errorName]; } +/** + * Add libgit2 return codes to git.error object. + * + * Refer to vendor/libgit2/include/git2/errors.h for return code definitions. + */ +for (var errorName in git.raw.Error.returnCodes) { + GitError.prototype[errorName] = git.raw.Error.returnCodes[errorName]; +} + exports.error = function(error) { return new GitError(error.message, error.code); }; diff --git a/src/error.cc b/src/error.cc index 0ba904050..d8171633d 100755 --- a/src/error.cc +++ b/src/error.cc @@ -15,9 +15,27 @@ using namespace v8; using namespace cvv8; using namespace node; +/** + * Copied from libgit2/include/errors.h, to allow exporting to JS + */ +typedef enum { + _GIT_OK = 0, + _GIT_ERROR = -1, + _GIT_ENOTFOUND = -3, + _GIT_EEXISTS = -4, + _GIT_EAMBIGUOUS = -5, + _GIT_EBUFS = -6, + + _GIT_PASSTHROUGH = -30, + _GIT_REVWALKOVER = -31, +} git_error_return_t; + namespace cvv8 { template <> struct NativeToJS : NativeToJS {}; + + template <> + struct NativeToJS : NativeToJS {}; } void GitError::Initialize (Handle target) { @@ -47,8 +65,22 @@ void GitError::Initialize (Handle target) { libgit2Errors->Set(String::NewSymbol("GITERR_TREE"), cvv8::CastToJS(GITERR_TREE), ReadOnly); libgit2Errors->Set(String::NewSymbol("GITERR_INDEXER"), cvv8::CastToJS(GITERR_INDEXER), ReadOnly); + // Add libgit2 error codes to error object + Local libgit2ReturnCodes = Object::New(); + + libgit2ReturnCodes->Set(String::NewSymbol("GIT_OK"), cvv8::CastToJS(_GIT_OK), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_ERROR"), cvv8::CastToJS(_GIT_ERROR), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_ENOTFOUND"), cvv8::CastToJS(_GIT_ENOTFOUND), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_EEXISTS"), cvv8::CastToJS(_GIT_EEXISTS), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_EAMBIGUOUS"), cvv8::CastToJS(_GIT_EAMBIGUOUS), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_EBUFS"), cvv8::CastToJS(_GIT_EBUFS), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_PASSTHROUGH"), cvv8::CastToJS(_GIT_PASSTHROUGH), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_REVWALKOVER"), cvv8::CastToJS(_GIT_REVWALKOVER), ReadOnly); + constructor_template = Persistent::New(tpl->GetFunction()); constructor_template->Set(String::NewSymbol("codes"), libgit2Errors, ReadOnly); + constructor_template->Set(String::NewSymbol("returnCodes"), libgit2ReturnCodes, ReadOnly); + target->Set(String::NewSymbol("Error"), constructor_template); } From ad251ebaa43249f830594aca5428c2e858d19784 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 21:58:44 +1300 Subject: [PATCH 030/120] Refactored revwalk to be more async & handle errors better --- include/revwalk.h | 37 +++++++++--- lib/revwalk.js | 65 ++++++++++---------- src/revwalk.cc | 147 +++++++++++++++++++++++++++++----------------- 3 files changed, 156 insertions(+), 93 deletions(-) diff --git a/include/revwalk.h b/include/revwalk.h index 203e2cf53..f2fc459c2 100755 --- a/include/revwalk.h +++ b/include/revwalk.h @@ -1,7 +1,6 @@ /* Copyright (c) 2011, Tim Branyen @tbranyen */ - #ifndef REVWALK_H #define REVWALK_H @@ -27,7 +26,6 @@ class GitRevWalk : public ObjectWrap { void Reset(); int Push(git_oid* oid); int Hide(); - int Next(git_oid* oid); int Sorting(int sort); void Free(); git_repository* Repository(); @@ -37,12 +35,21 @@ class GitRevWalk : public ObjectWrap { ~GitRevWalk() {} static Handle New(const Arguments& args); static Handle Reset(const Arguments& args); + + /** + * Although git_revwalk_next is not blocking when iterating with a + * time-sorting mode, options may be added later to allow different sort + * modes, hence the async implementation. + */ static Handle Push(const Arguments& args); + static void PushWork(uv_work_t *req); + static void PushAfterWork(uv_work_t *req); + static Handle Hide(const Arguments& args); static Handle Next(const Arguments& args); - static void EIO_Next(uv_work_t* req); - static void EIO_AfterNext(uv_work_t* req); + static void NextWork(uv_work_t* req); + static void NextAfterWork(uv_work_t* req); static Handle Sorting(const Arguments& args); static Handle Free(const Arguments& args); @@ -52,10 +59,24 @@ class GitRevWalk : public ObjectWrap { git_revwalk* revwalk; git_repository* repo; - struct next_request { - GitRevWalk* revwalk; - GitOid* oid; - int err; + struct PushBaton { + uv_work_t request; + const git_error* error; + + git_revwalk *revwalk; + git_oid oid; + + Persistent callback; + }; + + struct NextBaton { + uv_work_t request; + const git_error* error; + bool walkOver; + + git_revwalk *revwalk; + git_oid oid; + Persistent callback; }; }; diff --git a/lib/revwalk.js b/lib/revwalk.js index e12da98d4..9659828d7 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -3,11 +3,10 @@ var git = require( '../' ); var _RevWalk = function( obj ) { var self = {}; - if( obj instanceof git.raw.Repo ) { + if (obj instanceof git.raw.Repo) { self.repo = obj; - self.revwalk = new git.raw.RevWalk( obj ); - } - else if( obj instanceof git.raw.RevWalk ) { + self.revwalk = new git.raw.RevWalk(obj); + } else if (obj instanceof git.raw.RevWalk) { self.revwalk = obj; } @@ -18,47 +17,53 @@ var _RevWalk = function( obj ) { * @param {Function} callback Callback accepting the following arguments: * error, index, commit, noMoreCommits */ - self.walk = function(oid, callback ) { + self.walk = function(oid, callback) { if(!callback) { return; } - self.revwalk.push(oid); - - var shouldContinue = true, index = 0; - - function walk() { - if(!shouldContinue) { + self.revwalk.push(oid, function(error) { + if (error) { + callback.apply(this, [git.error(error)]); return; } - var _tmp = git.oid(); - self.revwalk.next( _tmp.oid, function(errorCode) { - if(errorCode) { - // Finished walking history, apply callback with noMoreCommits = true - if (errorCode === git.error.GIT_EREVWALKOVER) { - callback.apply(this, [null, index, null, true]); - return; - } - callback.apply(this, [git.error(errorCode)]); + var shouldContinue = true, index = 0; + + function walk() { + if(!shouldContinue) { return; } - git.commit(self.repo).lookup(self.repo, _tmp.oid, function(errorCode, commit) { - if(errorCode) { - callback.apply(this, [git.error(errorCode), index, commit]); + self.revwalk.next(function(error, oid, walkOver) { + if(error) { + callback.apply(this, [git.error(error), index, commit]); return; } - if(callback.apply(this, [null, index, commit]) === false) { - shouldContinue = false; + // Finished walking history, apply callback with noMoreCommits = true + if (walkOver) { + callback.apply(this, [null, index, null, walkOver]); + return; } - index++; - walk(); + git.commit(self.repo).lookup(self.repo, oid, function(error, commit) { + + if(error) { + callback.apply(this, [git.error(error), index, commit]); + return; + } + + if(callback.apply(this, [null, index, commit]) === false) { + shouldContinue = false; + } + + index++; + walk(); + }); }); - }); - } + } - walk(); + walk(); + }); }; return self; diff --git a/src/revwalk.cc b/src/revwalk.cc index ec3f6163e..bb5dc6cd6 100755 --- a/src/revwalk.cc +++ b/src/revwalk.cc @@ -10,6 +10,7 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../include/revwalk.h" #include "../include/repo.h" #include "../include/commit.h" +#include "../include/error.h" using namespace v8; using namespace node; @@ -59,22 +60,6 @@ void GitRevWalk::Reset() { git_revwalk_reset(this->revwalk); } -int GitRevWalk::Push(git_oid* oid) { - // Test - git_revwalk_sorting(this->revwalk, GIT_SORT_TIME | GIT_SORT_REVERSE); - - return git_revwalk_push(this->revwalk, oid); -} - -// Not for 0.0.1 -//int GitRevWalk::Hide() { -// git_revwalk_hide(this->revwalk); -//} - -int GitRevWalk::Next(git_oid *oid) { - return git_revwalk_next(oid, this->revwalk); -} - void GitRevWalk::Free() { git_revwalk_free(this->revwalk); } @@ -113,78 +98,130 @@ Handle GitRevWalk::Reset(const Arguments& args) { Handle GitRevWalk::Push(const Arguments& args) { HandleScope scope; - GitRevWalk *revwalk = ObjectWrap::Unwrap(args.This()); if(args.Length() == 0 || !args[0]->IsObject()) { return ThrowException(Exception::Error(String::New("Oid is required and must be an Object."))); } - GitOid *oid = ObjectWrap::Unwrap(args[0]->ToObject()); + if(args.Length() == 1 || !args[1]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); + } + + PushBaton* baton = new PushBaton(); - git_oid tmp = oid->GetValue(); - int err = revwalk->Push(&tmp); + baton->request.data = baton; + baton->revwalk = ObjectWrap::Unwrap(args.This())->GetValue(); + baton->oid = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); + baton->callback = Persistent::New(Local::Cast(args[1])); - return scope.Close( Integer::New(err) ); + uv_queue_work(uv_default_loop(), &baton->request, PushWork, PushAfterWork); + + return Undefined(); } -Handle GitRevWalk::Next(const Arguments& args) { +void GitRevWalk::PushWork(uv_work_t *req) { + PushBaton *baton = static_cast(req->data); + + git_revwalk_sorting(baton->revwalk, GIT_SORT_TIME | GIT_SORT_REVERSE); + + int returnCode = git_revwalk_push(baton->revwalk, &baton->oid); + if (returnCode) { + baton->error = giterr_last(); + } +} + +void GitRevWalk::PushAfterWork(uv_work_t *req) { HandleScope scope; - GitRevWalk* revwalk = ObjectWrap::Unwrap(args.This()); - Local callback; + PushBaton *baton = static_cast(req->data); + delete req; - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Oid is required and must be an Object."))); + Local argv[1]; + if (baton->error) { + argv[0] = GitError::WrapError(baton->error); + } else { + argv[0] = Local::New(Null()); } - if(args.Length() == 1 || !args[1]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); + TryCatch try_catch; + + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); } +} - callback = Local::Cast(args[1]); +Handle GitRevWalk::Next(const Arguments& args) { + HandleScope scope; - next_request* ar = new next_request(); - ar->revwalk = revwalk; - ar->oid = ObjectWrap::Unwrap(args[0]->ToObject()); - ar->callback = Persistent::New(callback); + if(args.Length() == 0 || !args[0]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); + } - revwalk->Ref(); + NextBaton* baton = new NextBaton(); - uv_work_t *req = new uv_work_t; - req->data = ar; - uv_queue_work(uv_default_loop(), req, EIO_Next, EIO_AfterNext); + baton->request.data = baton; + baton->revwalk = ObjectWrap::Unwrap(args.This())->GetValue(); + baton->walkOver = false; + baton->callback = Persistent::New(Local::Cast(args[0])); - return scope.Close( Undefined() ); -} + uv_queue_work(uv_default_loop(), &baton->request, NextWork, NextAfterWork); -void GitRevWalk::EIO_Next(uv_work_t *req) { - next_request *ar = static_cast(req->data); - git_oid oid = ar->oid->GetValue(); + return Undefined(); +} - ar->err = ar->revwalk->Next(&oid); - ar->oid->SetValue(oid); +void GitRevWalk::NextWork(uv_work_t *req) { + NextBaton *baton = static_cast(req->data); + // baton->oid = NULL; + int returnCode = git_revwalk_next(&baton->oid, baton->revwalk); + if (returnCode != GIT_OK) { + if (returnCode == GIT_REVWALKOVER) { + baton->walkOver = true; + } else { + baton->error = giterr_last(); + } + } } -void GitRevWalk::EIO_AfterNext(uv_work_t *req) { +void GitRevWalk::NextAfterWork(uv_work_t *req) { HandleScope scope; - next_request *ar = static_cast(req->data); + NextBaton *baton = static_cast(req->data); delete req; - ar->revwalk->Unref(); - Local argv[1]; - argv[0] = Integer::New(ar->err); + if (baton->error) { + Local argv[1] = { + GitError::WrapError(baton->error) + }; - TryCatch try_catch; + TryCatch try_catch; + + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { - ar->callback->Call(Context::GetCurrent()->Global(), 1, argv); + Local oid = GitOid::constructor_template->NewInstance(); + GitOid *oidInstance = ObjectWrap::Unwrap(oid); + oidInstance->SetValue(baton->oid); - if(try_catch.HasCaught()) - FatalException(try_catch); + Local argv[3] = { + Local::New(Null()), + oid, + Local::New(Boolean::New(baton->walkOver)) + }; - ar->callback.Dispose(); + TryCatch try_catch; - delete ar; + baton->callback->Call(Context::GetCurrent()->Global(), 3, argv); + + if(try_catch.HasCaught()) { + FatalException(try_catch); + } + } } Handle GitRevWalk::Free(const Arguments& args) { From 225d8528db457de75f42ba6bdbd81a1f9a0bd0d6 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:09:22 +1300 Subject: [PATCH 031/120] Removed sync open method --- include/repo.h | 10 ++-------- src/repo.cc | 4 ---- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/include/repo.h b/include/repo.h index 322f5b3b3..3677628f2 100755 --- a/include/repo.h +++ b/include/repo.h @@ -22,20 +22,14 @@ class GitRepo : public ObjectWrap { static void Initialize(Handle target); git_repository* GetValue(); void SetValue(git_repository* repo); + // Asynchronous int Open(const char* path); int Init(const char* path, bool is_bare); + // Synchronous void Free(); - // TODO: Implement these methods - //int Open2(const char* path); - //int Open3(const char* path); - //int Lookup(Object **obj, Oid *id, Otype type); - //Odb Database(); - //int Index(Index **index); - //int NewObject(git_object **obj, Otype type); - protected: GitRepo() {} ~GitRepo() {} diff --git a/src/repo.cc b/src/repo.cc index 2a9b153f1..6bff4ff0b 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -40,10 +40,6 @@ void GitRepo::SetValue(git_repository* repo) { this->repo = repo; } -int GitRepo::Open(const char* path) { - return git_repository_open(&this->repo, path); -} - void GitRepo::Free() { git_repository_free(this->repo); } From bc4d4e049aef7fa080608390b74cf8601ec2bb72 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:09:51 +1300 Subject: [PATCH 032/120] Updated install to use libgit2 .17 --- install.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.js b/install.js index 1207a4a43..c4a2be730 100644 --- a/install.js +++ b/install.js @@ -47,9 +47,9 @@ var updateSubmodules = function(mainCallback) { var checkoutDependencies = function(mainCallback) { console.log('[nodegit] Downloading libgit2 dependency.'); - var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/v0.15.0.zip'; + var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/v0.17.0.zip'; zipFile = __dirname + '/vendor/libgit2.zip', - unzippedFolderName = __dirname + '/vendor/libgit2-0.15.0', + unzippedFolderName = __dirname + '/vendor/libgit2-0.17.0', targetFolderName = __dirname + '/vendor/libgit2'; async.series([ From ff92fb1f78b7fbb51e312585f4f80bb4fc41f4ec Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:12:32 +1300 Subject: [PATCH 033/120] Whitesace --- test/convenience-commit.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index 846b120cc..022975c44 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -30,9 +30,7 @@ var helper = { */ exports.method = function(test){ test.expect(2); - helper.testFunction(test.equals, git.commit, 'Commmit'); - test.done(); }; @@ -69,7 +67,6 @@ exports.history = function(test) { test.equals(error, null, 'There should be no errors'); historyCount++; }).on('end', function(error, commits) { - test.equals(error, null, 'There should be no errors'); test.equals(historyCount, expectedHistoryCount, 'Manual count does not match expected'); test.equals(commits.length, expectedHistoryCount, '"end" count does not match expected'); From f7d7942caeed1a88177647859755689037b17f24 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:12:57 +1300 Subject: [PATCH 034/120] Updated oid tests --- test/raw-oid.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/raw-oid.js b/test/raw-oid.js index 3ebf4fdaa..d66b3c966 100644 --- a/test/raw-oid.js +++ b/test/raw-oid.js @@ -23,11 +23,11 @@ var helper = { }; // Oid -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Oid, 'Oid' ); + helper.testFunction(test.equals, git.Oid, 'Oid'); // Ensure we get an instance of Oid test.ok( new git.Oid() instanceof git.Oid, 'Invocation returns an instance of Oid' ); @@ -55,10 +55,10 @@ exports.mkstr = function( test ) { }, 'No exception is thrown with proper arguments' ); // Test invalid hex id string - test.equals( -2, testOid.mkstr( '1392DLFJIOS' ), 'Invalid hex id String' ); + test.equals(git.Error.returnCodes.GIT_ERROR, testOid.mkstr('1392DLFJIOS'), 'Invalid hex id String'); // Test valid hex id string - test.equals( 0, testOid.mkstr( '1810DFF58D8A660512D4832E740F692884338CCD' ), 'Valid hex id String' ); + test.equals(git.Error.returnCodes.GIT_OK, testOid.mkstr( '1810DFF58D8A660512D4832E740F692884338CCD' ), 'Valid hex id String'); test.done(); }; From 9d9ef7f7cb010054d2afd67ca0b7c14ef7d2f673 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:13:13 +1300 Subject: [PATCH 035/120] Updated raw commit test --- test/raw-commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/raw-commit.js b/test/raw-commit.js index c563bdd18..02479b4ad 100644 --- a/test/raw-commit.js +++ b/test/raw-commit.js @@ -113,11 +113,11 @@ exports.fetchDetails = function(test) { committer: { name: 'Tim Branyen', email: 'tim.branyen@gmail.com', - when: { when: 1300145116, offset: -240 } }, + when: { time: 1300145116, offset: -240 } }, author: { name: 'Tim Branyen', email: 'tim.branyen@gmail.com', - when: { when: 1300145116, offset: -240 } }, + when: { time: 1300145116, offset: -240 } }, parentCount: 1, parentShas: [ 'b1f941c62f508db5f392a6bb0ea1d591753a045b' ] }; From 0b1c9b6f57f57fed47a415c1762da9f83ee58f5c Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:13:38 +1300 Subject: [PATCH 036/120] Updated raw-repo test --- test/raw-repo.js | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/test/raw-repo.js b/test/raw-repo.js index 20fc927d3..e51af83f1 100644 --- a/test/raw-repo.js +++ b/test/raw-repo.js @@ -12,7 +12,7 @@ var helper = { // This ensures the repo is actually a derivative of the Function [[Class]] test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); }, - // Test code and handle exception thrown + // Test code and handle exception thrown testException: function( test, fun, label ) { try { fun(); @@ -30,7 +30,7 @@ exports.constructor = function( test ){ // Test for function helper.testFunction( test.equals, git.Repo, 'Repo' ); - + // Ensure we get an instance of Repo test.ok( new git.Repo() instanceof git.Repo, 'Invocation returns an instance of Repo' ); @@ -38,34 +38,31 @@ exports.constructor = function( test ){ }; // Repo::Open -exports.open = function( test ) { +exports.open = function(test) { var testRepo = new git.Repo(); - test.expect( 6 ); + test.expect(6); // Test for function - helper.testFunction( test.equals, testRepo.open, 'Repo::Open' ); + helper.testFunction(test.equals, testRepo.open, 'Repo::Open'); // Test path argument existence helper.testException( test.ok, function() { testRepo.open(); }, 'Throw an exception if no path' ); - + // Test callback argument existence - helper.testException( test.ok, function() { - testRepo.open( "some/path" ); - }, 'Throw an exception if no callback' ); + helper.testException(test.ok, function() { + testRepo.open('some/path'); + }, 'Throw an exception if no callback'); // Test invalid repository - testRepo.open( '/etc/hosts', function( err ) { - test.equals( -7, err, 'Invalid repository error code' ); + testRepo.open('/etc/hosts', function(error) { + test.equals(git.Error.codes.GIT_ERROR, error.klass, 'Invalid repository error code'); // Test valid repository - testRepo.open( path.resolve( '../.git' ), function( err ) { - test.equals( 0, err, 'Valid repository error code' ); - -// testRepo.free(); - + testRepo.open(path.resolve('../.git'), function(error) { + test.equals(0, error, 'Valid repository error code'); test.done(); }); }); @@ -73,13 +70,13 @@ exports.open = function( test ) { // TODO: Figure out how write unit tests for free // Repo::Free -exports.free = function( test ) { +exports.free = function(test) { var testRepo = new git.Repo(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testRepo.free, 'Repo::Free' ); + helper.testFunction(test.equals, testRepo.free, 'Repo::Free'); test.done(); }; @@ -97,7 +94,7 @@ exports.init = function( test ) { helper.testException( test.ok, function() { testRepo.init(); }, 'Throw an exception if no path' ); - + // Test is_bare argument existence helper.testException( test.ok, function() { testRepo.init( "some/path" ); @@ -117,7 +114,7 @@ exports.init = function( test ) { testRepo.open( './test.git', function(err, path) { test.equals( 0, err, 'Valid repository created' ); - testRepo.free(); + testRepo.free(); // Cleanup, remove test repo directory rimraf( './test.git', function() { From 86a230587885d73583bef65781dee845e947c655 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:14:04 +1300 Subject: [PATCH 037/120] Updated raw error tests --- test/raw-error.js | 55 +++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/test/raw-error.js b/test/raw-error.js index 075a3d805..bf9658afa 100644 --- a/test/raw-error.js +++ b/test/raw-error.js @@ -23,42 +23,45 @@ var helper = { }; // Error -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Error, 'Error' ); + helper.testFunction(test.equals, git.Error, 'Error'); // Ensure we get an instance of Error - test.ok( new git.Error() instanceof git.Error, 'Invocation returns an instance of Error' ); + test.ok(new git.Error() instanceof git.Error, 'Invocation returns an instance of Error'); test.done(); }; -// Error::StrError -exports.str_error = function( test ) { - var testError = new git.Error(); +exports.codes = function(test) { + test.expect(23); - test.expect( 6 ); + test.equals(git.Error.returnCodes.GIT_OK, 0, 'GIT_OK should equal 0'), + test.equals(git.Error.returnCodes.GIT_ERROR, -1, 'GIT_ERROR should equal -1'), + test.equals(git.Error.returnCodes.GIT_ENOTFOUND, -3, 'GIT_ENOTFOUND should equal -3'), + test.equals(git.Error.returnCodes.GIT_EEXISTS, -4, 'GIT_EEXISTS should equal -4'), + test.equals(git.Error.returnCodes.GIT_EAMBIGUOUS, -5, 'GIT_EAMBIGUOUS should equal -5'), + test.equals(git.Error.returnCodes.GIT_EBUFS, -6, 'GIT_EBUFS should equal -6'), + test.equals(git.Error.returnCodes.GIT_PASSTHROUGH, -30, 'GIT_PASSTHROUGH should equal -30'), + test.equals(git.Error.returnCodes.GIT_REVWALKOVER, -31, 'GIT_REVWALKOVER should equal -31'), - // Test for function - helper.testFunction( test.equals, testError.strError, 'Error::StrError' ); - - // Test path argument existence - helper.testException( test.ok, function() { - testError.strError(); - }, 'Throw an exception if no error code' ); - - // Test that arguments result correctly - helper.testException( test.ifError, function() { - testError.strError( 0 ); - }, 'No exception is thrown with proper arguments' ); - - // Finding an actual error - test.equals( 'Input was not a properly formatted Git object id.', testError.strError( -2 ), 'Returns proper error message per code.' ); - - // Returning a consistent error message for all unknown errors - test.equals( 'Unknown error', testError.strError( 1000 ), 'Returns consistent error message with an unknown.' ); + test.equals(git.Error.codes.GITERR_NOMEMORY, 0, 'GITERR_NOMEMORY should equal 0'); + test.equals(git.Error.codes.GITERR_OS, 1, 'GITERR_OS should equal 1'); + test.equals(git.Error.codes.GITERR_INVALID, 2, 'GITERR_INVALID should equal 2'); + test.equals(git.Error.codes.GITERR_REFERENCE, 3, 'GITERR_REFERENCE should equal 3'); + test.equals(git.Error.codes.GITERR_ZLIB, 4, 'GITERR_ZLIB should equal 4'); + test.equals(git.Error.codes.GITERR_REPOSITORY, 5, 'GITERR_REPOSITORY should equal 5'); + test.equals(git.Error.codes.GITERR_CONFIG, 6, 'GITERR_CONFIG should equal 6'); + test.equals(git.Error.codes.GITERR_REGEX, 7, 'GITERR_REGEX should equal 7'); + test.equals(git.Error.codes.GITERR_ODB, 8, 'GITERR_ODB should equal 8'); + test.equals(git.Error.codes.GITERR_INDEX, 9, 'GITERR_INDEX should equal 9'); + test.equals(git.Error.codes.GITERR_OBJECT, 10, 'GITERR_OBJECT should equal 10'); + test.equals(git.Error.codes.GITERR_NET, 11, 'GITERR_NET should equal 11'); + test.equals(git.Error.codes.GITERR_TAG, 12, 'GITERR_TAG should equal 12'); + test.equals(git.Error.codes.GITERR_TREE, 13, 'GITERR_TREE should equal 13'); + test.equals(git.Error.codes.GITERR_INDEXER, 14, 'GITERR_INDEXER should equal 14'); test.done(); }; From c6a995e55e3dd224f059eaf4300ec59b2ab7904e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:54:19 +1300 Subject: [PATCH 038/120] Updated repo.cc initialization --- include/repo.h | 2 +- src/repo.cc | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/repo.h b/include/repo.h index 3677628f2..ef2fa0b0f 100755 --- a/include/repo.h +++ b/include/repo.h @@ -18,7 +18,7 @@ using namespace v8; class GitRepo : public ObjectWrap { public: - static Persistent constructor_template; + static Persistent constructor_template; static void Initialize(Handle target); git_repository* GetValue(); void SetValue(git_repository* repo); diff --git a/src/repo.cc b/src/repo.cc index 6bff4ff0b..c69faa20b 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -18,18 +18,18 @@ using namespace node; void GitRepo::Initialize(Handle target) { HandleScope scope; - Local t = FunctionTemplate::New(New); + Local tpl = FunctionTemplate::New(New); - constructor_template = Persistent::New(t); - constructor_template->InstanceTemplate()->SetInternalFieldCount(1); - constructor_template->SetClassName(String::NewSymbol("Repo")); + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("Repo")); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "open", Open); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "lookup", Lookup); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "free", Free); - NODE_SET_PROTOTYPE_METHOD(constructor_template, "init", Init); + NODE_SET_PROTOTYPE_METHOD(tpl, "open", Open); + NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup); + NODE_SET_PROTOTYPE_METHOD(tpl, "free", Free); + NODE_SET_PROTOTYPE_METHOD(tpl, "init", Init); - target->Set(String::NewSymbol("Repo"), constructor_template->GetFunction()); + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("Repo"), constructor_template); } git_repository* GitRepo::GetValue() { @@ -280,4 +280,4 @@ void GitRepo::EIO_AfterInit(uv_work_t *req) { delete ar; } -Persistent GitRepo::constructor_template; +Persistent GitRepo::constructor_template; From 999dd711ad7b6af3e991d8c780a064b139aad33e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:54:41 +1300 Subject: [PATCH 039/120] Removed async stub --- lib/repo.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/repo.js b/lib/repo.js index 64313ed38..c90d1a47a 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -49,11 +49,6 @@ exports.repo = function(dir, async) { }; self.init = function(dir, isBare, async) { - if (!async) { - // TODO: Implement Sync API - return; - } - self.repo.init(dir, isBare, function() { git.util().asyncComplete.call(this, arguments, async); }); From 22402dd0719cb75ac50d23c2b56a81b06feb85ab Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:55:17 +1300 Subject: [PATCH 040/120] Refactored repo open async --- include/repo.h | 13 +++++---- lib/repo.js | 51 ++++++++++++++++++--------------- src/repo.cc | 76 ++++++++++++++++++++++++++++---------------------- 3 files changed, 80 insertions(+), 60 deletions(-) diff --git a/include/repo.h b/include/repo.h index ef2fa0b0f..e83d15b16 100755 --- a/include/repo.h +++ b/include/repo.h @@ -36,8 +36,8 @@ class GitRepo : public ObjectWrap { static Handle New(const Arguments& args); static Handle Open(const Arguments& args); - static void EIO_Open(uv_work_t* req); - static void EIO_AfterOpen(uv_work_t* req); + static void OpenWork(uv_work_t* req); + static void OpenAfterWork(uv_work_t* req); static Handle Lookup(const Arguments& args); static void EIO_Lookup(uv_work_t* req); @@ -52,10 +52,13 @@ class GitRepo : public ObjectWrap { private: git_repository* repo; - struct open_request { - GitRepo* repo; - int err; + struct OpenBaton { + uv_work_t request; + const git_error* error; + + git_repository* repo; std::string path; + Persistent callback; }; diff --git a/lib/repo.js b/lib/repo.js index c90d1a47a..5b69defaa 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -3,38 +3,45 @@ var git = require("../"); /* Module: Repo * Work with a repository. */ -exports.repo = function(dir, async) { +exports.repo = function(directory, callback) { var self = { // Assign a new repo object repo: new git.raw.Repo() }; - if (dir && async) { - self.repo.open(dir, function() { - git.util().asyncComplete.call(self, arguments, async); + if (directory) { + if (!callback || typeof callback !== 'function') { + throw new Error('If directory is provided, callback function is required'); + } + self.repo.open(directory, function(error, repository) { + if (error) { + callback(git.error(error), null); + return; + } + self.repo = repository; + callback(null, self); }); } - else if (dir) { - // TODO: Make this eventually - // this.repo.openSync(path.resolve(dir) - //this.repo.open(path.resolve(dir) - self.repo.open(dir); - } - - // Look up a branch and find its tree - self.branch = function(name, async) { - if (!async) { - // TODO: Implement Sync API - return; - } - git.ref(self.repo).lookup("refs/heads/" + name, function(err, ref) { - if (err) { - return git.util().asyncComplete.call(this, arguments, async); + /** + * Look up a branch and find its tree. + * + * @param {String} name Branch name, e.g. 'master' + * @param {Function} + */ + self.branch = function(name, callback) { + git.ref(self.repo).lookup('refs/heads/' + name, function(error, ref) { + if (error) { + callback(git.error(error), null); + return; } - git.commit(self.repo).lookup(self.repo, ref.oid().oid, function() { - git.util().asyncComplete.call(this, arguments, async); + git.commit(self.repo).lookup(self.repo, ref.oid().oid, function(error, commit) { + if (error) { + callback(git.error(error), null); + return; + } + callback(null, commit); }); }); }; diff --git a/src/repo.cc b/src/repo.cc index c69faa20b..6e58889a5 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -11,6 +11,7 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../include/object.h" #include "../include/repo.h" #include "../include/commit.h" +#include "../include/error.h" using namespace v8; using namespace node; @@ -61,15 +62,12 @@ Handle GitRepo::New(const Arguments& args) { GitRepo *repo = new GitRepo(); repo->Wrap(args.This()); - return scope.Close( args.This() ); + return scope.Close(args.This()); } Handle GitRepo::Open(const Arguments& args) { HandleScope scope; - GitRepo *repo = ObjectWrap::Unwrap(args.This()); - Local callback; - if(args.Length() == 0 || !args[0]->IsString()) { return ThrowException(Exception::Error(String::New("Path is required and must be a String."))); } @@ -78,52 +76,64 @@ Handle GitRepo::Open(const Arguments& args) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - callback = Local::Cast(args[1]); - - open_request *ar = new open_request(); - ar->repo = repo; - + OpenBaton *baton = new OpenBaton(); + baton->request.data = baton; + baton->error = NULL; String::Utf8Value path(args[0]); - ar->path = *path; + baton->path = *path; + baton->callback = Persistent::New(Local::Cast(args[1])); - ar->callback = Persistent::New(callback); - - repo->Ref(); + uv_queue_work(uv_default_loop(), &baton->request, OpenWork, OpenAfterWork); - uv_work_t *req = new uv_work_t; - req->data = ar; - uv_queue_work(uv_default_loop(), req, EIO_Open, EIO_AfterOpen); - - return scope.Close( Undefined() ); + return Undefined(); } -void GitRepo::EIO_Open(uv_work_t *req) { - open_request *ar = static_cast(req->data); - - ar->err = ar->repo->Open(ar->path.c_str()); +void GitRepo::OpenWork(uv_work_t *req) { + OpenBaton *baton = static_cast(req->data); + int returnCode = git_repository_open(&baton->repo, baton->path.c_str()); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + } } -void GitRepo::EIO_AfterOpen(uv_work_t *req) { +void GitRepo::OpenAfterWork(uv_work_t *req) { HandleScope scope; - open_request *ar = static_cast(req->data); + OpenBaton *baton = static_cast(req->data); delete req; - ar->repo->Unref(); - Local argv[1]; - argv[0] = Integer::New(ar->err); + if (baton->error) { + Local argv[1] = { + GitError::WrapError(baton->error) + }; - TryCatch try_catch; + TryCatch try_catch; - ar->callback->Call(Context::GetCurrent()->Global(), 1, argv); + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - if(try_catch.HasCaught()) - FatalException(try_catch); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { - ar->callback.Dispose(); + Local repository = GitRepo::constructor_template->NewInstance(); + GitRepo *repositoryInstance = ObjectWrap::Unwrap(repository); + repositoryInstance->SetValue(baton->repo); - delete ar; + Handle argv[2] = { + Local::New(Null()), + repository + }; + + TryCatch try_catch; + + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } } Handle GitRepo::Lookup(const Arguments& args) { From 754532c19c0bf5798050726d72f6410bb9f58bde Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 12 Mar 2013 22:55:45 +1300 Subject: [PATCH 041/120] Updated convenience-repo tests --- test/convenience-repo.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/convenience-repo.js b/test/convenience-repo.js index d9f359dce..21107114c 100644 --- a/test/convenience-repo.js +++ b/test/convenience-repo.js @@ -16,8 +16,7 @@ var helper = { try { fun(); test(false, label); - } - catch (ex) { + } catch (ex) { test(true, label); } } @@ -37,13 +36,12 @@ exports.method = function(test){ }, 'Throw an exception if no callback'); // Test invalid repository - git.repo('/etc/hosts', function(err, path) { - test.equals('The specified repository is invalid', err.message, 'Invalid repository error code'); + git.repo('/etc/hosts', function(error, path) { + test.equals(error.code, error.GITERR_REPOSITORY, error.message, 'Invalid repository error code'); // Test valid repository - git.repo('../.git', function(err, path) { - test.equals(0, err, 'Valid repository error code'); - + git.repo('../.git', function(error, path) { + test.equals(null, error, 'Valid repository error code'); test.done(); }); }); From 87672c89c32646ba5dfacf907b47e9608f50a7fc Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 00:58:07 +1300 Subject: [PATCH 042/120] Updated libgit2 to b70bf922a1de35722904930c42467e95c889562f --- vendor/libgit2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/libgit2 b/vendor/libgit2 index 5b9fac39d..b70bf922a 160000 --- a/vendor/libgit2 +++ b/vendor/libgit2 @@ -1 +1 @@ -Subproject commit 5b9fac39d8a76b9139667c26a63e6b3f204b3977 +Subproject commit b70bf922a1de35722904930c42467e95c889562f From 0a9b553a307177c858f1a632341fab8b9a93596f Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:49:12 +1300 Subject: [PATCH 043/120] Added basic threads class to handle git_threads_init required in latest version of libgit2 --- binding.gyp | 3 ++- include/threads.h | 37 ++++++++++++++++++++++++++++++++ install.js | 9 ++++---- lib/threads.js | 36 +++++++++++++++++++++++++++++++ src/threads.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) create mode 100755 include/threads.h create mode 100644 lib/threads.js create mode 100755 src/threads.cc diff --git a/binding.gyp b/binding.gyp index 7902aedd6..7eafaa095 100644 --- a/binding.gyp +++ b/binding.gyp @@ -14,7 +14,8 @@ 'src/revwalk.cc', 'src/sig.cc', 'src/tree.cc', - 'src/tree_entry.cc' + 'src/tree_entry.cc', + 'src/threads.cc' ], 'todosources': [ ], diff --git a/include/threads.h b/include/threads.h new file mode 100755 index 000000000..92ce32d76 --- /dev/null +++ b/include/threads.h @@ -0,0 +1,37 @@ +/* + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ + +#include +#include + +#include "../vendor/libgit2/include/git2.h" + +using namespace node; +using namespace v8; + +/** + * Class wrapper for libgit2 git_threads_* + */ +class GitThreads : public ObjectWrap { + public: + /** + * v8::FunctionTemplate used to create Node.js constructor + */ + static Persistent constructor_template; + + static void Initialize (Handle target); + + static Handle Init(const Arguments& args); + + protected: + + GitThreads() {} + ~GitThreads() {} + + static Handle New(const Arguments& args); + +}; diff --git a/install.js b/install.js index c4a2be730..f9e31fe6c 100644 --- a/install.js +++ b/install.js @@ -47,9 +47,10 @@ var updateSubmodules = function(mainCallback) { var checkoutDependencies = function(mainCallback) { console.log('[nodegit] Downloading libgit2 dependency.'); - var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/v0.17.0.zip'; + var commit = 'b70bf922a1de35722904930c42467e95c889562f'; + var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip'; zipFile = __dirname + '/vendor/libgit2.zip', - unzippedFolderName = __dirname + '/vendor/libgit2-0.17.0', + unzippedFolderName = __dirname + '/vendor/libgit2-' + commit, targetFolderName = __dirname + '/vendor/libgit2'; async.series([ @@ -103,8 +104,8 @@ async.series([ }, function(callback) { console.log('[nodegit] Building native module.'); - // shpassthru('node-gyp configure --debug', callback); - shpassthru('node-gyp configure', callback); + shpassthru('node-gyp configure --debug', callback); + // shpassthru('node-gyp configure', callback); }, function(callback) { shpassthru('node-gyp build', callback); diff --git a/lib/threads.js b/lib/threads.js new file mode 100644 index 000000000..ae9f31efe --- /dev/null +++ b/lib/threads.js @@ -0,0 +1,36 @@ +var git = require('../'); + +var _Blob = function(obj) { + var self = {}; + + if( obj instanceof git.raw.Repo ) { + self.repo = obj; + self.blob = new git.raw.Blob( obj ); + } + else if( obj instanceof git.raw.Blob ) { + self.blob = obj; + } + + Object.defineProperty( self, 'raw', { + get: function() { + return self.blob.rawContent().toString(); + }, + enumerable: true + }); + + self.lookup = function( oid ) { + self.blob.lookup( self.repo, oid, function() { + var args = Array.prototype.slice.call( arguments ); + args[0] = git.util().error( args[0] ); + + callback.apply( self, args.concat( self ) ); + }); + }; + + return self; +}; + +exports.blob = _Blob; + + +exports = _Threads; diff --git a/src/threads.cc b/src/threads.cc new file mode 100755 index 000000000..14c4b7f1c --- /dev/null +++ b/src/threads.cc @@ -0,0 +1,54 @@ +/* + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ + +#include +#include +#include + +#include "../vendor/libgit2/include/git2.h" + +#include "../include/threads.h" +#include "../include/error.h" + +using namespace v8; +using namespace node; + +void GitThreads::Initialize(Handle target) { + HandleScope scope; + + Local tpl = FunctionTemplate::New(New); + + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("Threads")); + + NODE_SET_PROTOTYPE_METHOD(tpl, "init", Init); + + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("Threads"), constructor_template); +} + +Handle GitThreads::New(const Arguments& args) { + HandleScope scope; + + GitThreads *threads = new GitThreads(); + + threads->Wrap(args.This()); + + return scope.Close(args.This()); +} + +Handle GitThreads::Init(const Arguments& args) { + HandleScope scope; + + int returnCode = git_threads_init(); + if (returnCode) { + return GitError::WrapError(giterr_last()); + } + return True(); +} + +Persistent GitThreads::constructor_template; From 551739fab90a33c46e59d82d9a747d59b2b46497 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:49:40 +1300 Subject: [PATCH 044/120] Updated error to work with latests lib version --- src/error.cc | 4 ++-- test/raw-error.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/error.cc b/src/error.cc index d8171633d..85c87dc74 100755 --- a/src/error.cc +++ b/src/error.cc @@ -27,7 +27,7 @@ typedef enum { _GIT_EBUFS = -6, _GIT_PASSTHROUGH = -30, - _GIT_REVWALKOVER = -31, + _GIT_ITEROVER = -31, } git_error_return_t; namespace cvv8 { @@ -75,7 +75,7 @@ void GitError::Initialize (Handle target) { libgit2ReturnCodes->Set(String::NewSymbol("GIT_EAMBIGUOUS"), cvv8::CastToJS(_GIT_EAMBIGUOUS), ReadOnly); libgit2ReturnCodes->Set(String::NewSymbol("GIT_EBUFS"), cvv8::CastToJS(_GIT_EBUFS), ReadOnly); libgit2ReturnCodes->Set(String::NewSymbol("GIT_PASSTHROUGH"), cvv8::CastToJS(_GIT_PASSTHROUGH), ReadOnly); - libgit2ReturnCodes->Set(String::NewSymbol("GIT_REVWALKOVER"), cvv8::CastToJS(_GIT_REVWALKOVER), ReadOnly); + libgit2ReturnCodes->Set(String::NewSymbol("GIT_ITEROVER"), cvv8::CastToJS(_GIT_ITEROVER), ReadOnly); constructor_template = Persistent::New(tpl->GetFunction()); constructor_template->Set(String::NewSymbol("codes"), libgit2Errors, ReadOnly); diff --git a/test/raw-error.js b/test/raw-error.js index bf9658afa..622f4d54e 100644 --- a/test/raw-error.js +++ b/test/raw-error.js @@ -45,7 +45,7 @@ exports.codes = function(test) { test.equals(git.Error.returnCodes.GIT_EAMBIGUOUS, -5, 'GIT_EAMBIGUOUS should equal -5'), test.equals(git.Error.returnCodes.GIT_EBUFS, -6, 'GIT_EBUFS should equal -6'), test.equals(git.Error.returnCodes.GIT_PASSTHROUGH, -30, 'GIT_PASSTHROUGH should equal -30'), - test.equals(git.Error.returnCodes.GIT_REVWALKOVER, -31, 'GIT_REVWALKOVER should equal -31'), + test.equals(git.Error.returnCodes.GIT_ITEROVER, -31, 'GIT_ITEROVER should equal -31'), test.equals(git.Error.codes.GITERR_NOMEMORY, 0, 'GITERR_NOMEMORY should equal 0'); test.equals(git.Error.codes.GITERR_OS, 1, 'GITERR_OS should equal 1'); From bb3202c598d7a454b5f8da9444d597a4bf3e61ab Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:50:26 +1300 Subject: [PATCH 045/120] libgit2 api change --- src/blob.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blob.cc b/src/blob.cc index c627a3ff2..bc501cc52 100755 --- a/src/blob.cc +++ b/src/blob.cc @@ -61,7 +61,7 @@ void GitBlob::Close() { } int CreateFromFile(git_oid* oid, git_repository* repo, const char* path) { - return git_blob_create_fromfile(oid, repo, path); + return git_blob_create_fromdisk(oid, repo, path); } int CreateFromBuffer(git_oid* oid, git_repository* repo, const void* buffer, size_t len) { From 28b06577b992a50e4748dc452d2fe8920c57b845 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:50:34 +1300 Subject: [PATCH 046/120] Added threads to base --- src/base.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/base.cc b/src/base.cc index a74f08273..d70063902 100755 --- a/src/base.cc +++ b/src/base.cc @@ -18,6 +18,7 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../include/revwalk.h" #include "../include/tree.h" #include "../include/tree_entry.h" +#include "../include/threads.h" extern "C" void init(Handle target) { HandleScope scope; @@ -33,4 +34,5 @@ extern "C" void init(Handle target) { GitRevWalk::Initialize(target); GitTree::Initialize(target); GitTreeEntry::Initialize(target); + GitThreads::Initialize(target); } From 43ae3dfc9d6d93ebe8d8fda6c1e5caf88f3473ae Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:50:42 +1300 Subject: [PATCH 047/120] Whitespace --- src/oid.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oid.cc b/src/oid.cc index d66c0df28..016246d38 100755 --- a/src/oid.cc +++ b/src/oid.cc @@ -119,7 +119,7 @@ Handle GitOid::Fmt(const Arguments& args) { char buffer[40]; oid->Fmt(buffer); - return scope.Close( String::New(buffer) ); + return scope.Close(String::New(buffer)); } Handle GitOid::PathFmt(const Arguments& args) { From a2c59f13bdcb326d61a37daafff6cbf06cec74ec Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:51:46 +1300 Subject: [PATCH 048/120] Removed sync open method, refactored async --- src/repo.cc | 50 +++++++++++++------------------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/src/repo.cc b/src/repo.cc index 6e58889a5..3c067259c 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -45,17 +45,6 @@ void GitRepo::Free() { git_repository_free(this->repo); } -int GitRepo::Init(const char* path, bool is_bare) { - git_repository* repo_; - int err = git_repository_init(&repo_, path, is_bare); - - if(err == 0) { - this->repo = *&repo_; - } - - return err; -} - Handle GitRepo::New(const Arguments& args) { HandleScope scope; @@ -81,6 +70,9 @@ Handle GitRepo::Open(const Arguments& args) { baton->error = NULL; String::Utf8Value path(args[0]); baton->path = *path; + baton->repo = ObjectWrap::Unwrap(args.This()); + baton->repo->Ref(); + baton->rawRepo = baton->repo->GetValue(); baton->callback = Persistent::New(Local::Cast(args[1])); uv_queue_work(uv_default_loop(), &baton->request, OpenWork, OpenAfterWork); @@ -91,7 +83,7 @@ Handle GitRepo::Open(const Arguments& args) { void GitRepo::OpenWork(uv_work_t *req) { OpenBaton *baton = static_cast(req->data); - int returnCode = git_repository_open(&baton->repo, baton->path.c_str()); + int returnCode = git_repository_open(&baton->rawRepo, baton->path.c_str()); if (returnCode != GIT_OK) { baton->error = giterr_last(); } @@ -102,37 +94,21 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { OpenBaton *baton = static_cast(req->data); delete req; + baton->repo->Unref(); + Local argv[1]; if (baton->error) { - Local argv[1] = { - GitError::WrapError(baton->error) - }; - - TryCatch try_catch; - - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } + argv[0] = GitError::WrapError(baton->error); } else { + argv[0] = Local::New(Null()); + } - Local repository = GitRepo::constructor_template->NewInstance(); - GitRepo *repositoryInstance = ObjectWrap::Unwrap(repository); - repositoryInstance->SetValue(baton->repo); - - Handle argv[2] = { - Local::New(Null()), - repository - }; - - TryCatch try_catch; + TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - if (try_catch.HasCaught()) { - node::FatalException(try_catch); - } + if (try_catch.HasCaught()) { + node::FatalException(try_catch); } } From 4f0799144e4de69735b10044be3a3b448431b711 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:51:56 +1300 Subject: [PATCH 049/120] Refactored repo init --- include/repo.h | 18 +++++++++----- lib/repo.js | 16 ++++++------- src/repo.cc | 64 ++++++++++++++++++++++++-------------------------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/include/repo.h b/include/repo.h index e83d15b16..b6d82f8a4 100755 --- a/include/repo.h +++ b/include/repo.h @@ -46,8 +46,8 @@ class GitRepo : public ObjectWrap { static Handle Free(const Arguments& args); static Handle Init(const Arguments& args); - static void EIO_Init(uv_work_t* req); - static void EIO_AfterInit(uv_work_t* req); + static void InitWork(uv_work_t* req); + static void InitAfterWork(uv_work_t* req); private: git_repository* repo; @@ -56,7 +56,9 @@ class GitRepo : public ObjectWrap { uv_work_t request; const git_error* error; - git_repository* repo; + git_repository* rawRepo; + GitRepo *repo; + std::string path; Persistent callback; @@ -67,11 +69,15 @@ class GitRepo : public ObjectWrap { Persistent callback; }; - struct init_request { + struct InitBaton { + uv_work_t request; + const git_error* error; + GitRepo* repo; - int err; + git_repository* rawRepo; std::string path; - bool is_bare; + bool isBare; + Persistent callback; }; }; diff --git a/lib/repo.js b/lib/repo.js index 5b69defaa..aeca1b415 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -13,12 +13,11 @@ exports.repo = function(directory, callback) { if (!callback || typeof callback !== 'function') { throw new Error('If directory is provided, callback function is required'); } - self.repo.open(directory, function(error, repository) { + self.repo.open(directory, function(error) { if (error) { callback(git.error(error), null); return; } - self.repo = repository; callback(null, self); }); } @@ -48,19 +47,20 @@ exports.repo = function(directory, callback) { // Find a single commit self.commit = function(sha, callback) { - git.commit().lookup(self.repo, git.oid(sha).oid, callback); + git.commit().lookup(self.repo, sha, function(error, commit) { + callback(error, commit); + }); }; self.commitSync = function(sha) { throw new Error('commitSync not yet implemented'); + // return git.commit().lookupSync(sha); }; - self.init = function(dir, isBare, async) { - self.repo.init(dir, isBare, function() { - git.util().asyncComplete.call(this, arguments, async); + self.init = function(directory, isBare, callback) { + self.repo.init(directory, isBare, function(error) { + callback.call(this, error, self); }); - - return self; }; self.free = function() { diff --git a/src/repo.cc b/src/repo.cc index 3c067259c..910145a4c 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -203,8 +203,6 @@ Handle GitRepo::Free(const Arguments& args) { Handle GitRepo::Init(const Arguments& args) { HandleScope scope; - GitRepo *repo = ObjectWrap::Unwrap(args.This()); - Local callback; if(args.Length() == 0 || !args[0]->IsString()) { return ThrowException(Exception::Error(String::New("path is required and must be a String."))); @@ -218,52 +216,52 @@ Handle GitRepo::Init(const Arguments& args) { return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); } - callback = Local::Cast(args[2]); - - init_request *ar = new init_request(); - ar->repo = repo; - + InitBaton *baton = new InitBaton(); + baton->request.data = baton; + baton->error = NULL; + baton->repo = ObjectWrap::Unwrap(args.This()); + baton->repo->Ref(); + baton->rawRepo = baton->repo->GetValue(); String::Utf8Value path(args[0]); - ar->path = *path; - - ar->is_bare = args[1]->ToBoolean()->Value(); - ar->callback = Persistent::New(callback); - - repo->Ref(); + baton->path = *path; + baton->isBare = args[1]->ToBoolean()->Value(); + baton->callback = Persistent::New(Local::Cast(args[2])); - uv_work_t *req = new uv_work_t; - req->data = ar; - uv_queue_work(uv_default_loop(), req, EIO_Init, EIO_AfterInit); + uv_queue_work(uv_default_loop(), &baton->request, InitWork, InitAfterWork); - return scope.Close( Undefined() ); + return Undefined(); } -void GitRepo::EIO_Init(uv_work_t *req) { - init_request *ar = static_cast(req->data); - - ar->err = ar->repo->Init(ar->path.c_str(), ar->is_bare); +void GitRepo::InitWork(uv_work_t *req) { + InitBaton *baton = static_cast(req->data); + int returnCode = git_repository_init(&baton->rawRepo, baton->path.c_str(), baton->isBare); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + } } -void GitRepo::EIO_AfterInit(uv_work_t *req) { +void GitRepo::InitAfterWork(uv_work_t *req) { HandleScope scope; - init_request *ar = static_cast(req->data); + InitBaton *baton = static_cast(req->data); delete req; - ar->repo->Unref(); + baton->repo->Unref(); - Local argv[2]; - argv[0] = Integer::New(ar->err); + Local argv[1]; + if (baton->error) { + argv[0] = GitError::WrapError(baton->error); + } else { + argv[0] = Local::New(Null()); + } TryCatch try_catch; - ar->callback->Call(Context::GetCurrent()->Global(), 1, argv); - - if(try_catch.HasCaught()) - FatalException(try_catch); - - ar->callback.Dispose(); + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - delete ar; + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } } + Persistent GitRepo::constructor_template; From 0fd56229881fb858f3455d280f9f5a5e4d13ca27 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 01:52:35 +1300 Subject: [PATCH 050/120] libgit2 api change --- src/commit.cc | 4 ++-- src/reference.cc | 2 +- src/revwalk.cc | 2 +- src/tree_entry.cc | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index b7982178f..d1db6ecae 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -139,7 +139,7 @@ Handle GitCommit::FetchDetailsSync(const Arguments& args) { int parentIndex = parentCount -1; char sha[GIT_OID_HEXSZ + 1]; sha[GIT_OID_HEXSZ] = '\0'; - const git_oid *parentOid = git_commit_parent_oid(commit->commit, parentIndex); + const git_oid *parentOid = git_commit_parent_id(commit->commit, parentIndex); git_oid_fmt(sha, parentOid); parentShas.push_back(sha); parentCount--; @@ -189,7 +189,7 @@ void GitCommit::FetchDetailsWork(uv_work_t *req) { int parentIndex = parentCount -1; char sha[GIT_OID_HEXSZ + 1]; sha[GIT_OID_HEXSZ] = '\0'; - const git_oid *parentOid = git_commit_parent_oid(baton->rawCommit, parentIndex); + const git_oid *parentOid = git_commit_parent_id(baton->rawCommit, parentIndex); git_oid_fmt(sha, parentOid); baton->parentShas.push_back(sha); parentCount--; diff --git a/src/reference.cc b/src/reference.cc index ac824c3b4..9c341c443 100755 --- a/src/reference.cc +++ b/src/reference.cc @@ -43,7 +43,7 @@ int GitReference::Lookup(git_repository* repo, const char* name) { } const git_oid* GitReference::Oid() { - return git_reference_oid(this->ref); + return git_reference_target(this->ref); } Handle GitReference::New(const Arguments& args) { diff --git a/src/revwalk.cc b/src/revwalk.cc index bb5dc6cd6..0776ce8ab 100755 --- a/src/revwalk.cc +++ b/src/revwalk.cc @@ -176,7 +176,7 @@ void GitRevWalk::NextWork(uv_work_t *req) { // baton->oid = NULL; int returnCode = git_revwalk_next(&baton->oid, baton->revwalk); if (returnCode != GIT_OK) { - if (returnCode == GIT_REVWALKOVER) { + if (returnCode == GIT_ITEROVER) { baton->walkOver = true; } else { baton->error = giterr_last(); diff --git a/src/tree_entry.cc b/src/tree_entry.cc index cd677008f..f8541fd18 100755 --- a/src/tree_entry.cc +++ b/src/tree_entry.cc @@ -45,7 +45,7 @@ const char* GitTreeEntry::Name() { } int GitTreeEntry::Attributes() { - return git_tree_entry_attributes(this->entry); + return git_tree_entry_filemode(this->entry); } const git_oid* GitTreeEntry::Id() { From 84afe8a0bb5ec3dd3f5f96ce0c66b29bcbaf605e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:15:26 +1300 Subject: [PATCH 051/120] Updated commit lookup --- include/commit.h | 7 +++++-- lib/commit.js | 8 +++++--- src/commit.cc | 36 +++++++++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/include/commit.h b/include/commit.h index 45951f10f..a4ac29303 100755 --- a/include/commit.h +++ b/include/commit.h @@ -1,5 +1,7 @@ /* * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * * Dual licensed under the MIT and GPL licenses. */ @@ -82,8 +84,9 @@ class GitCommit : public ObjectWrap { uv_work_t request; const git_error* error; - GitRepo* repo; - GitOid* oid; + git_repository* repo; + git_oid oid; + const char* sha; git_commit* rawCommit; Persistent callback; diff --git a/lib/commit.js b/lib/commit.js index 7ef8bd094..5d9097591 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -62,19 +62,21 @@ var _Commit = function(obj) { * with the result. * * @param {Repo} repo - * @param {Oid} oid + * @param {Oid|String} oid Raw OID object or SHA string * @param {Function} callback */ self.lookup = function(repo, oid, callback) { self.repo = repo; self.commit.lookup(repo, oid, function(error, commit) { if (error) { - return callback(git.error(error), null); + callback(git.error(error), null); + return; } self.commit = commit; self.fetchDetails(function(error) { if (error) { - return callback(git.error(error), null); + callback(git.error(error), null); + return; } callback(null, self); }); diff --git a/src/commit.cc b/src/commit.cc index d1db6ecae..8bd7f1214 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -1,5 +1,6 @@ /* * Copyright 2011, Tim Branyen @tbranyen + * * Dual licensed under the MIT and GPL licenses. */ @@ -16,7 +17,7 @@ #include "../include/oid.h" #include "../include/tree.h" #include "../include/commit.h" - #include "../include/error.h" +#include "../include/error.h" using namespace v8; using namespace cvv8; @@ -273,8 +274,8 @@ Handle GitCommit::Lookup(const Arguments& args) { return ThrowException(Exception::Error(String::New("Repo is required and must be an Object."))); } - if(args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("Oid is required and must be an Object."))); + if(args.Length() == 1 || !(args[1]->IsObject() || args[1]->IsString())) { + return ThrowException(Exception::Error(String::New("Oid is required and must be an Object or String"))); } if(args.Length() == 2 || !args[2]->IsFunction()) { @@ -284,8 +285,21 @@ Handle GitCommit::Lookup(const Arguments& args) { LookupBaton *baton = new LookupBaton(); baton->request.data = baton; baton->error = NULL; - baton->repo = ObjectWrap::Unwrap(args[0]->ToObject()); - baton->oid = ObjectWrap::Unwrap(args[1]->ToObject()); + baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); + + if (baton->repo == NULL) { + printf("BeforeWork: baton->repo is null\n"); + } + if (args[1]->IsObject()) { + baton->oid = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); + baton->sha = NULL; + } else { + // Make this less ugly + String::AsciiValue shaValue(args[1]->ToString()); + char *sha = (char *) malloc(shaValue.length() + 1); + strcpy(sha, *shaValue); + baton->sha = sha; + } baton->callback = Persistent::New(Local::Cast(args[2])); uv_queue_work(uv_default_loop(), &baton->request, LookupWork, LookupAfterWork); @@ -296,9 +310,17 @@ Handle GitCommit::Lookup(const Arguments& args) { void GitCommit::LookupWork(uv_work_t *req) { LookupBaton *baton = static_cast(req->data); + git_oid oid = baton->oid; + if (baton->sha != NULL) { + int returnCode = git_oid_fromstr(&oid, baton->sha); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + return; + } + } + baton->rawCommit = NULL; - git_oid oid = baton->oid->GetValue(); - int returnCode = git_commit_lookup(&baton->rawCommit, baton->repo->GetValue(), &oid); + int returnCode = git_commit_lookup(&baton->rawCommit, baton->repo, &oid); if (returnCode != GIT_OK) { baton->error = giterr_last(); } From 0457c65b550b42da03bbdccf81c35c0c10d5e9f1 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:16:11 +1300 Subject: [PATCH 052/120] Updated convenience-commit tests --- test/convenience-commit.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index 022975c44..59150c84c 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -60,14 +60,14 @@ exports.history = function(test) { test.expect(368); git.repo('../.git', function(error, repository) { repository.commit(historyCountKnownSHA, function(error, commit) { - test.equals(error, null, 'Getting latest branch commit should not error'); + test.equals(null, error, 'Getting latest branch commit should not error'); var historyCount = 0; var expectedHistoryCount = 364; commit.history().on('commit', function(error, commit) { - test.equals(error, null, 'There should be no errors'); + test.equals(null, error, 'There should be no errors'); historyCount++; }).on('end', function(error, commits) { - test.equals(error, null, 'There should be no errors'); + test.equals(null, error, 'There should be no errors'); test.equals(historyCount, expectedHistoryCount, 'Manual count does not match expected'); test.equals(commits.length, expectedHistoryCount, '"end" count does not match expected'); From 4b8c6e059c70f2a7d3cc6d371a83538dee90c3e1 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:16:22 +1300 Subject: [PATCH 053/120] Updated convenience-repo tests --- test/convenience-repo.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/test/convenience-repo.js b/test/convenience-repo.js index 21107114c..6d9cf23cf 100644 --- a/test/convenience-repo.js +++ b/test/convenience-repo.js @@ -22,9 +22,11 @@ var helper = { } }; -// Repo -// Ensure the repo method can handle opening repositories with async/sync -// signatures properly. +/** + * Repo + * Ensure the repo method can handle opening repositories with async/sync + * signatures properly. + */ exports.method = function(test){ test.expect(5); @@ -47,10 +49,13 @@ exports.method = function(test){ }); }; -// Repo::Init -// Ensure the init method can create repositories at the destination path and -// can create either bare/non-bare. This should work async/sync and provide -// the proper return values. +/** + * Repo::Init + * + * Ensure the init method can create repositories at the destination path and + * can create either bare/non-bare. This should work async/sync and provide + * the proper return values. + */ exports.init = function(test) { test.expect(4); @@ -59,11 +64,11 @@ exports.init = function(test) { // Cleanup, remove test repo directory - if it exists rimraf('./test.git', function() { // Create bare repo and test for creation - git.repo().init('./test.git', true, function(err, path, isBare) { - test.equals(0, err, 'Successfully created bare repository'); + git.repo().init('./test.git', true, function(error, path, isBare) { + test.equals(null, error, 'Successfully created bare repository'); // Verify repo exists - git.repo('./test.git', function(err, path, repo) { - test.equals(0, err, 'Valid repository created'); + git.repo('./test.git', function(error, path, repo) { + test.equals(null, error, 'Valid repository created'); // Cleanup, remove test repo directory rimraf('./test.git', test.done); From db48698d3b8bc8d14c5b28ba0e0176497f1f507b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:16:42 +1300 Subject: [PATCH 054/120] Added version extraction from package.json, added thread initialization --- lib/index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/index.js b/lib/index.js index 3d687095f..0e75909a7 100755 --- a/lib/index.js +++ b/lib/index.js @@ -2,7 +2,7 @@ var os = require("os"); // Required for Windows/Cygwin support -var root = [ __dirname, "/../vendor/libgit2/build/shared" ].join(""), +var root = [__dirname, "/../vendor/libgit2/build/shared"].join(""), path = process.env.PATH; if (~os.type().indexOf("CYGWIN") && !~path.indexOf(root)) { @@ -10,7 +10,6 @@ if (~os.type().indexOf("CYGWIN") && !~path.indexOf(root)) { } // Import libraries -exports.util = require("./util.js").util; exports.blob = require("./blob.js").blob; exports.repo = require("./repo.js").repo; exports.sig = require("./sig.js").sig; @@ -33,4 +32,8 @@ try { exports.error = require("./error.js").error; // Set version -exports.version = "0.0.7"; +var version = require('../package').version; +exports.version = version; + +// Initialize threads +(new exports.raw.Threads()).init(); From 5284f52c00b8f9a8de307bee499c51be0cab9044 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:16:51 +1300 Subject: [PATCH 055/120] Tidied ref --- lib/ref.js | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/ref.js b/lib/ref.js index 84d786a0e..5c244cece 100644 --- a/lib/ref.js +++ b/lib/ref.js @@ -1,32 +1,32 @@ -var git = require( '../' ); +var git = require('../'); -var _Ref = function( obj ) { +var _Ref = function(obj) { var self = {}; - if( obj instanceof git.raw.Repo ) { + if(obj instanceof git.raw.Repo) { self.repo = obj; - self.ref = new git.raw.Ref( obj ); - } - else if( obj instanceof git.raw.Ref ) { + self.ref = new git.raw.Ref(obj); + } else if(obj instanceof git.raw.Ref) { self.ref = obj; } - self.lookup = function( name, callback ) { - if( !callback ) { return; } - - self.ref.lookup( self.repo, name, function() { - var args = Array.prototype.slice.call( arguments ); - args[0] = git.util().error( args[0] ); - - callback.apply( self, args.concat( self ) ); + self.lookup = function(name, callback) { + if(!callback || typeof callback !== 'function') { + throw new Error('Callback is required and must be a function'); + } + + self.ref.lookup(self.repo, name, function(error) { + if (error) { + callback(git.error(error), self); + return; + } + callback(null, self); }); }; self.oid = function() { var oid = git.oid(); - - self.ref.oid( oid.oid ); - + self.ref.oid(oid.oid); return oid; }; From d5b84ce3b535c136e90903dd809b709c9cd01cdb Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:17:13 +1300 Subject: [PATCH 056/120] Set this->repo in open --- src/repo.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/repo.cc b/src/repo.cc index 910145a4c..b8c4d2fd3 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -94,6 +94,8 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { OpenBaton *baton = static_cast(req->data); delete req; + + baton->repo->SetValue(baton->rawRepo); baton->repo->Unref(); Local argv[1]; From b77fd3f44e32051468e717c776a1dfa9ba886a7a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:17:18 +1300 Subject: [PATCH 057/120] Removed util --- lib/util.js | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 lib/util.js diff --git a/lib/util.js b/lib/util.js deleted file mode 100644 index 256d91c94..000000000 --- a/lib/util.js +++ /dev/null @@ -1,24 +0,0 @@ -var git = require( '../' ); - -var _Util = function( error ) { - var self = {}; - - self.error = function error( err ) { - if(err !== 0) { - return git.error( err ); - } - - return 0; - }; - - self.asyncComplete = function(args, callback) { - args = Array.prototype.slice.call(args); - args[0] = git.util().error(args[0]); - - callback.apply(this, args.concat(this)); - }; - - return self; -}; - -exports.util = _Util; From 5ad2b0e5dd9f38d9f7f91594f48acc633966063a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 02:17:28 +1300 Subject: [PATCH 058/120] Updated raw-repo tests --- test/raw-repo.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/raw-repo.js b/test/raw-repo.js index e51af83f1..81ad6672b 100644 --- a/test/raw-repo.js +++ b/test/raw-repo.js @@ -25,14 +25,14 @@ var helper = { }; // Repo -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Repo, 'Repo' ); + helper.testFunction(test.equals, git.Repo, 'Repo'); // Ensure we get an instance of Repo - test.ok( new git.Repo() instanceof git.Repo, 'Invocation returns an instance of Repo' ); + test.ok(new git.Repo() instanceof git.Repo, 'Invocation returns an instance of Repo'); test.done(); }; @@ -62,7 +62,7 @@ exports.open = function(test) { // Test valid repository testRepo.open(path.resolve('../.git'), function(error) { - test.equals(0, error, 'Valid repository error code'); + test.equals(null, error, 'Valid repository error code'); test.done(); }); }); @@ -106,18 +106,18 @@ exports.init = function( test ) { }, 'Throw an exception if no callback' ); // Cleanup, remove test repo directory - if it exists - rimraf( './test.git', function() { + rimraf('./test.git', function() { // Create bare repo and test for creation - testRepo.init( './test.git', true, function( err, path, is_bare ) { - test.equals( 0, err, 'Successfully created bare repository' ); + testRepo.init('./test.git', true, function(error, path, is_bare) { + test.equals(null, error, 'Successfully created bare repository'); // Verify repo exists - testRepo.open( './test.git', function(err, path) { - test.equals( 0, err, 'Valid repository created' ); + testRepo.open('./test.git', function(error, path) { + test.equals(null, error, 'Valid repository created'); testRepo.free(); // Cleanup, remove test repo directory - rimraf( './test.git', function() { + rimraf('./test.git', function() { test.done(); }); }); From 34306bf17818e1a22647e3327414e61cf17a9abd Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 22:35:09 +1300 Subject: [PATCH 059/120] Removed debug statement, tidy up. --- src/commit.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index 8bd7f1214..ba4f891ee 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -287,9 +287,6 @@ Handle GitCommit::Lookup(const Arguments& args) { baton->error = NULL; baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); - if (baton->repo == NULL) { - printf("BeforeWork: baton->repo is null\n"); - } if (args[1]->IsObject()) { baton->oid = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); baton->sha = NULL; @@ -342,7 +339,7 @@ void GitCommit::LookupAfterWork(uv_work_t *req) { baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); if (try_catch.HasCaught()) { - node::FatalException(try_catch); + node::FatalException(try_catch); } } else { @@ -358,7 +355,7 @@ void GitCommit::LookupAfterWork(uv_work_t *req) { TryCatch try_catch; baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) { - node::FatalException(try_catch); + node::FatalException(try_catch); } } } From 7a1975474b94cef6b7cb2fb8cfd11f56be8d3870 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 22:36:08 +1300 Subject: [PATCH 060/120] Couldn't sleep until I made OpenAfterWork call its callback with error, object like *all* the other async methods. --- lib/repo.js | 3 ++- src/repo.cc | 28 ++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/repo.js b/lib/repo.js index aeca1b415..1e26fb0ee 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -13,11 +13,12 @@ exports.repo = function(directory, callback) { if (!callback || typeof callback !== 'function') { throw new Error('If directory is provided, callback function is required'); } - self.repo.open(directory, function(error) { + self.repo.open(directory, function(error, rawRepo) { if (error) { callback(git.error(error), null); return; } + self.repo = rawRepo; callback(null, self); }); } diff --git a/src/repo.cc b/src/repo.cc index b8c4d2fd3..efe19e7f9 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -95,22 +95,34 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { OpenBaton *baton = static_cast(req->data); delete req; - baton->repo->SetValue(baton->rawRepo); baton->repo->Unref(); - Local argv[1]; if (baton->error) { - argv[0] = GitError::WrapError(baton->error); + Local argv[1] = { + GitError::WrapError(baton->error) + }; + + TryCatch try_catch; + + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } } else { - argv[0] = Local::New(Null()); - } - TryCatch try_catch; + baton->repo->SetValue(baton->rawRepo); - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + Handle argv[2] = { + Local::New(Null()), + baton->repo->handle_ + }; - if (try_catch.HasCaught()) { + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { node::FatalException(try_catch); + } } } From c00bc4757f8f2fc9434bd9812a669c8ac96c84bc Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 22:36:21 +1300 Subject: [PATCH 061/120] Documentation --- include/threads.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/threads.h b/include/threads.h index 92ce32d76..469911d8c 100755 --- a/include/threads.h +++ b/include/threads.h @@ -25,6 +25,10 @@ class GitThreads : public ObjectWrap { static void Initialize (Handle target); + /** + * Calls git_threads_init synchronously. This is called one time + * on initialization, and is required for libgit2 to run correctly. + */ static Handle Init(const Arguments& args); protected: From d08120fa0c226458edf1cf6c28ed4111b58b10ee Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 22:40:28 +1300 Subject: [PATCH 062/120] Updated raw-revwalk test --- test/raw-revwalk.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/raw-revwalk.js b/test/raw-revwalk.js index ddf92aa91..c78cede3d 100644 --- a/test/raw-revwalk.js +++ b/test/raw-revwalk.js @@ -25,7 +25,9 @@ var helper = { } }; -// RevWalk +/** + * RevWalk + */ exports.constructor = function(test){ test.expect(3); @@ -33,9 +35,8 @@ exports.constructor = function(test){ helper.testFunction(test.equals, git.RevWalk, 'RevWalk'); // Ensure we get an instance of Oid - testRepo.open( './dummyrepo/.git', function(error, path) { - test.ok(new git.RevWalk(testRepo) instanceof git.RevWalk, 'Invocation returns an instance of RevWalk'); - + testRepo.open('../.git', function(error, repository) { + test.ok(new git.RevWalk(repository) instanceof git.RevWalk, 'Invocation returns an instance of RevWalk'); test.done(); }); }; From 8afa0e5f2937e33a7b2f57657385a22c96be182e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Fri, 15 Mar 2013 13:25:32 +1300 Subject: [PATCH 063/120] Updated installer --- install.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/install.js b/install.js index f9e31fe6c..c507c7b3f 100644 --- a/install.js +++ b/install.js @@ -46,22 +46,21 @@ var updateSubmodules = function(mainCallback) { var checkoutDependencies = function(mainCallback) { console.log('[nodegit] Downloading libgit2 dependency.'); - var commit = 'b70bf922a1de35722904930c42467e95c889562f'; var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip'; zipFile = __dirname + '/vendor/libgit2.zip', unzippedFolderName = __dirname + '/vendor/libgit2-' + commit, targetFolderName = __dirname + '/vendor/libgit2'; - async.series([ - function(callback) { - request(libgit2ZipUrl) - .pipe(fs.createWriteStream(zipFile)) - .on('close', function () { - callback(); + async.waterfall([ + function downloadLibgit2(callback) { + var ws = fs.createWriteStream(zipFile); + ws.on('close', function() { + callback(); }); - - }, function(callback) { + request(libgit2ZipUrl) + .pipe(ws); + }, function unzipLibgit2(callback) { var zip = new AdmZip(zipFile); zip.extractAllTo(__dirname + '/vendor/', true); fs.unlink(zipFile); From 50f008f0ececebebbcdd6c53d9615510aa0e78bd Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Thu, 14 Mar 2013 23:05:04 -0400 Subject: [PATCH 064/120] Updated readme --- README.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 86ed14aa4..b1f0afe01 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,26 @@ -Node.js libgit2 bindings [![Build Status](https://travis-ci.org/tbranyen/nodegit.png)](https://travis-ci.org/tbranyen/nodegit) -======================= +nodegit +======= -Created by Tim Branyen [@tbranyen](http://twitter.com/tbranyen) +> Node.js libgit2 bindings -Currently under active development (and seeking contributions), `nodegit` provides asynchronous native bindings to the [`libgit2`](http://libgit2.github.com/libgit2/) C API. +**v0.0.72** [![Build +Status](https://travis-ci.org/tbranyen/nodegit.png)](https://travis-ci.org/tbranyen/nodegit) +Maintained by Tim Branyen [@tbranyen](http://twitter.com/tbranyen) and Michael +Robinson [@codeofinterest](http://twitter.com/codeofinterest), with help from +[awesome +contributors](https://github.com/tbranyen/nodegit/contributors)! Contributing ------------ -Nodegit aims to eventually provide native asynchronous bindings for as much of libgit2 as possible, but we can't do it alone! +Nodegit aims to eventually provide native asynchronous bindings for as much of +libgit2 as possible, but we can't do it alone! -We welcome pull requests, but please pay attention to the following: whether your lovely code fixes a bug or adds a new feature, please include unit tests that either prove the bug is fixed, or that your new feature works as expected. See [running tests](#running-tests) +We welcome pull requests, but please pay attention to the following: whether +your lovely code fixes a bug or adds a new feature, please include unit tests +that either prove the bug is fixed, or that your new feature works as expected. +See [running tests](#running-tests) Unit tests are what makes the Node event loop go around. @@ -19,7 +28,8 @@ Building and installing ----------------------- ### Dependencies ### -To run `nodegit` you need `Node.js` and to run unit tests you will need to have `git` installed and accessible from your `PATH` to fetch any `vendor/` addons. +To run `nodegit` you need `Node.js` and to run unit tests you will need to have +`git` installed and accessible from your `PATH` to fetch any `vendor/` addons. ### Easy install (Recommended) ### This will install and configure everything you need to use `nodegit`. @@ -255,6 +265,10 @@ __Can keep track of current method coverage at: [http://bit.ly/tb_methods](http: Getting involved ---------------- -If you find this project of interest, please document all issues and fork if you feel you can provide a patch. Testing is of huge importance; by simply running the unit tests on your system and reporting issues you can contribute! +If you find this project of interest, please document all issues and fork if +you feel you can provide a patch. Testing is of huge importance; by simply +running the unit tests on your system and reporting issues you can contribute! -__Before submitting a pull request, please ensure both that you've added unit tests to cover your shiny new code, and that all unit tests and lint checks pass.__ +__Before submitting a pull request, please ensure both that you've added unit +tests to cover your shiny new code, and that all unit tests and lint checks +pass.__ From 9151f4429d0b5036483c161d0f559e6e5ee47c94 Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Thu, 14 Mar 2013 23:24:34 -0400 Subject: [PATCH 065/120] bumped up git commit count, may fix travis-ci --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index baa0031d5..f6e2ee0ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: node_js node_js: - 0.8 +git: + depth: 1000 From 9514772c85fd5a229936e450d8c14901b5e047d5 Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Thu, 14 Mar 2013 23:45:23 -0400 Subject: [PATCH 066/120] updated license copyright date --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 01edb91b1..4782c6003 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011 Tim Branyen +Copyright (c) 2013 Tim Branyen This file is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, From 3e584ca1fc17adcecec7bf0778d05bad6ea4ad1b Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Thu, 14 Mar 2013 23:57:26 -0400 Subject: [PATCH 067/120] removed unused variable --- lib/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 0e75909a7..739edc2fe 100755 --- a/lib/index.js +++ b/lib/index.js @@ -32,8 +32,7 @@ try { exports.error = require("./error.js").error; // Set version -var version = require('../package').version; -exports.version = version; +exports.version = require('../package').version; // Initialize threads (new exports.raw.Threads()).init(); From 4313cb1c0ca80f996a981760d69da58a6e1f931c Mon Sep 17 00:00:00 2001 From: Tim Branyen Date: Fri, 15 Mar 2013 00:02:57 -0400 Subject: [PATCH 068/120] fixed code style in readme --- README.md | 123 +++++++++++++++++++++++++++--------------------------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index b1f0afe01..9c3db9a11 100644 --- a/README.md +++ b/README.md @@ -107,85 +107,86 @@ var git = require('nodegit').raw; var repo = new git.Repo(); // Read a repository -repo.open('.git', function(error) { - // Err is an integer, success is 0, use strError for string representation - if(error) { - var error = new git.Error(); - throw error.strError(error); +repo.open('.git', function(err) { + // Err is an integer, success is 0, use strError for string representation + if (err) { + var error = new git.Error(); + throw error.strError(err); + } + + // Create instance of Ref constructor with this repository + var ref = new git.Ref(repo); + + // Find the master branch + repo.lookupRef(ref, '/refs/heads/master', function(err) { + if (err) { + var error = new git.Error(); + throw error.strError(err); } - // Create instance of Ref constructor with this repository - var ref = new git.Ref(repo); - - // Find the master branch - repo.lookupRef(ref, '/refs/heads/master', function(err) { - if(error) { - var error = new git.Error(); - throw error.strError(err); - } - - // Create instance of Commit constructor with this repository - var commit = new git.Commit(repo), - // Create instance of Oid constructor - oid = new git.Oid(); + // Create instance of Commit constructor with this repository + var commit = new git.Commit(repo); - // Set the oid constructor internal reference to this branch reference - ref.oid(oid); + // Create instance of Oid constructor + var oid = new git.Oid(); - // Lookup the commit for this oid - commit.lookup(oid, function(err) { - if(err) { - var error = new git.Error(); - throw error.strError( err ); - } + // Set the oid constructor internal reference to this branch reference + ref.oid(oid); - // Create instance of RevWalk constructor with this repository - var revwalk = new git.RevWalk(repo); + // Lookup the commit for this oid + commit.lookup(oid, function(err) { + if (err) { + var error = new git.Error(); + throw error.strError(err); + } - // Push the commit as the start to walk - revwalk.push(commit); + // Create instance of RevWalk constructor with this repository + var revwalk = new git.RevWalk(repo); - // Recursive walk - function walk() { - // Each revision walk iteration yields a commit - var revisionCommit = new git.Commit(repo); + // Push the commit as the start to walk + revwalk.push(commit); - revwalk.next( revisionCommit, function(err) { - // Finish recursion once no more revision commits are left - if(err) { return; } + // Recursive walk + function walk() { + // Each revision walk iteration yields a commit + var revisionCommit = new git.Commit(repo); - // Create instance of Oid for sha - var oid = new git.Oid(); + revwalk.next(revisionCommit, function(err) { + // Finish recursion once no more revision commits are left + if (err) { return; } - // Set oid to the revision commit - revisionCommit.id(oid); + // Create instance of Oid for sha + var oid = new git.Oid(); - // Create instance of Sig for author - var author = new git.Sig(); + // Set oid to the revision commit + revisionCommit.id(oid); - // Set the author to the revision commit author - revisionCommit.author(author); + // Create instance of Sig for author + var author = new git.Sig(); - // Convert timestamp to milliseconds and set new Date object - var time = new Date( revisionCommit.time() * 1000 ); + // Set the author to the revision commit author + revisionCommit.author(author); - // Print out `git log` emulation - console.log(oid.toString( 40 )); - console.log(author.name() + '<' + author.email() + '>'); - console.log(time); - console.log('\n'); - console.log(revisionCommit.message()); - console.log('\n'); + // Convert timestamp to milliseconds and set new Date object + var time = new Date( revisionCommit.time() * 1000 ); - // Recurse! - walk(); - }); - } + // Print out `git log` emulation + console.log(oid.toString( 40 )); + console.log(author.name() + '<' + author.email() + '>'); + console.log(time); + console.log('\n'); + console.log(revisionCommit.message()); + console.log('\n'); - // Initiate recursion - walk(): + // Recurse! + walk(); }); + } + + // Initiate recursion + walk(): }); + }); }); ```` From dd440cc734d7b4e1c3db4cbdc6bf626ad5065fe0 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 22:42:14 +1300 Subject: [PATCH 069/120] Updated class comment --- src/commit.cc | 1 + src/reference.cc | 7 +++++-- src/repo.cc | 7 +++++-- src/revwalk.cc | 7 +++++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index ba4f891ee..5eccb01d1 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -1,5 +1,6 @@ /* * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest * * Dual licensed under the MIT and GPL licenses. */ diff --git a/src/reference.cc b/src/reference.cc index 9c341c443..a701168ab 100755 --- a/src/reference.cc +++ b/src/reference.cc @@ -1,6 +1,9 @@ /* -Copyright (c) 2011, Tim Branyen @tbranyen -*/ + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ #include #include diff --git a/src/repo.cc b/src/repo.cc index efe19e7f9..e759182d6 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -1,6 +1,9 @@ /* -Copyright (c) 2011, Tim Branyen @tbranyen -*/ + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ #include #include diff --git a/src/revwalk.cc b/src/revwalk.cc index 0776ce8ab..82dcb465d 100755 --- a/src/revwalk.cc +++ b/src/revwalk.cc @@ -1,6 +1,9 @@ /* -Copyright (c) 2011, Tim Branyen @tbranyen -*/ + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ #include #include From cf24e9a377c8bac577efcb40f899505fe43be927 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 23:11:15 +1300 Subject: [PATCH 070/120] Updated commit "constructor" --- lib/commit.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 5d9097591..177a71dc1 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -20,16 +20,15 @@ function applyDetails(details, context) { /** * Convenience commit constructor. * - * @param {RawCommit} obj + * @param {RawCommit|Null} rawCommit * @return {Commit} */ -var _Commit = function(obj) { +var _Commit = function(rawCommit) { var self = {}; - if(obj instanceof git.raw.Commit) { - self.commit = obj; - } - else { + if(rawCommit && rawCommit instanceof git.raw.Commit) { + self.commit = rawCommit; + } else { self.commit = new git.raw.Commit(); } From e45fb747e39a889ef422087f2a11cc852d73c216 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 23:16:47 +1300 Subject: [PATCH 071/120] Removed parentCount methods, they were sync and redundant after fetchDetails --- include/commit.h | 4 ---- src/commit.cc | 19 ------------------- 2 files changed, 23 deletions(-) diff --git a/include/commit.h b/include/commit.h index a4ac29303..43c2e7647 100755 --- a/include/commit.h +++ b/include/commit.h @@ -44,8 +44,6 @@ class GitCommit : public ObjectWrap { void Close(); int Tree(git_tree** tree); - unsigned int ParentCount(); - int Parent(git_commit** commit, int pos); protected: GitCommit() {} @@ -69,8 +67,6 @@ class GitCommit : public ObjectWrap { static void TreeWork(uv_work_t* req); static void TreeAfterWork(uv_work_t* req); - static Handle ParentCount(const Arguments& args); - static Handle ParentSync(const Arguments& args); static Handle Parent(const Arguments& args); static void ParentWork(uv_work_t* req); diff --git a/src/commit.cc b/src/commit.cc index 5eccb01d1..b42ba3a34 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -36,7 +36,6 @@ void GitCommit::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); NODE_SET_PROTOTYPE_METHOD(tpl, "tree", Tree); - NODE_SET_PROTOTYPE_METHOD(tpl, "parentCount", ParentCount); NODE_SET_PROTOTYPE_METHOD(tpl, "parent", Parent); NODE_SET_PROTOTYPE_METHOD(tpl, "parentSync", ParentSync); NODE_SET_PROTOTYPE_METHOD(tpl, "fetchDetails", FetchDetails); @@ -63,14 +62,6 @@ int GitCommit::Tree(git_tree** tree) { return git_commit_tree(tree, this->commit); } -unsigned int GitCommit::ParentCount() { - return git_commit_parentcount(this->commit); -} - -int GitCommit::Parent(git_commit** commit, int pos) { - return git_commit_parent(commit, this->commit, pos); -} - Handle GitCommit::New(const Arguments& args) { HandleScope scope; @@ -388,16 +379,6 @@ Handle GitCommit::Tree(const Arguments& args) { return scope.Close( Integer::New(err) ); } -Handle GitCommit::ParentCount(const Arguments& args) { - HandleScope scope; - - GitCommit *commit = ObjectWrap::Unwrap(args.This()); - - unsigned int count = commit->ParentCount(); - - return scope.Close( Integer::New(count) ); -} - Handle GitCommit::ParentSync(const Arguments& args) { HandleScope scope; From 7158a33b100c40a6d95a3196bd136086de9ab969 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 23:18:03 +1300 Subject: [PATCH 072/120] Remove ifndef from commit.h --- include/commit.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/commit.h b/include/commit.h index 43c2e7647..ab5375bd8 100755 --- a/include/commit.h +++ b/include/commit.h @@ -5,9 +5,6 @@ * Dual licensed under the MIT and GPL licenses. */ -#ifndef COMMIT_H -#define COMMIT_H - #include #include #include @@ -126,4 +123,3 @@ class GitCommit : public ObjectWrap { }; }; -#endif From 8132ff4d24129f2c7712eed2f2f9973fcc9e8632 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 23:18:25 +1300 Subject: [PATCH 073/120] Remove commit.h include from revwalk.h --- include/revwalk.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/revwalk.h b/include/revwalk.h index f2fc459c2..09a0c0588 100755 --- a/include/revwalk.h +++ b/include/revwalk.h @@ -10,7 +10,6 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../vendor/libgit2/include/git2.h" #include "repo.h" -#include "commit.h" using namespace node; using namespace v8; From cdb549c3051cbcac199850bad50f0f679197d4b9 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 13 Mar 2013 23:18:33 +1300 Subject: [PATCH 074/120] Remove odb_backend --- include/odb_backend.h | 56 ------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100755 include/odb_backend.h diff --git a/include/odb_backend.h b/include/odb_backend.h deleted file mode 100755 index 0615cda43..000000000 --- a/include/odb_backend.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011, Tim Branyen @tbranyen - * Dual licensed under the MIT and GPL licenses. - */ - -#ifndef ODB_BACKEND_H -#define ODB_BACKEND_H - -#include - -#include "../vendor/libgit2/include/git2.h" - -using namespace node; - -/** - * Class: GitOdbBackend - * Wrapper for libgit2 git_error. - */ -class GitOdbBackend : public ObjectWrap { - public: - /** - * Variable: constructor_template - * Used to create Node.js constructor. - */ - static v8::Persistent constructor_template; - /** - * Function: Initialize - * Used to intialize the EventEmitter from Node.js - * - * Parameters: - * target - v8::Object the Node.js global module object - */ - static void Initialize(v8::Handle target); - - protected: - /** - * Constructor: GitOdbBackend - */ - GitOdbBackend() {}; - /** - * Deconstructor: GitOdbBackend - */ - ~GitOdbBackend() {}; - /** - * Function: New - * - * Parameters: - * args v8::Arguments function call - * - * Returns: - * v8::Object args.This() - */ - static v8::Handle New(const v8::Arguments& args); -}; - -#endif From f38f05c0c97cf4edd5b937b679b37eacedf483ad Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 01:26:58 +1300 Subject: [PATCH 075/120] Tidied lib/tree --- lib/tree.js | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/tree.js b/lib/tree.js index e51d3de41..5bb25ea3d 100644 --- a/lib/tree.js +++ b/lib/tree.js @@ -1,20 +1,19 @@ -var git = require( '../' ) - , events = require( 'events' ); +var git = require( '../' ), + events = require( 'events' ); -var _Tree = function( obj, tree ) { +var _Tree = function(rawObject, tree) { var self = {}; - if ( obj instanceof git.raw.Repo && tree instanceof git.raw.Tree ) { - self.repo = obj; + + if (rawObject instanceof git.raw.Repo && + tree instanceof git.raw.Tree) { + self.repo = rawObject; self.tree = tree; - } - else if( obj instanceof git.raw.Repo ) { - self.repo = obj; - self.tree = new git.raw.Tree( tree ); - } - else if ( obj instanceof git.raw.Tree ) { - self.tree = obj; - } - else { + } else if(rawObject instanceof git.raw.Repo) { + self.repo = rawObject; + self.tree = new git.raw.Tree(tree); + } else if (rawObject instanceof git.raw.Tree) { + self.tree = rawObject; + } else { self.tree = new git.raw.Tree(); } @@ -91,24 +90,26 @@ var _Tree = function( obj, tree ) { return event; }; - self.entry = function( name, callback ) { - if( !callback ) { return; } + self.entry = function(name, callback) { + if(!callback) { + return; + } - var entry = git.entry( self.repo ); + var entry = git.entry(self.repo); - var path = name.split( '/' ); - if( path.length === 1 ) { - self.tree.entryByName( entry.entry, path[0], function( valid ) { - callback( valid ? entry : undefined ); + var path = name.split('/'); + if(path.length === 1) { + self.tree.entryByName(entry.entry, path[0], function(valid) { + callback(valid ? entry : undefined); }); } else { - function recurse( tree ) { + var recurse = function(tree) { var name = path.shift(); - var tree = tree || self.tree; + tree = tree || self.tree; - tree.entryByName( entry.entry, name, function( valid ) { - if( !path.length ) { + tree.entryByName(entry.entry, name, function(valid) { + if(!path.length) { callback( valid ? entry : undefined ); } else { @@ -120,7 +121,7 @@ var _Tree = function( obj, tree ) { } } }); - } + }; recurse(); } From a4fe99996f13206a771625720ac40647ee97d30d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 01:27:34 +1300 Subject: [PATCH 076/120] Removed NewInstance --- include/commit.h | 1 - src/commit.cc | 8 -------- 2 files changed, 9 deletions(-) diff --git a/include/commit.h b/include/commit.h index ab5375bd8..f19159705 100755 --- a/include/commit.h +++ b/include/commit.h @@ -47,7 +47,6 @@ class GitCommit : public ObjectWrap { ~GitCommit() {} static Handle New(const Arguments& args); - static Handle NewInstance(); static Handle FetchDetailsSync(const Arguments& args); static Handle FetchDetails(const Arguments& args); diff --git a/src/commit.cc b/src/commit.cc index b42ba3a34..66e15fccc 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -72,14 +72,6 @@ Handle GitCommit::New(const Arguments& args) { return scope.Close(args.This()); } -Handle GitCommit::NewInstance() { - HandleScope scope; - - Local instance = constructor_template->NewInstance(); - - return scope.Close(instance); -} - Handle GitCommit::FetchDetailsSync(const Arguments& args) { HandleScope scope; From 53bfaab87eea0251fb33992d4036755ff09192e1 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 01:28:03 +1300 Subject: [PATCH 077/120] Changed LookupBaton->sha to std::string, use string functions to convert --- include/commit.h | 2 +- src/commit.cc | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/include/commit.h b/include/commit.h index f19159705..da626c8ac 100755 --- a/include/commit.h +++ b/include/commit.h @@ -78,7 +78,7 @@ class GitCommit : public ObjectWrap { git_repository* repo; git_oid oid; - const char* sha; + std::string sha; git_commit* rawCommit; Persistent callback; diff --git a/src/commit.cc b/src/commit.cc index 66e15fccc..7efac2593 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -20,6 +20,8 @@ #include "../include/commit.h" #include "../include/error.h" +#include "../include/functions/string.h" + using namespace v8; using namespace cvv8; using namespace node; @@ -273,14 +275,10 @@ Handle GitCommit::Lookup(const Arguments& args) { if (args[1]->IsObject()) { baton->oid = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); - baton->sha = NULL; } else { - // Make this less ugly - String::AsciiValue shaValue(args[1]->ToString()); - char *sha = (char *) malloc(shaValue.length() + 1); - strcpy(sha, *shaValue); - baton->sha = sha; + baton->sha = stringArgToString(args[1]->ToString()); } + baton->callback = Persistent::New(Local::Cast(args[2])); uv_queue_work(uv_default_loop(), &baton->request, LookupWork, LookupAfterWork); @@ -292,8 +290,8 @@ void GitCommit::LookupWork(uv_work_t *req) { LookupBaton *baton = static_cast(req->data); git_oid oid = baton->oid; - if (baton->sha != NULL) { - int returnCode = git_oid_fromstr(&oid, baton->sha); + if (!baton->sha.empty()) { + int returnCode = git_oid_fromstr(&oid, baton->sha.c_str()); if (returnCode != GIT_OK) { baton->error = giterr_last(); return; @@ -353,6 +351,9 @@ Handle GitCommit::Close(const Arguments& args) { return scope.Close(Undefined()); } +/** + * @todo asynchronize + */ Handle GitCommit::Tree(const Arguments& args) { HandleScope scope; From ae87feca0eac21d4e950d2b286452a19479f48cf Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 01:28:25 +1300 Subject: [PATCH 078/120] Documentation --- test/convenience-commit.js | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index 59150c84c..6d64b266d 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -25,8 +25,6 @@ var helper = { /** * Test that the commit object is present. - * - * @param {Object} test */ exports.method = function(test){ test.expect(2); @@ -35,9 +33,7 @@ exports.method = function(test){ }; /** - * Test that - * - * @param {Object} test + * Test that improper commit ID's result in an error message */ exports.improperCommitId = function(test) { test.expect(1); @@ -79,8 +75,6 @@ exports.history = function(test) { /** * Test that retreiving master branch's HEAD commit works as expected. - * - * @param {Object} test */ exports.masterHead = function(test) { test.expect(2); @@ -138,8 +132,6 @@ exports.parent = function(test) { /** * Test that retrieving and walking a commit's tree works as expected. - * - * @param {Object} test */ exports.tree = function(test) { test.expect(2); @@ -163,3 +155,18 @@ exports.tree = function(test) { }); }); }; + +/** + * Test that parentsDiffTrees works as expected. + */ +exports.parentsDiffTrees = function(test) { + test.expect(1); + git.repo('../.git', function(error, repository) { + repository.commit(historyCountKnownSHA, function(error, commit) { + commit.parentsDiffTrees(function(error, parentsDiffTrees) { + console.log(arguments); + process.exit(); + }); + }); + }); +}; From 01d469416b26340ee4922d5171ef8dbe46c879f4 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 23:21:41 +1300 Subject: [PATCH 079/120] Added string functions --- binding.gyp | 1 + include/functions/string.h | 8 ++++++++ src/functions/string.cc | 9 +++++++++ 3 files changed, 18 insertions(+) create mode 100644 include/functions/string.h create mode 100644 src/functions/string.cc diff --git a/binding.gyp b/binding.gyp index 7eafaa095..fc23a2f8b 100644 --- a/binding.gyp +++ b/binding.gyp @@ -16,6 +16,7 @@ 'src/tree.cc', 'src/tree_entry.cc', 'src/threads.cc' + 'src/functions/string.cc' ], 'todosources': [ ], diff --git a/include/functions/string.h b/include/functions/string.h new file mode 100644 index 000000000..85c63027b --- /dev/null +++ b/include/functions/string.h @@ -0,0 +1,8 @@ +#include + +#ifndef STRING_FUNCTIONS +#define STRING_FUNCTIONS + +std::string stringArgToString(const v8::Local arg); + +#endif diff --git a/src/functions/string.cc b/src/functions/string.cc new file mode 100644 index 000000000..5c74f4aa7 --- /dev/null +++ b/src/functions/string.cc @@ -0,0 +1,9 @@ +#include +#include + +#include "../../include/functions/string.h" + +std::string stringArgToString(const v8::Local arg) { + v8::String::Utf8Value param1(arg); + return std::string(*param1); +} From b859de99399eacc53eab11f094bd77b824c20b6b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 23:24:25 +1300 Subject: [PATCH 080/120] Added diff_list --- include/diff_list.h | 87 +++++++++++++++ lib/diff_list.js | 93 ++++++++++++++++ src/diff_list.cc | 250 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 430 insertions(+) create mode 100644 include/diff_list.h create mode 100644 lib/diff_list.js create mode 100755 src/diff_list.cc diff --git a/include/diff_list.h b/include/diff_list.h new file mode 100644 index 000000000..04b1fc346 --- /dev/null +++ b/include/diff_list.h @@ -0,0 +1,87 @@ +/* + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ + +#include +#include +#include +#include + +#include "../vendor/libgit2/include/git2.h" + +#include "../include/repo.h" + +using namespace node; +using namespace v8; + +/** + * Class wrapper for libgit2 git_diff_list + */ +class GitDiffList : public ObjectWrap { + public: + + /** + * v8::FunctionTemplate used to create Node.js constructor + */ + static Persistent constructor_template; + + /** + * Used to intialize the EventEmitter from Node.js + * + * @param target v8::Object the Node.js module object + */ + static void Initialize (Handle target); + + git_diff_list* GetValue(); + void SetValue(git_diff_list* diffList); + void Close(); + + protected: + GitDiffList() {} + ~GitDiffList() {} + + static Handle New(const Arguments& args); + static Handle Close(const Arguments& args); + + static Handle TreeToTree(const Arguments& args); + static void TreeToTreeWork(uv_work_t *req); + static void TreeToTreeAfterWork(uv_work_t *req); + + static Handle Iterate(const Arguments& args); + static void IterateWork(void *arg); + + private: + git_diff_list* diffList; + // git_oid* oldOid; + // git_oid* newOid; + + struct TreeToTreeBaton { + uv_work_t request; + const git_error* error; + + GitDiffList *diffList; + git_repository* repo; + git_oid oldOid; + std::string oldSha; + git_oid newOid; + std::string newSha; + + git_diff_list* rawDiffList; + + Persistent callback; + }; + + struct IterateBaton { + uv_thread_t threadId; + const git_error* error; + + git_diff_list* rawDiffList; + Persistent fileCallback; + Persistent hunkCallback; + Persistent lineCallback; + Persistent endCallback; + }; +}; diff --git a/lib/diff_list.js b/lib/diff_list.js new file mode 100644 index 000000000..1624ca710 --- /dev/null +++ b/lib/diff_list.js @@ -0,0 +1,93 @@ +var git = require('../'), + events = require('events'); + +var _DiffList = function(rawRepo, rawDiffList) { + var self = { + repo: rawRepo, + diffList: rawDiffList || new git.raw.DiffList() + }; + + self.walk = function(repo) { + repo = repo || self.repo; + + var entry, + index, + length = self.length, + event = new events.EventEmitter(), + entries = []; + + self.diffList.iterate(function diffCallback(error, diff) { + console.log('diff callback'); + }, function hunkCallback(error, diffHunk) { + console.log('hunk callback'); + }, function lineCallback(error, diffLine) { + console.log('line callback'); + }, function endCallback(error) { + console.log('end'); + }); + + // function next(index) { + // var dir; + // var tree; + // var prerequisites = 0; + + // function complete(error) { + // if (index < length-1) { + // next(index = index+1); + // } else { + // event.emit('end', error, entries); + // } + // } + + // entry = git.entry(repo); + + // self.tree.entryByIndex(entry.entry, index, function() { + // if (entry.isFile()) { + // entries.push(entry); + // event.emit('entry', null, index, entry); + // } else { + // dir = entry.name; + // tree = entry.tree(); + // prerequisites++; + // if (tree.error) { + // event.emit('end', tree.error); + // return; + // } + + // tree.walk(repo).on('entry', function(error, index, entry) { + // if (error) { + // event.emit('entry', error, index, entry); + // } + // entry.dir = dir + '/' + entry.dir; + // event.emit('entry', null, index, entry); + // }).on('end', function(error, endEntries) { + // if (error) { + // complete(error); + // } + // prerequisites--; + // entries = entries.concat(endEntries); + // if (prerequisites === 0) { + // complete(error); + // } + // }); + // } + + // if (prerequisites === 0) { + // complete(); + // } + // }); + // } + + // next(0); + + return event; + }; + + self.treeToTree = function(oldSha, newSha, callback) { + self.diffList.treeToTree(self.repo, oldSha, newSha, callback); + }; + + return self; +}; + +exports.diffList = _DiffList; diff --git a/src/diff_list.cc b/src/diff_list.cc new file mode 100755 index 000000000..d9a202b61 --- /dev/null +++ b/src/diff_list.cc @@ -0,0 +1,250 @@ +/* + * Copyright 2011, Tim Branyen @tbranyen + * @author Michael Robinson @codeofinterest + * + * Dual licensed under the MIT and GPL licenses. + */ + +#include +#include +#include + +#include "../vendor/libgit2/include/git2.h" + +#include "../include/diff_list.h" +#include "../include/error.h" + +#include "../include/functions/string.h" + +using namespace v8; +using namespace node; + +void GitDiffList::Initialize(Handle target) { + HandleScope scope; + + Local tpl = FunctionTemplate::New(New); + + tpl->InstanceTemplate()->SetInternalFieldCount(1); + tpl->SetClassName(String::NewSymbol("DiffList")); + + NODE_SET_PROTOTYPE_METHOD(tpl, "treeToTree", TreeToTree); + NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); + + constructor_template = Persistent::New(tpl->GetFunction()); + target->Set(String::NewSymbol("DiffList"), constructor_template); +} + +git_diff_list* GitDiffList::GetValue() { + return this->diffList; +} + +void GitDiffList::SetValue(git_diff_list* diffList) { + this->diffList = diffList; +} + +Handle GitDiffList::New(const Arguments& args) { + HandleScope scope; + + GitDiffList *diffList = new GitDiffList(); + diffList->Wrap(args.This()); + + return scope.Close(args.This()); +} + +void GitDiffList::Close() { + git_diff_list_free(this->diffList); + this->diffList = NULL; +} + +Handle GitDiffList::Close(const Arguments& args) { + HandleScope scope; + + GitDiffList *diffList = ObjectWrap::Unwrap(args.This()); + diffList->Close(); + + return scope.Close(Undefined()); +} + +Handle GitDiffList::TreeToTree(const Arguments& args) { + HandleScope scope; + + if(args.Length() == 0 || !(args[0]->IsObject() || args[0]->IsString())) { + return ThrowException(Exception::Error(String::New("Repo is required and must be an Object or String"))); + } + + if(args.Length() == 1 || !(args[1]->IsObject() || args[1]->IsString())) { + return ThrowException(Exception::Error(String::New("Old Oid/SHA is required and must be an Object or String"))); + } + + if(args.Length() == 2 || !(args[2]->IsObject() || args[2]->IsString())) { + return ThrowException(Exception::Error(String::New("New Oid/SHA is required and must be an Object or String"))); + } + + if(args.Length() == 3 || !args[3]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); + } + + TreeToTreeBaton *baton = new TreeToTreeBaton(); + baton->request.data = baton; + baton->error = NULL; + baton->diffList = ObjectWrap::Unwrap(args.This()); + baton->repo = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); + + if (args[1]->IsObject()) { + baton->oldOid = ObjectWrap::Unwrap(args[1]->ToObject())->GetValue(); + } else { + baton->oldSha = stringArgToString(args[1]->ToString()); + } + + if (args[2]->IsObject()) { + baton->newOid = ObjectWrap::Unwrap(args[2]->ToObject())->GetValue(); + } else { + baton->newSha = stringArgToString(args[2]->ToString()); + } + + baton->callback = Persistent::New(Local::Cast(args[3])); + + uv_queue_work(uv_default_loop(), &baton->request, TreeToTreeWork, TreeToTreeAfterWork); + + return Undefined(); +} + +void GitDiffList::TreeToTreeWork(uv_work_t *req) { + TreeToTreeBaton *baton = static_cast(req->data); + + + // Prepare git_oid's + git_oid *oldOid = &baton->oldOid; + if (!baton->oldSha.empty()) { + int returnCode = git_oid_fromstr(oldOid, baton->oldSha.c_str()); + if (returnCode != GIT_OK) { + printf("oldOid\n"); + baton->error = giterr_last(); + return; + } + } + git_oid *newOid = &baton->newOid; + if (!baton->newSha.empty()) { + int returnCode = git_oid_fromstr(newOid, baton->newSha.c_str()); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + return; + } + } + + // Get commits + git_commit* oldCommit = NULL; + int returnCode = git_commit_lookup(&oldCommit, baton->repo, oldOid); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + return; + } + + git_commit* newCommit = NULL; + returnCode = git_commit_lookup(&newCommit, baton->repo, oldOid); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + return; + } + + // Prepare trees + git_tree* oldTree = NULL; + returnCode = git_commit_tree(&oldTree, oldCommit); + if (returnCode != GIT_OK) { + printf("oldTree\n"); + baton->error = giterr_last(); + return; + } + git_tree* newTree = NULL; + returnCode = git_commit_tree(&newTree, newCommit); + if (returnCode != GIT_OK) { + printf("newTree\n"); + baton->error = giterr_last(); + return; + } + + baton->rawDiffList = NULL; + returnCode = git_diff_tree_to_tree(&baton->rawDiffList, baton->repo, oldTree, newTree, NULL); + if (returnCode != GIT_OK) { + printf("t2t\n"); + baton->error = giterr_last(); + } +} + +void GitDiffList::TreeToTreeAfterWork(uv_work_t *req) { + HandleScope scope; + + TreeToTreeBaton *baton = static_cast(req->data); + delete req; + + if (baton->error) { + Local argv[1] = { + GitError::WrapError(baton->error) + }; + + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { + + baton->diffList->SetValue(baton->rawDiffList); + + Handle argv[2] = { + Local::New(Null()), + baton->diffList->handle_ + }; + + TryCatch try_catch; + baton->callback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } +} + +Handle GitDiffList::Iterate(const Arguments& args) { + HandleScope scope; + + GitDiffList* diffList = ObjectWrap::Unwrap(args.This()); + + if (diffList->GetValue() == NULL) { + return ThrowException(Exception::Error(String::New("Diff list has not been initialized."))); + } + + if(args.Length() == 0 || !args[0]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Diff callback is required and must be a Function."))); + } + + if(args.Length() == 1 || !args[1]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Hunk callback is required and must be a Function."))); + } + + if(args.Length() == 2 || !args[2]->IsFunction()) { + return ThrowException(Exception::Error(String::New("Line callback is required and must be a Function."))); + } + + if(args.Length() == 3 || !args[3]->IsFunction()) { + return ThrowException(Exception::Error(String::New("End callback is required and must be a Function."))); + } + + IterateBaton* baton = new IterateBaton(); + baton->rawDiffList = diffList->GetValue(); + + baton->fileCallback = Persistent::New(Local::Cast(args[0])); + baton->hunkCallback = Persistent::New(Local::Cast(args[1])); + baton->lineCallback = Persistent::New(Local::Cast(args[2])); + baton->endCallback = Persistent::New(Local::Cast(args[3])); + + uv_thread_create(&baton->threadId, IterateWork, &baton); + + return Undefined(); +} + +void GitDiffList::IterateWork(void *arg) { + printf("here\n"); +} + + +Persistent GitDiffList::constructor_template; From f19f1a835982f0bc7097351513e0647187ecd315 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 23:24:45 +1300 Subject: [PATCH 081/120] Minor formatting update --- lib/tree.js | 4 ++-- lib/tree_entry.js | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/tree.js b/lib/tree.js index 5bb25ea3d..2b7f5b96d 100644 --- a/lib/tree.js +++ b/lib/tree.js @@ -1,5 +1,5 @@ -var git = require( '../' ), - events = require( 'events' ); +var git = require('../'), + events = require('events'); var _Tree = function(rawObject, tree) { var self = {}; diff --git a/lib/tree_entry.js b/lib/tree_entry.js index f9c9a8e0a..a5f969d2a 100644 --- a/lib/tree_entry.js +++ b/lib/tree_entry.js @@ -1,14 +1,13 @@ var git = require( '../' ); -var _TreeEntry = function( obj ) { +var _TreeEntry = function(rawObject) { var self = {}; - if( obj instanceof git.raw.TreeEntry ) { - self.entry = obj; - } - else { + if(rawObject instanceof git.raw.TreeEntry) { + self.entry = rawObject; + } else { self.entry = new git.raw.TreeEntry(); - self.repo = obj; + self.repo = rawObject; } self.dir = ''; From 75aafd76c34e30c12f45b4fd33ed4864bac745a5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 23:25:18 +1300 Subject: [PATCH 082/120] Added difflist to index --- lib/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/index.js b/lib/index.js index 739edc2fe..66556746d 100755 --- a/lib/index.js +++ b/lib/index.js @@ -20,6 +20,7 @@ exports.revwalk = require("./revwalk.js").revwalk; exports.commit = require("./commit.js").commit; exports.tree = require("./tree.js").tree; exports.entry = require("./tree_entry.js").entry; +exports.diffList = require("./diff_list.js").diffList; // Assign raw api to module try { From a245a4988d11f4f6da23e1484fa38a4bc362ef9e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 14 Mar 2013 23:25:28 +1300 Subject: [PATCH 083/120] Added difflist to bindings, base.cc --- binding.gyp | 3 ++- src/base.cc | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/binding.gyp b/binding.gyp index fc23a2f8b..d8fa3d3e5 100644 --- a/binding.gyp +++ b/binding.gyp @@ -15,7 +15,8 @@ 'src/sig.cc', 'src/tree.cc', 'src/tree_entry.cc', - 'src/threads.cc' + 'src/diff_list.cc', + 'src/threads.cc', 'src/functions/string.cc' ], 'todosources': [ diff --git a/src/base.cc b/src/base.cc index d70063902..2bd9178cf 100755 --- a/src/base.cc +++ b/src/base.cc @@ -18,21 +18,27 @@ Copyright (c) 2011, Tim Branyen @tbranyen #include "../include/revwalk.h" #include "../include/tree.h" #include "../include/tree_entry.h" +#include "../include/diff_list.h" #include "../include/threads.h" extern "C" void init(Handle target) { HandleScope scope; + GitError::Initialize(target); + GitReference::Initialize(target); GitSig::Initialize(target); - GitError::Initialize(target); GitBlob::Initialize(target); GitOid::Initialize(target); GitObject::Initialize(target); GitRepo::Initialize(target); GitCommit::Initialize(target); GitRevWalk::Initialize(target); + GitTree::Initialize(target); GitTreeEntry::Initialize(target); + + GitDiffList::Initialize(target); + GitThreads::Initialize(target); } From a4a21e4d5cb5cd0fe88971d0fc615bf3083d05c5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 18 Mar 2013 00:54:55 +1300 Subject: [PATCH 084/120] Named anonymous functions --- lib/commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/commit.js b/lib/commit.js index 177a71dc1..46752bc17 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -131,14 +131,14 @@ var _Commit = function(rawCommit) { */ self.parent = function(position, callback) { var parent = null; - self.commit.parent(position, function(errorCode, parent) { + self.commit.parent(position, function processParent(errorCode, parent) { var error = null; if (errorCode) { error = git.error(errorCode); return callback(error, null); } var parentCommit = new _Commit(parent); - parentCommit.fetchDetails(function(error) { + parentCommit.fetchDetails(function returnParent(error) { callback(error, parentCommit); }); }); From b9885fc4dccbcb1eb2f36558bb3d6cbb18c49d03 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 18 Mar 2013 00:55:35 +1300 Subject: [PATCH 085/120] Added delta structs --- include/diff_list.h | 52 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/include/diff_list.h b/include/diff_list.h index 04b1fc346..429c96145 100644 --- a/include/diff_list.h +++ b/include/diff_list.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "../vendor/libgit2/include/git2.h" @@ -28,6 +29,8 @@ class GitDiffList : public ObjectWrap { */ static Persistent constructor_template; + static const int WALK_DELTA_THRESHHOLD = 10; + /** * Used to intialize the EventEmitter from Node.js * @@ -50,8 +53,31 @@ class GitDiffList : public ObjectWrap { static void TreeToTreeWork(uv_work_t *req); static void TreeToTreeAfterWork(uv_work_t *req); - static Handle Iterate(const Arguments& args); - static void IterateWork(void *arg); + /** + * Walk the current git_diff_list + */ + static Handle Walk(const Arguments& args); + static void WalkWork(void *payload); + static int WalkWorkFile(const git_diff_delta *delta, float progress, + void *payload); + static int WalkWorkHunk(const git_diff_delta *delta, const git_diff_range *range, + const char *header, size_t header_len, void *payload); + static int WalkWorkData(const git_diff_delta *delta, /** delta that contains this data */ + const git_diff_range *range, /** range of lines containing this data */ + char line_origin, /** git_diff_list_t value from above */ + const char *content, /** diff data - not NUL terminated */ + size_t content_len, /** number of bytes of diff data */ + void *payload); /** user reference data */ + /** + * Called when WalkWorkFile reaches its cache + * thresholds. Passes data back to main thread + * + * @param payload The WalkBaton + */ + static void WalkWorkSendFile(uv_async_t *handle, int status /*UNUSED*/); + static void WalkWorkSendHunk(uv_async_t *handle, int status /*UNUSED*/); + static void WalkWorkSendData(uv_async_t *handle, int status /*UNUSED*/); + static void WalkWorkSendEnd(uv_async_t *handle, int status /*UNUSED*/); private: git_diff_list* diffList; @@ -74,10 +100,30 @@ class GitDiffList : public ObjectWrap { Persistent callback; }; - struct IterateBaton { + struct DeltaContent { + git_diff_range *range; + char lineOrigin; + size_t contentLength; + std::string content; + }; + + struct Delta { + git_diff_delta *raw; + std::vector contents; + }; + + struct WalkBaton { uv_thread_t threadId; + uv_mutex_t mutex; + uv_async_t asyncFile; + uv_async_t asyncHunk; + uv_async_t asyncData; + uv_async_t asyncEnd; + const git_error* error; + std::map fileDeltas; + git_diff_list* rawDiffList; Persistent fileCallback; Persistent hunkCallback; From d65733f0cb7154fec84e91135e75d6957eeb8fa1 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 18 Mar 2013 00:56:34 +1300 Subject: [PATCH 086/120] Added delta type constants, tidied up includes --- src/diff_list.cc | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/diff_list.cc b/src/diff_list.cc index d9a202b61..51c1f9b92 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -5,11 +5,11 @@ * Dual licensed under the MIT and GPL licenses. */ -#include #include #include -#include "../vendor/libgit2/include/git2.h" +#include "cvv8/v8-convert.hpp" +#include "git2.h" #include "../include/diff_list.h" #include "../include/error.h" @@ -19,6 +19,14 @@ using namespace v8; using namespace node; +namespace cvv8 { + template <> + struct NativeToJS : NativeToJS {}; + + template <> + struct NativeToJS : NativeToJS {}; +} + void GitDiffList::Initialize(Handle target) { HandleScope scope; @@ -30,7 +38,21 @@ void GitDiffList::Initialize(Handle target) { NODE_SET_PROTOTYPE_METHOD(tpl, "treeToTree", TreeToTree); NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); + // Add libgit2 delta types to diff_list object + Local libgit2DeltaTypes = Object::New(); + + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_UNMODIFIED"), cvv8::CastToJS(GIT_DELTA_UNMODIFIED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_ADDED"), cvv8::CastToJS(GIT_DELTA_ADDED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_DELETED"), cvv8::CastToJS(GIT_DELTA_DELETED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_MODIFIED"), cvv8::CastToJS(GIT_DELTA_MODIFIED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_RENAMED"), cvv8::CastToJS(GIT_DELTA_RENAMED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_COPIED"), cvv8::CastToJS(GIT_DELTA_COPIED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_IGNORED"), cvv8::CastToJS(GIT_DELTA_IGNORED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_UNTRACKED"), cvv8::CastToJS(GIT_DELTA_UNTRACKED), ReadOnly); + libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_TYPECHANGE"), cvv8::CastToJS(GIT_DELTA_TYPECHANGE), ReadOnly); + constructor_template = Persistent::New(tpl->GetFunction()); + constructor_template->Set(String::NewSymbol("deltaTypes"), libgit2DeltaTypes, ReadOnly); target->Set(String::NewSymbol("DiffList"), constructor_template); } From 53bd66fbd82d846636d300de20b6df1127366e92 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 18 Mar 2013 00:57:32 +1300 Subject: [PATCH 087/120] Tidied up treeToTree debug output --- src/diff_list.cc | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/diff_list.cc b/src/diff_list.cc index 51c1f9b92..502d5ec7a 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -134,13 +134,11 @@ Handle GitDiffList::TreeToTree(const Arguments& args) { void GitDiffList::TreeToTreeWork(uv_work_t *req) { TreeToTreeBaton *baton = static_cast(req->data); - // Prepare git_oid's git_oid *oldOid = &baton->oldOid; if (!baton->oldSha.empty()) { int returnCode = git_oid_fromstr(oldOid, baton->oldSha.c_str()); if (returnCode != GIT_OK) { - printf("oldOid\n"); baton->error = giterr_last(); return; } @@ -163,7 +161,7 @@ void GitDiffList::TreeToTreeWork(uv_work_t *req) { } git_commit* newCommit = NULL; - returnCode = git_commit_lookup(&newCommit, baton->repo, oldOid); + returnCode = git_commit_lookup(&newCommit, baton->repo, newOid); if (returnCode != GIT_OK) { baton->error = giterr_last(); return; @@ -173,14 +171,12 @@ void GitDiffList::TreeToTreeWork(uv_work_t *req) { git_tree* oldTree = NULL; returnCode = git_commit_tree(&oldTree, oldCommit); if (returnCode != GIT_OK) { - printf("oldTree\n"); baton->error = giterr_last(); return; } git_tree* newTree = NULL; returnCode = git_commit_tree(&newTree, newCommit); if (returnCode != GIT_OK) { - printf("newTree\n"); baton->error = giterr_last(); return; } @@ -188,7 +184,6 @@ void GitDiffList::TreeToTreeWork(uv_work_t *req) { baton->rawDiffList = NULL; returnCode = git_diff_tree_to_tree(&baton->rawDiffList, baton->repo, oldTree, newTree, NULL); if (returnCode != GIT_OK) { - printf("t2t\n"); baton->error = giterr_last(); } } From 798d5ba9c945a0bb1b5537bd5cf22f9e7f94ec34 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Mon, 18 Mar 2013 00:58:39 +1300 Subject: [PATCH 088/120] Added outline of delat aggregation functions --- src/diff_list.cc | 178 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 6 deletions(-) diff --git a/src/diff_list.cc b/src/diff_list.cc index 502d5ec7a..74596391f 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -221,13 +221,13 @@ void GitDiffList::TreeToTreeAfterWork(uv_work_t *req) { } } -Handle GitDiffList::Iterate(const Arguments& args) { +Handle GitDiffList::Walk(const Arguments& args) { HandleScope scope; GitDiffList* diffList = ObjectWrap::Unwrap(args.This()); if (diffList->GetValue() == NULL) { - return ThrowException(Exception::Error(String::New("Diff list has not been initialized."))); + return ThrowException(Exception::Error(String::New("No diff list to Walk."))); } if(args.Length() == 0 || !args[0]->IsFunction()) { @@ -246,22 +246,188 @@ Handle GitDiffList::Iterate(const Arguments& args) { return ThrowException(Exception::Error(String::New("End callback is required and must be a Function."))); } - IterateBaton* baton = new IterateBaton(); + + WalkBaton* baton = new WalkBaton(); + uv_async_init(uv_default_loop(), &baton->asyncFile, WalkWorkSendFile); + uv_async_init(uv_default_loop(), &baton->asyncHunk, WalkWorkSendHunk); + uv_async_init(uv_default_loop(), &baton->asyncData, WalkWorkSendData); + uv_async_init(uv_default_loop(), &baton->asyncEnd, WalkWorkSendEnd); + + uv_mutex_init(&baton->mutex); + baton->rawDiffList = diffList->GetValue(); + diffList->Ref(); baton->fileCallback = Persistent::New(Local::Cast(args[0])); baton->hunkCallback = Persistent::New(Local::Cast(args[1])); baton->lineCallback = Persistent::New(Local::Cast(args[2])); baton->endCallback = Persistent::New(Local::Cast(args[3])); - uv_thread_create(&baton->threadId, IterateWork, &baton); + uv_thread_create(&baton->threadId, WalkWork, baton); return Undefined(); } -void GitDiffList::IterateWork(void *arg) { - printf("here\n"); +void GitDiffList::WalkWork(void *payload) { + WalkBaton *baton = static_cast(payload); + + int returnCode = git_diff_foreach(baton->rawDiffList, WalkWorkFile, WalkWorkHunk, WalkWorkData, payload); + if (returnCode != GIT_OK) { + baton->error = giterr_last(); + baton->asyncEnd.data = baton; + uv_async_send(&baton->asyncEnd); + return; + } + + baton->asyncFile.data = baton; + uv_async_send(&baton->asyncFile); + + baton->asyncEnd.data = baton; + uv_async_send(&baton->asyncEnd); + printf("GitDiffList::WalkWork finished\n"); +} + +int GitDiffList::WalkWorkFile(const git_diff_delta *delta, float progress, + void *payload) { + + printf("GitDiffList::WalkWorkFile\n"); + WalkBaton *baton = static_cast(payload); + uv_mutex_lock(&baton->mutex); + + GitDiffList::Delta* newDelta = new GitDiffList::Delta(); + memcpy(&newDelta->raw, delta, sizeof(git_diff_delta)); + + // @todo use combined OID or another less stupid way to index deltas + std::string key(newDelta->raw->old_file.path); + key.append(newDelta->raw->new_file.path); + baton->fileDeltas[key] = newDelta; + uv_mutex_unlock(&baton->mutex); + + if (baton->fileDeltas.size() == GitDiffList::WALK_DELTA_THRESHHOLD) { + uv_async_send(&baton->asyncFile); + } + + return GIT_OK; +} + +int GitDiffList::WalkWorkHunk(const git_diff_delta *delta, const git_diff_range *range, const char *header, size_t header_len, void *payload) { + + // printf("%s\n", header); + // WalkBaton *baton = static_cast(payload); + // uv_mutex_lock(&baton->mutex); + + // git_diff_delta *deltaCopy = (git_diff_delta*)malloc(sizeof(delta)); + // memcpy(deltaCopy, delta, sizeof(git_diff_delta)); + + // baton->fileDeltas.push_back(deltaCopy); + // uv_mutex_unlock(&baton->mutex); + + // if (baton->fileDeltas.size() == GitDiffList::WALK_DELTA_THRESHHOLD) { + // uv_async_send(&baton->asyncFile); + // } + + + return GIT_OK; +} + +int GitDiffList::WalkWorkData(const git_diff_delta *delta, const git_diff_range *range, + char line_origin, const char *content, size_t content_len, + void *payload) { + printf("GitDiffList::WalkWorkData\n"); + + WalkBaton *baton = static_cast(payload); + uv_mutex_lock(&baton->mutex); + + GitDiffList::DeltaContent *deltaContent = new GitDiffList::DeltaContent(); + + // git_diff_range* range = (git_diff_range*)malloc(sizeof(range)); + memcpy(&deltaContent->range, range, sizeof(git_diff_range)); + deltaContent->lineOrigin = line_origin; + deltaContent->contentLength = content_len; + deltaContent->content = content; + + std::string key(delta->old_file.path); + key.append(delta->new_file.path); + baton->fileDeltas[key]->contents.push_back(deltaContent); + + uv_mutex_unlock(&baton->mutex); + + return GIT_OK; } +void GitDiffList::WalkWorkSendFile(uv_async_t *handle, int status /*UNUSED*/) { + HandleScope scope; + + WalkBaton *baton = static_cast(handle->data); + + if (baton->error) { + Local argv[1] = { + GitError::WrapError(baton->error) + }; + + TryCatch try_catch; + baton->fileCallback->Call(Context::GetCurrent()->Global(), 1, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } else { + + /* + diff_file_delta + git_diff_file old_file + git_oid oid + const char *path + git_off_t size + uint32_t flags + uint16_t mode + + git_diff_file new_file + git_delta_t status + uint32_t similarity + uint32_t flags + */ + + uv_mutex_lock(&baton->mutex); + + std::vector > fileDeltasArray; + + for(std::map::iterator iterator=baton->fileDeltas.begin(); iterator != baton->fileDeltas.end(); ++iterator) { + + Local fileDelta = Object::New(); + GitDiffList::Delta* delta = iterator->second; + + Local oldFile = Object::New(); + oldFile->Set(String::NewSymbol("path"), String::New(delta->raw->old_file.path)); + fileDelta->Set(String::NewSymbol("oldFile"), oldFile); + + Local newFile = Object::New(); + newFile->Set(String::NewSymbol("path"), String::New(delta->raw->new_file.path)); + fileDelta->Set(String::NewSymbol("newFile"), newFile); + + fileDelta->Set(String::NewSymbol("status"), cvv8::CastToJS(delta->raw->status)); + + fileDeltasArray.push_back(fileDelta); + } + uv_mutex_unlock(&baton->mutex); + + Handle argv[2] = { + Local::New(Null()), + cvv8::CastToJS(fileDeltasArray) + }; + + TryCatch try_catch; + baton->fileCallback->Call(Context::GetCurrent()->Global(), 2, argv); + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } + } +} + +void GitDiffList::WalkWorkSendHunk(uv_async_t *handle, int status /*UNUSED*/) { } +void GitDiffList::WalkWorkSendData(uv_async_t *handle, int status /*UNUSED*/) { } +void GitDiffList::WalkWorkSendEnd(uv_async_t *handle, int status /*UNUSED*/) { + // @todo destroy threads mutex etc + printf("GitDiffList::WalkWorkSendEnd\n"); +} Persistent GitDiffList::constructor_template; From c0b2a63f7a1d2eac1288ccd63047da8f7dada1d5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:04:37 +1300 Subject: [PATCH 089/120] DiffTree walk --- lib/diff_list.js | 122 +++++++++++++--------------------- src/diff_list.cc | 170 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 172 insertions(+), 120 deletions(-) diff --git a/lib/diff_list.js b/lib/diff_list.js index 1624ca710..d9a615ce3 100644 --- a/lib/diff_list.js +++ b/lib/diff_list.js @@ -1,93 +1,67 @@ var git = require('../'), events = require('events'); -var _DiffList = function(rawRepo, rawDiffList) { +var GitDiffList = function(rawRepo, rawDiffList) { var self = { repo: rawRepo, diffList: rawDiffList || new git.raw.DiffList() }; - self.walk = function(repo) { - repo = repo || self.repo; + self.walk = function() { + var event = new events.EventEmitter(), + allFileDeltas = []; - var entry, - index, - length = self.length, - event = new events.EventEmitter(), - entries = []; - - self.diffList.iterate(function diffCallback(error, diff) { - console.log('diff callback'); - }, function hunkCallback(error, diffHunk) { - console.log('hunk callback'); - }, function lineCallback(error, diffLine) { - console.log('line callback'); - }, function endCallback(error) { - console.log('end'); - }); - - // function next(index) { - // var dir; - // var tree; - // var prerequisites = 0; - - // function complete(error) { - // if (index < length-1) { - // next(index = index+1); - // } else { - // event.emit('end', error, entries); - // } - // } - - // entry = git.entry(repo); - - // self.tree.entryByIndex(entry.entry, index, function() { - // if (entry.isFile()) { - // entries.push(entry); - // event.emit('entry', null, index, entry); - // } else { - // dir = entry.name; - // tree = entry.tree(); - // prerequisites++; - // if (tree.error) { - // event.emit('end', tree.error); - // return; - // } - - // tree.walk(repo).on('entry', function(error, index, entry) { - // if (error) { - // event.emit('entry', error, index, entry); - // } - // entry.dir = dir + '/' + entry.dir; - // event.emit('entry', null, index, entry); - // }).on('end', function(error, endEntries) { - // if (error) { - // complete(error); - // } - // prerequisites--; - // entries = entries.concat(endEntries); - // if (prerequisites === 0) { - // complete(error); - // } - // }); - // } - - // if (prerequisites === 0) { - // complete(); - // } - // }); - // } - - // next(0); + process.nextTick(function() { + self.diffList.walk(function fileCallback(error, fileDeltas) { + if (error) { + event.emit('end', error, null); + } + fileDeltas.forEach(function(fileDelta) { + event.emit('file', null, fileDelta); + allFileDeltas.push(fileDelta); + }) + }, function hunkCallback(error, diffHunk) { + // @todo implement? + }, function lineCallback(error, diffLine) { + // @todo implement? + }, function endCallback(error) { + event.emit('end', error, allFileDeltas); + }); + }) return event; }; self.treeToTree = function(oldSha, newSha, callback) { - self.diffList.treeToTree(self.repo, oldSha, newSha, callback); + self.diffList.treeToTree(self.repo, oldSha, newSha, function(error, rawDifflist) { + if (error) { + callback(error, null); + return; + } + self.diffList = rawDifflist; + callback(null, self); + }); }; + /** + * Add libgit2 delta types to git.diffList object. + * + * Refer to vendor/libgit2/include/git2/diff.h for definitions. + */ + for (var deltaType in git.raw.DiffList.deltaTypes) { + self[deltaType] = git.raw.DiffList.deltaTypes[deltaType]; + } + + /** + * Add libgit2 line origin types to git.diffList object. + * + * Refer to vendor/libgit2/include/git2/diff.h for definitions. + */ + for (var lineOriginType in git.raw.DiffList.lineOriginTypes) { + self[lineOriginType] = git.raw.DiffList.lineOriginTypes[lineOriginType]; + } + return self; }; -exports.diffList = _DiffList; +exports.diffList = GitDiffList; diff --git a/src/diff_list.cc b/src/diff_list.cc index 74596391f..dd4159192 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -22,9 +22,6 @@ using namespace node; namespace cvv8 { template <> struct NativeToJS : NativeToJS {}; - - template <> - struct NativeToJS : NativeToJS {}; } void GitDiffList::Initialize(Handle target) { @@ -36,6 +33,7 @@ void GitDiffList::Initialize(Handle target) { tpl->SetClassName(String::NewSymbol("DiffList")); NODE_SET_PROTOTYPE_METHOD(tpl, "treeToTree", TreeToTree); + NODE_SET_PROTOTYPE_METHOD(tpl, "walk", Walk); NODE_SET_PROTOTYPE_METHOD(tpl, "close", Close); // Add libgit2 delta types to diff_list object @@ -51,8 +49,52 @@ void GitDiffList::Initialize(Handle target) { libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_UNTRACKED"), cvv8::CastToJS(GIT_DELTA_UNTRACKED), ReadOnly); libgit2DeltaTypes->Set(String::NewSymbol("GIT_DELTA_TYPECHANGE"), cvv8::CastToJS(GIT_DELTA_TYPECHANGE), ReadOnly); + Local libgit2LineOriginConstants = Object::New(); + + // @todo refactor this into something sane + char _GIT_DIFF_LINE_CONTEXT[2]; + _GIT_DIFF_LINE_CONTEXT[0] = GIT_DIFF_LINE_CONTEXT; + _GIT_DIFF_LINE_CONTEXT[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_CONTEXT"), cvv8::CastToJS(_GIT_DIFF_LINE_CONTEXT), ReadOnly); + + char _GIT_DIFF_LINE_ADDITION[2]; + _GIT_DIFF_LINE_ADDITION[0] = GIT_DIFF_LINE_ADDITION; + _GIT_DIFF_LINE_ADDITION[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_ADDITION"), cvv8::CastToJS(_GIT_DIFF_LINE_ADDITION), ReadOnly); + + char _GIT_DIFF_LINE_DELETION[2]; + _GIT_DIFF_LINE_DELETION[0] = GIT_DIFF_LINE_DELETION; + _GIT_DIFF_LINE_DELETION[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_DELETION"), cvv8::CastToJS(_GIT_DIFF_LINE_DELETION), ReadOnly); + + char _GIT_DIFF_LINE_ADD_EOFNL[2]; + _GIT_DIFF_LINE_ADD_EOFNL[0] = GIT_DIFF_LINE_ADD_EOFNL; + _GIT_DIFF_LINE_ADD_EOFNL[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_ADD_EOFNL"), cvv8::CastToJS(_GIT_DIFF_LINE_ADD_EOFNL), ReadOnly); + + char _GIT_DIFF_LINE_DEL_EOFNL[2]; + _GIT_DIFF_LINE_DEL_EOFNL[0] = GIT_DIFF_LINE_DEL_EOFNL; + _GIT_DIFF_LINE_DEL_EOFNL[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_DEL_EOFNL"), cvv8::CastToJS(_GIT_DIFF_LINE_DEL_EOFNL), ReadOnly); + + char _GIT_DIFF_LINE_FILE_HDR[2]; + _GIT_DIFF_LINE_FILE_HDR[0] = GIT_DIFF_LINE_FILE_HDR; + _GIT_DIFF_LINE_FILE_HDR[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_FILE_HDR"), cvv8::CastToJS(_GIT_DIFF_LINE_FILE_HDR), ReadOnly); + + char _GIT_DIFF_LINE_HUNK_HDR[2]; + _GIT_DIFF_LINE_HUNK_HDR[0] = GIT_DIFF_LINE_HUNK_HDR; + _GIT_DIFF_LINE_HUNK_HDR[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_HUNK_HDR"), cvv8::CastToJS(_GIT_DIFF_LINE_HUNK_HDR), ReadOnly); + + char _GIT_DIFF_LINE_BINARY[2]; + _GIT_DIFF_LINE_BINARY[0] = GIT_DIFF_LINE_BINARY; + _GIT_DIFF_LINE_BINARY[1] = '\0'; + libgit2LineOriginConstants->Set(String::NewSymbol("GIT_DIFF_LINE_BINARY"), cvv8::CastToJS(_GIT_DIFF_LINE_BINARY), ReadOnly); + constructor_template = Persistent::New(tpl->GetFunction()); constructor_template->Set(String::NewSymbol("deltaTypes"), libgit2DeltaTypes, ReadOnly); + constructor_template->Set(String::NewSymbol("lineOriginTypes"), libgit2LineOriginConstants, ReadOnly); target->Set(String::NewSymbol("DiffList"), constructor_template); } @@ -284,18 +326,32 @@ void GitDiffList::WalkWork(void *payload) { baton->asyncEnd.data = baton; uv_async_send(&baton->asyncEnd); - printf("GitDiffList::WalkWork finished\n"); } int GitDiffList::WalkWorkFile(const git_diff_delta *delta, float progress, void *payload) { - - printf("GitDiffList::WalkWorkFile\n"); WalkBaton *baton = static_cast(payload); + + /* + diff_file_delta + git_diff_file old_file + git_oid oid + const char *path + git_off_t size + uint32_t flags + uint16_t mode + + git_diff_file new_file + git_delta_t status + uint32_t similarity + uint32_t flags + */ + uv_mutex_lock(&baton->mutex); GitDiffList::Delta* newDelta = new GitDiffList::Delta(); - memcpy(&newDelta->raw, delta, sizeof(git_diff_delta)); + newDelta->raw = (git_diff_delta*)malloc(sizeof(git_diff_delta)); + memcpy(newDelta->raw, delta, sizeof(git_diff_delta)); // @todo use combined OID or another less stupid way to index deltas std::string key(newDelta->raw->old_file.path); @@ -311,38 +367,22 @@ int GitDiffList::WalkWorkFile(const git_diff_delta *delta, float progress, } int GitDiffList::WalkWorkHunk(const git_diff_delta *delta, const git_diff_range *range, const char *header, size_t header_len, void *payload) { - - // printf("%s\n", header); - // WalkBaton *baton = static_cast(payload); - // uv_mutex_lock(&baton->mutex); - - // git_diff_delta *deltaCopy = (git_diff_delta*)malloc(sizeof(delta)); - // memcpy(deltaCopy, delta, sizeof(git_diff_delta)); - - // baton->fileDeltas.push_back(deltaCopy); - // uv_mutex_unlock(&baton->mutex); - - // if (baton->fileDeltas.size() == GitDiffList::WALK_DELTA_THRESHHOLD) { - // uv_async_send(&baton->asyncFile); - // } - - return GIT_OK; } int GitDiffList::WalkWorkData(const git_diff_delta *delta, const git_diff_range *range, char line_origin, const char *content, size_t content_len, void *payload) { - printf("GitDiffList::WalkWorkData\n"); - WalkBaton *baton = static_cast(payload); uv_mutex_lock(&baton->mutex); - GitDiffList::DeltaContent *deltaContent = new GitDiffList::DeltaContent(); + GitDiffList::DeltaContent *deltaContent = new GitDiffList::DeltaContent; + + deltaContent->range = (git_diff_range*)malloc(sizeof(git_diff_range)); + memcpy(deltaContent->range, range, sizeof(git_diff_range)); - // git_diff_range* range = (git_diff_range*)malloc(sizeof(range)); - memcpy(&deltaContent->range, range, sizeof(git_diff_range)); deltaContent->lineOrigin = line_origin; + deltaContent->contentLength = content_len; deltaContent->content = content; @@ -372,26 +412,11 @@ void GitDiffList::WalkWorkSendFile(uv_async_t *handle, int status /*UNUSED*/) { } } else { - /* - diff_file_delta - git_diff_file old_file - git_oid oid - const char *path - git_off_t size - uint32_t flags - uint16_t mode - - git_diff_file new_file - git_delta_t status - uint32_t similarity - uint32_t flags - */ - uv_mutex_lock(&baton->mutex); std::vector > fileDeltasArray; - for(std::map::iterator iterator=baton->fileDeltas.begin(); iterator != baton->fileDeltas.end(); ++iterator) { + for(std::map::iterator iterator = baton->fileDeltas.begin(); iterator != baton->fileDeltas.end(); ++iterator) { Local fileDelta = Object::New(); GitDiffList::Delta* delta = iterator->second; @@ -404,10 +429,47 @@ void GitDiffList::WalkWorkSendFile(uv_async_t *handle, int status /*UNUSED*/) { newFile->Set(String::NewSymbol("path"), String::New(delta->raw->new_file.path)); fileDelta->Set(String::NewSymbol("newFile"), newFile); + std::vector > deltaContent; + for(std::vector::iterator contentIterator = delta->contents.begin(); contentIterator != delta->contents.end(); ++contentIterator) { + DeltaContent* rawContent = (*contentIterator); + Local content = Object::New(); + + Local range = Object::New(); + /* + int old_start + int old_lines + int new_start + int new_lines + */ + Local oldRange = Object::New(); + oldRange->Set(String::New("start"), Integer::New(rawContent->range->old_start)); + oldRange->Set(String::New("lines"), Integer::New(rawContent->range->old_lines)); + range->Set(String::New("old"), oldRange); + + Local newRange = Object::New(); + newRange->Set(String::New("start"), Integer::New(rawContent->range->new_start)); + newRange->Set(String::New("lines"), Integer::New(rawContent->range->new_lines)); + range->Set(String::New("new"), newRange); + + content->Set(String::New("range"), range); + content->Set(String::New("content"), String::New(rawContent->content.c_str())); + + char lineOrigin[2]; + strncpy(lineOrigin, &rawContent->lineOrigin, 1); + content->Set(String::New("lineOrigin"), String::New(lineOrigin)); + content->Set(String::New("contentLength"), Integer::New(rawContent->contentLength)); + + deltaContent.push_back(content); + } + + fileDelta->Set(String::NewSymbol("content"), cvv8::CastToJS(deltaContent)); fileDelta->Set(String::NewSymbol("status"), cvv8::CastToJS(delta->raw->status)); fileDeltasArray.push_back(fileDelta); } + + baton->fileDeltas.clear(); + uv_mutex_unlock(&baton->mutex); Handle argv[2] = { @@ -426,8 +488,24 @@ void GitDiffList::WalkWorkSendFile(uv_async_t *handle, int status /*UNUSED*/) { void GitDiffList::WalkWorkSendHunk(uv_async_t *handle, int status /*UNUSED*/) { } void GitDiffList::WalkWorkSendData(uv_async_t *handle, int status /*UNUSED*/) { } void GitDiffList::WalkWorkSendEnd(uv_async_t *handle, int status /*UNUSED*/) { - // @todo destroy threads mutex etc - printf("GitDiffList::WalkWorkSendEnd\n"); + WalkBaton *baton = static_cast(handle->data); + + uv_mutex_destroy(&baton->mutex); + + Local argv[1]; + if (baton->error) { + argv[0] = GitError::WrapError(baton->error); + } else { + argv[0] = Local::New(Null()); + } + + TryCatch try_catch; + + baton->endCallback->Call(Context::GetCurrent()->Global(), 1, argv); + + if (try_catch.HasCaught()) { + node::FatalException(try_catch); + } } Persistent GitDiffList::constructor_template; From 005888128e5d8a59264b3b60dfecbae4a56f85b5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:04:57 +1300 Subject: [PATCH 090/120] Removed commented line --- lib/tree_entry.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/tree_entry.js b/lib/tree_entry.js index a5f969d2a..5b954047c 100644 --- a/lib/tree_entry.js +++ b/lib/tree_entry.js @@ -46,7 +46,6 @@ var _TreeEntry = function(rawObject) { Object.defineProperty( self, 'sha', { get: function() { var oid = self.id; - //console.log(self.id); return oid.oid.toString( 40 ); }, From 909ca49dbaf27b0a26b4548c62b882ddd95a9506 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:05:08 +1300 Subject: [PATCH 091/120] Added parentsDiffTrees --- lib/commit.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/lib/commit.js b/lib/commit.js index 46752bc17..5a75b5103 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -155,6 +155,33 @@ var _Commit = function(rawCommit) { return parent.fetchDetailsSync(); }; + /** + * Get a diff tree showing changes between this commit and its parent(s). + * Assumes commit has been populated with fetchDetails|fetchDetailsSync + * + * @param {Function} callback Called with error (null if no error) and the + * diff tree + */ + self.parentsDiffTrees = function(callback) { + if (!self.parentCount) { + callback(null, {}); + return; + } + var parentDiffLists = []; + self.parentShas.forEach(function eachParentSha(parentSha) { + git.diffList(self.repo).treeToTree(parentSha, self.sha, function walkDiffList(error, diffList) { + if (error) { + callback(error, null); + return; + } + parentDiffLists.push(diffList); + if (parentDiffLists.length === self.parentShas.length) { + callback(null, parentDiffLists); + } + }); + }); + }; + return self; }; From ab6e5dfefae749ff5b0898fc8936ee9ab369d723 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:05:20 +1300 Subject: [PATCH 092/120] Added diff_list --- lib/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/index.js b/lib/index.js index 66556746d..8daeca81e 100755 --- a/lib/index.js +++ b/lib/index.js @@ -20,16 +20,17 @@ exports.revwalk = require("./revwalk.js").revwalk; exports.commit = require("./commit.js").commit; exports.tree = require("./tree.js").tree; exports.entry = require("./tree_entry.js").entry; -exports.diffList = require("./diff_list.js").diffList; // Assign raw api to module try { exports.raw = require('../build/Debug/nodegit'); } catch (error) { + throw error; exports.raw = require('../build/Release/nodegit'); } -// Initialize error object after so it may access raw.Error +// Initialize objects that need to access their raw counterparts +exports.diffList = require("./diff_list.js").diffList; exports.error = require("./error.js").error; // Set version From 86ade8e5a39042c3d2b2ef9ad301c4359db11977 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:05:47 +1300 Subject: [PATCH 093/120] Updated libgit2 --- install.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/install.js b/install.js index c507c7b3f..6b07c89c9 100644 --- a/install.js +++ b/install.js @@ -46,7 +46,7 @@ var updateSubmodules = function(mainCallback) { var checkoutDependencies = function(mainCallback) { console.log('[nodegit] Downloading libgit2 dependency.'); - var commit = 'b70bf922a1de35722904930c42467e95c889562f'; + var commit = 'e953c1606d0d7aea680c9b19db0b955b34ae63c2'; var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip'; zipFile = __dirname + '/vendor/libgit2.zip', unzippedFolderName = __dirname + '/vendor/libgit2-' + commit, @@ -103,8 +103,8 @@ async.series([ }, function(callback) { console.log('[nodegit] Building native module.'); - shpassthru('node-gyp configure --debug', callback); - // shpassthru('node-gyp configure', callback); + // shpassthru('node-gyp configure --debug', callback); + shpassthru('node-gyp configure', callback); }, function(callback) { shpassthru('node-gyp build', callback); From bc2a3b09aeddc94e0c8879604c18e291d8d84b73 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:12:19 +1300 Subject: [PATCH 094/120] Very basic diffTrees test --- test/convenience-commit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/convenience-commit.js b/test/convenience-commit.js index 6d64b266d..34154ac62 100644 --- a/test/convenience-commit.js +++ b/test/convenience-commit.js @@ -164,8 +164,8 @@ exports.parentsDiffTrees = function(test) { git.repo('../.git', function(error, repository) { repository.commit(historyCountKnownSHA, function(error, commit) { commit.parentsDiffTrees(function(error, parentsDiffTrees) { - console.log(arguments); - process.exit(); + test.equals(parentsDiffTrees.length, 1, 'Should be one item in parents diff trees'); + test.done(); }); }); }); From caa887d68453c13ed6164c3575d364e2e1bbf3ff Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:17:14 +1300 Subject: [PATCH 095/120] Updated comparison --- src/diff_list.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/diff_list.cc b/src/diff_list.cc index dd4159192..7d692be88 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -359,7 +359,7 @@ int GitDiffList::WalkWorkFile(const git_diff_delta *delta, float progress, baton->fileDeltas[key] = newDelta; uv_mutex_unlock(&baton->mutex); - if (baton->fileDeltas.size() == GitDiffList::WALK_DELTA_THRESHHOLD) { + if ((unsigned int)baton->fileDeltas.size() == (unsigned int)GitDiffList::WALK_DELTA_THRESHHOLD) { uv_async_send(&baton->asyncFile); } From cc284fe6174b46f89bb5342238901d90ddfa701e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 00:19:59 +1300 Subject: [PATCH 096/120] Removed accidentally commited throw... --- lib/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/index.js b/lib/index.js index 8daeca81e..37c6e39c0 100755 --- a/lib/index.js +++ b/lib/index.js @@ -25,7 +25,6 @@ exports.entry = require("./tree_entry.js").entry; try { exports.raw = require('../build/Debug/nodegit'); } catch (error) { - throw error; exports.raw = require('../build/Release/nodegit'); } From b780383bc8e96d19d0adee1b022f04897de86846 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 22:07:42 +1300 Subject: [PATCH 097/120] Added --python python2 to install. Should fix #54 --- install.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.js b/install.js index 6b07c89c9..2ef128f9a 100644 --- a/install.js +++ b/install.js @@ -103,8 +103,8 @@ async.series([ }, function(callback) { console.log('[nodegit] Building native module.'); - // shpassthru('node-gyp configure --debug', callback); - shpassthru('node-gyp configure', callback); + // shpassthru('node-gyp configure --python python2 --debug', callback); + shpassthru('node-gyp configure --python python2', callback); }, function(callback) { shpassthru('node-gyp build', callback); From 0b2563ae346651632f174539715db856851e79d4 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 22:13:49 +1300 Subject: [PATCH 098/120] Updated install script to use zlib+tar instead of adm-zip --- install.js | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/install.js b/install.js index 2ef128f9a..ced27b9b3 100644 --- a/install.js +++ b/install.js @@ -4,7 +4,8 @@ var async = require('async'), path = require('path'), fs = require('fs'), request = require('request'), - AdmZip = require('adm-zip'); + zlib = require('zlib'), + tar = require('tar'); function passthru() { var args = Array.prototype.slice.call(arguments); @@ -47,32 +48,16 @@ var updateSubmodules = function(mainCallback) { var checkoutDependencies = function(mainCallback) { console.log('[nodegit] Downloading libgit2 dependency.'); var commit = 'e953c1606d0d7aea680c9b19db0b955b34ae63c2'; - var libgit2ZipUrl = 'https://github.com/libgit2/libgit2/archive/' + commit + '.zip'; - zipFile = __dirname + '/vendor/libgit2.zip', - unzippedFolderName = __dirname + '/vendor/libgit2-' + commit, - targetFolderName = __dirname + '/vendor/libgit2'; - async.waterfall([ - function downloadLibgit2(callback) { - var ws = fs.createWriteStream(zipFile); - ws.on('close', function() { - callback(); - }); - request(libgit2ZipUrl) - .pipe(ws); - }, function unzipLibgit2(callback) { - var zip = new AdmZip(zipFile); - zip.extractAllTo(__dirname + '/vendor/', true); - fs.unlink(zipFile); - callback(); - }, - function renameLibgit2Folder(callback) { - fs.rename(unzippedFolderName, targetFolderName, callback); - } - ], function(error) { - if (error) process.exit(error); - mainCallback(); - }); + var url = 'https://github.com/libgit2/libgit2/tarball/'+ commit; + var path = __dirname + '/vendor/libgit2-' + commit; + request({ + url: url + }).pipe(zlib.createUnzip()).pipe(tar.Extract({ + path: path + })).on('end', function() { + mainCallback(); + }); }; var buildDir = path.join(__dirname, 'vendor/libgit2/build'); From a1d7c241f861e1e3b071aaf15f2ffdbf1a8ccb1d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 22:14:00 +1300 Subject: [PATCH 099/120] Remove adm-zip dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index b15fe3957..4899426d1 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ }, "dependencies": { "async": ">= 0.1.21", - "adm-zip": "0.2.x", "request": "2.9.x", "node-gyp": "~0.8.2" }, From abd9d4b34fb2da84e50aa1c42f377b02e843bb7d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 22:30:28 +1300 Subject: [PATCH 100/120] Added tar to packages --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4899426d1..6871b5dd2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "dependencies": { "async": ">= 0.1.21", "request": "2.9.x", - "node-gyp": "~0.8.2" + "node-gyp": "~0.8.2", + "tar": "" }, "devDependencies": { "nodeunit": "0.7.x", From 1708a725e29d6eb6db2c80b52d63fb808f37c18c Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 23:27:43 +1300 Subject: [PATCH 101/120] Use tar instead of adm-zip --- install.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install.js b/install.js index ced27b9b3..c607c8107 100644 --- a/install.js +++ b/install.js @@ -50,11 +50,12 @@ var checkoutDependencies = function(mainCallback) { var commit = 'e953c1606d0d7aea680c9b19db0b955b34ae63c2'; var url = 'https://github.com/libgit2/libgit2/tarball/'+ commit; - var path = __dirname + '/vendor/libgit2-' + commit; + var path = __dirname + '/vendor/libgit2/'; request({ url: url }).pipe(zlib.createUnzip()).pipe(tar.Extract({ - path: path + path: path, + strip: true })).on('end', function() { mainCallback(); }); From bfbeba2e3ac27b1e3daa58bf7a7dbc4b0fc52661 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 23:39:43 +1300 Subject: [PATCH 102/120] Added note about cmake --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c3db9a11..2442f8583 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Building and installing ----------------------- ### Dependencies ### -To run `nodegit` you need `Node.js` and to run unit tests you will need to have +To install `nodegit` you need `Node.js` and `cmake`. To run unit tests you will need to have `git` installed and accessible from your `PATH` to fetch any `vendor/` addons. ### Easy install (Recommended) ### From f0ffa8a4b9a7eeab5bed850109b7daee751deb17 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Tue, 19 Mar 2013 23:47:08 +1300 Subject: [PATCH 103/120] Added (uv_after_work_cb) casts to after work methods --- src/blob.cc | 2 +- src/commit.cc | 6 +++--- src/diff_list.cc | 2 +- src/reference.cc | 2 +- src/repo.cc | 4 ++-- src/revwalk.cc | 4 ++-- src/tree.cc | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/blob.cc b/src/blob.cc index bc501cc52..ef2b9b7ac 100755 --- a/src/blob.cc +++ b/src/blob.cc @@ -105,7 +105,7 @@ Handle GitBlob::Lookup(const Arguments& args) { uv_work_t *req = new uv_work_t; req->data = ar; - uv_queue_work(uv_default_loop(), req, EIO_Lookup, EIO_AfterLookup); + uv_queue_work(uv_default_loop(), req, EIO_Lookup, (uv_after_work_cb)EIO_AfterLookup); return scope.Close( Undefined() ); } diff --git a/src/commit.cc b/src/commit.cc index 7efac2593..05cd27efc 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -150,7 +150,7 @@ Handle GitCommit::FetchDetails(const Arguments& args) { baton->rawCommit = ObjectWrap::Unwrap(args.This())->commit; baton->callback = Persistent::New(Local::Cast(args[0])); - uv_queue_work(uv_default_loop(), &baton->request, FetchDetailsWork, FetchDetailsAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, FetchDetailsWork, (uv_after_work_cb)FetchDetailsAfterWork); return Undefined(); } @@ -281,7 +281,7 @@ Handle GitCommit::Lookup(const Arguments& args) { baton->callback = Persistent::New(Local::Cast(args[2])); - uv_queue_work(uv_default_loop(), &baton->request, LookupWork, LookupAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, LookupWork, (uv_after_work_cb)LookupAfterWork); return Undefined(); } @@ -418,7 +418,7 @@ Handle GitCommit::Parent(const Arguments& args) { baton->index = args[0]->ToInteger()->Value(); baton->callback = Persistent::New(Local::Cast(args[1])); - uv_queue_work(uv_default_loop(), &baton->request, ParentWork, ParentAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, ParentWork, (uv_after_work_cb)ParentAfterWork); return Undefined(); } diff --git a/src/diff_list.cc b/src/diff_list.cc index 7d692be88..09bcc2ca2 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -168,7 +168,7 @@ Handle GitDiffList::TreeToTree(const Arguments& args) { baton->callback = Persistent::New(Local::Cast(args[3])); - uv_queue_work(uv_default_loop(), &baton->request, TreeToTreeWork, TreeToTreeAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, TreeToTreeWork, (uv_after_work_cb)TreeToTreeAfterWork); return Undefined(); } diff --git a/src/reference.cc b/src/reference.cc index a701168ab..58a4f64cd 100755 --- a/src/reference.cc +++ b/src/reference.cc @@ -92,7 +92,7 @@ Handle GitReference::Lookup(const Arguments& args) { uv_work_t *req = new uv_work_t; req->data = ar; - uv_queue_work(uv_default_loop(), req, EIO_Lookup, EIO_AfterLookup); + uv_queue_work(uv_default_loop(), req, EIO_Lookup, (uv_after_work_cb)EIO_AfterLookup); return scope.Close( Undefined() ); } diff --git a/src/repo.cc b/src/repo.cc index e759182d6..334d1f7ff 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -78,7 +78,7 @@ Handle GitRepo::Open(const Arguments& args) { baton->rawRepo = baton->repo->GetValue(); baton->callback = Persistent::New(Local::Cast(args[1])); - uv_queue_work(uv_default_loop(), &baton->request, OpenWork, OpenAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, OpenWork, (uv_after_work_cb)OpenAfterWork); return Undefined(); } @@ -244,7 +244,7 @@ Handle GitRepo::Init(const Arguments& args) { baton->isBare = args[1]->ToBoolean()->Value(); baton->callback = Persistent::New(Local::Cast(args[2])); - uv_queue_work(uv_default_loop(), &baton->request, InitWork, InitAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, InitWork, (uv_after_work_cb)InitAfterWork); return Undefined(); } diff --git a/src/revwalk.cc b/src/revwalk.cc index 82dcb465d..7ee6f5569 100755 --- a/src/revwalk.cc +++ b/src/revwalk.cc @@ -116,7 +116,7 @@ Handle GitRevWalk::Push(const Arguments& args) { baton->oid = ObjectWrap::Unwrap(args[0]->ToObject())->GetValue(); baton->callback = Persistent::New(Local::Cast(args[1])); - uv_queue_work(uv_default_loop(), &baton->request, PushWork, PushAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, PushWork, (uv_after_work_cb)PushAfterWork); return Undefined(); } @@ -168,7 +168,7 @@ Handle GitRevWalk::Next(const Arguments& args) { baton->walkOver = false; baton->callback = Persistent::New(Local::Cast(args[0])); - uv_queue_work(uv_default_loop(), &baton->request, NextWork, NextAfterWork); + uv_queue_work(uv_default_loop(), &baton->request, NextWork, (uv_after_work_cb)NextAfterWork); return Undefined(); } diff --git a/src/tree.cc b/src/tree.cc index 591f9bdc4..8d39bb5de 100755 --- a/src/tree.cc +++ b/src/tree.cc @@ -185,7 +185,7 @@ Handle GitTree::EntryByIndex(const Arguments& args) { uv_work_t *req = new uv_work_t; req->data = er; - uv_queue_work(uv_default_loop(), req, EIO_EntryByIndex, EIO_AfterEntryByIndex); + uv_queue_work(uv_default_loop(), req, EIO_EntryByIndex, (uv_after_work_cb)EIO_AfterEntryByIndex); return scope.Close( Undefined() ); } @@ -249,7 +249,7 @@ Handle GitTree::EntryByName(const Arguments& args) { uv_work_t *req = new uv_work_t; req->data = er; - uv_queue_work(uv_default_loop(), req, EIO_EntryByName, EIO_AfterEntryByName); + uv_queue_work(uv_default_loop(), req, EIO_EntryByName, (uv_after_work_cb)EIO_AfterEntryByName); return scope.Close( Undefined() ); } From d931b9b32f0176fdd80337c5c6d833d662d0126a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 00:20:11 +1300 Subject: [PATCH 104/120] Updated base.cc to export module for node 0.10.0 --- src/base.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/base.cc b/src/base.cc index 2bd9178cf..5a73900a2 100755 --- a/src/base.cc +++ b/src/base.cc @@ -41,4 +41,7 @@ extern "C" void init(Handle target) { GitDiffList::Initialize(target); GitThreads::Initialize(target); + } + +NODE_MODULE(nodegit, init) From 272f501685ff465f8fcbad712a302f55cfaa71d1 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 22:45:03 +1300 Subject: [PATCH 105/120] Reoganised .gitignore --- .gitignore | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 91f748bb6..1f63036f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ -.lock-wscript -build -doc -!doc/Theme.css -example/stress/test -node_modules +# Files .DS_Store +/sftp-config.json + +# Directories +/build +/example/stress/test +/doc +!doc/Theme.css +/node_modules + From fab376c9bb0cc4392cfe93ede00853630a40a48b Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 22:46:11 +1300 Subject: [PATCH 106/120] Updated install script to delete existing libgit2 build directory if present --- install.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/install.js b/install.js index c607c8107..bbdc410ea 100644 --- a/install.js +++ b/install.js @@ -2,9 +2,9 @@ var async = require('async'), child_process = require('child_process'), spawn = child_process.spawn, path = require('path'), - fs = require('fs'), request = require('request'), zlib = require('zlib'), + fs = require('fs-extra'), tar = require('tar'); function passthru() { @@ -61,7 +61,7 @@ var checkoutDependencies = function(mainCallback) { }); }; -var buildDir = path.join(__dirname, 'vendor/libgit2/build'); +var libgit2BuildDirectory = path.join(__dirname, 'vendor/libgit2/build'); async.series([ function(callback) { // Check for presence of .git folder @@ -73,18 +73,27 @@ async.series([ } }); }, + function deleteExistingLibgit2BuildFolder(callback) { + fs.exists(libgit2BuildDirectory, function(exists) { + if (exists) { + fs.remove(libgit2BuildDirectory, callback); + } else { + callback(); + } + }); + }, function(callback) { console.log('[nodegit] Building libgit2 dependency.'); - envpassthru('mkdir', '-p', buildDir, callback); + fs.mkdirs(libgit2BuildDirectory, callback); }, function(callback) { envpassthru('cmake', '-DTHREADSAFE=1', '-DBUILD_CLAR=0', '..', { - cwd: buildDir + cwd: libgit2BuildDirectory }, callback); }, function(callback) { envpassthru('cmake', '--build', '.', { - cwd: buildDir + cwd: libgit2BuildDirectory }, callback); }, function(callback) { From 4de3cbd50b67bde01b5714f648938ff020eb8bac Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 22:48:55 +1300 Subject: [PATCH 107/120] Name anonymous functions --- install.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/install.js b/install.js index bbdc410ea..2275fff38 100644 --- a/install.js +++ b/install.js @@ -63,7 +63,7 @@ var checkoutDependencies = function(mainCallback) { var libgit2BuildDirectory = path.join(__dirname, 'vendor/libgit2/build'); async.series([ - function(callback) { + function prepareLibgit2Repository(callback) { // Check for presence of .git folder fs.exists(__dirname + '/.git', function(exists) { if (exists) { @@ -82,28 +82,28 @@ async.series([ } }); }, - function(callback) { + function createLibgit2BuildDirectory(callback) { console.log('[nodegit] Building libgit2 dependency.'); fs.mkdirs(libgit2BuildDirectory, callback); }, - function(callback) { + function configureLibgit2(callback) { envpassthru('cmake', '-DTHREADSAFE=1', '-DBUILD_CLAR=0', '..', { cwd: libgit2BuildDirectory }, callback); }, - function(callback) { + function buildLibgit2(callback) { envpassthru('cmake', '--build', '.', { cwd: libgit2BuildDirectory }, callback); }, - function(callback) { + function configureNodegit(callback) { console.log('[nodegit] Building native module.'); // shpassthru('node-gyp configure --python python2 --debug', callback); shpassthru('node-gyp configure --python python2', callback); }, - function(callback) { + function buildNodegit(callback) { shpassthru('node-gyp build', callback); } -], function(err) { - if(err) process.exit(err); +], function handleError(error) { + if(error) process.exit(error); }); From 95a0c54889bd611ffdfe292931a103675dd90ec2 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 22:49:21 +1300 Subject: [PATCH 108/120] Updated packages --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6871b5dd2..e29c00998 100644 --- a/package.json +++ b/package.json @@ -33,10 +33,11 @@ "async": ">= 0.1.21", "request": "2.9.x", "node-gyp": "~0.8.2", - "tar": "" + "tar": "0.1.17", + "fs-extra": "0.6.0" }, "devDependencies": { - "nodeunit": "0.7.x", + "nodeunit": "", "rimraf": "1.0.x" }, "scripts": { From 7302a17158548ff857e3c468c1b48ba5eb4d35bc Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Wed, 20 Mar 2013 23:13:48 +1300 Subject: [PATCH 109/120] Ensure convenience repo does not allow one to open a non existent directory --- lib/repo.js | 19 +++++++++++++------ test/convenience-repo.js | 18 +++++++++++++++--- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/repo.js b/lib/repo.js index 1e26fb0ee..2335bd7bc 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -1,4 +1,5 @@ -var git = require("../"); +var git = require('../'), + fs = require('fs'); /* Module: Repo * Work with a repository. @@ -13,13 +14,19 @@ exports.repo = function(directory, callback) { if (!callback || typeof callback !== 'function') { throw new Error('If directory is provided, callback function is required'); } - self.repo.open(directory, function(error, rawRepo) { - if (error) { - callback(git.error(error), null); + fs.exists(directory, function directoryExists(exists) { + if (!exists) { + callback(new Error('Directory must exist'), null); return; } - self.repo = rawRepo; - callback(null, self); + self.repo.open(directory, function(error, rawRepo) { + if (error) { + callback(git.error(error), null); + return; + } + self.repo = rawRepo; + callback(null, self); + }); }); } diff --git a/test/convenience-repo.js b/test/convenience-repo.js index 6d9cf23cf..94e9eb4a6 100644 --- a/test/convenience-repo.js +++ b/test/convenience-repo.js @@ -1,6 +1,6 @@ -var git = require( '../' ); -var rimraf = require('rimraf'); -var fs = require( 'fs' ); +var git = require('../'), + rimraf = require('rimraf'), + fs = require( 'fs' ); // Helper functions var helper = { @@ -49,6 +49,18 @@ exports.method = function(test){ }); }; +/** + * Ensure repo doesn't attempt to open missing directories + */ +exports.nonexistentDirectory = function(test) { + test.expect(2); + git.repo('/surely/this/directory/does/not/exist/on/this/machine', function(error, repository) { + test.notEqual(error, null, 'Attempting to open a nonexistent directory should error'); + test.equals(repository, null, 'Non existent directory should result in null repository'); + test.done(); + }); +}; + /** * Repo::Init * From 1a0bd7f08f9094a3b31bad06d663371a13c97ebe Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 00:13:43 +1300 Subject: [PATCH 110/120] Realpath directory before attempting to open it --- lib/repo.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/repo.js b/lib/repo.js index 2335bd7bc..2420ba45b 100644 --- a/lib/repo.js +++ b/lib/repo.js @@ -19,13 +19,19 @@ exports.repo = function(directory, callback) { callback(new Error('Directory must exist'), null); return; } - self.repo.open(directory, function(error, rawRepo) { + fs.realpath(directory, function realpathCallback(error, directory) { if (error) { callback(git.error(error), null); return; } - self.repo = rawRepo; - callback(null, self); + self.repo.open(directory, function(error, rawRepo) { + if (error) { + callback(git.error(error), null); + return; + } + self.repo = rawRepo; + callback(null, self); + }); }); }); } From c2fd9c9449cf1f3437a4d6c1fddb588fcb3e6ff5 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:15:58 +1300 Subject: [PATCH 111/120] Removed todosources from binding.gyp --- binding.gyp | 2 -- 1 file changed, 2 deletions(-) diff --git a/binding.gyp b/binding.gyp index d8fa3d3e5..ad556410f 100644 --- a/binding.gyp +++ b/binding.gyp @@ -19,8 +19,6 @@ 'src/threads.cc', 'src/functions/string.cc' ], - 'todosources': [ - ], 'include_dirs': [ 'vendor/libv8-convert', From 98b95b15ed32f88d062b55133c79e09aec438ea9 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:16:22 +1300 Subject: [PATCH 112/120] Work towards normalizing testing code style --- test/convenience-error.js | 11 +-- test/convenience-tree.js | 6 +- test/raw-blob.js | 142 +++++++++++++++++++------------------- test/raw-commit.js | 44 ++++++------ test/raw-error.js | 14 ++-- test/raw-object.js | 22 +++--- test/raw-oid.js | 54 +++++++-------- test/raw-reference.js | 66 +++++++++--------- test/raw-repo.js | 44 ++++++------ test/raw-revwalk.js | 14 ++-- 10 files changed, 206 insertions(+), 211 deletions(-) diff --git a/test/convenience-error.js b/test/convenience-error.js index c2152f1aa..cb1b10cca 100644 --- a/test/convenience-error.js +++ b/test/convenience-error.js @@ -1,6 +1,6 @@ -var git = require('../'); -var rimraf = require('rimraf'); -var fs = require( 'fs' ); +var git = require('../'), + rimraf = require('rimraf'), + fs = require( 'fs' ); // Helper functions var helper = { @@ -30,9 +30,7 @@ var helper = { */ exports.method = function(test){ test.expect(2); - helper.testFunction(test.equals, git.error, 'Error'); - test.done(); }; @@ -44,11 +42,8 @@ exports.method = function(test){ exports.improperCommitId = function(test) { test.expect(1); git.repo('../.git', function(error, repository) { - repository.commit('not a proper commit sha', function(error, commit) { - test.notEqual(error.code, git.error.GIT_SUCCESS, 'Attempting to get commit by invalid SHA should error'); - test.done(); }); }); diff --git a/test/convenience-tree.js b/test/convenience-tree.js index d97e51b0e..5144a0137 100644 --- a/test/convenience-tree.js +++ b/test/convenience-tree.js @@ -1,6 +1,6 @@ -var git = require('../'); -var rimraf = require('rimraf'); -var fs = require('fs'); +var git = require('../'), + rimraf = require('rimraf'), + fs = require('fs'); var sha = '5716e9757886eaf38d51c86b192258c960d9cfea'; var fileCount = 513; diff --git a/test/raw-blob.js b/test/raw-blob.js index eab916974..c8ba41a71 100644 --- a/test/raw-blob.js +++ b/test/raw-blob.js @@ -1,173 +1,173 @@ -var git = require( '../' ).raw - , path = require( 'path' ) - , rimraf = require('rimraf'); +var git = require('../').raw, + path = require('path'), + rimraf = require('rimraf'); var testRepo = new git.Repo(); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, - // Test code and handle exception thrown - testException: function( test, fun, label ) { + // Test code and handle exception thrown + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; // Blob -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Blob, 'Blob' ); + helper.testFunction(test.equals, git.Blob, 'Blob'); // Ensure we get an instance of Blob - test.ok( new git.Blob() instanceof git.Blob, 'Invocation returns an instance of Blob' ); + test.ok(new git.Blob() instanceof git.Blob, 'Invocation returns an instance of Blob'); test.done(); }; // Blob::Lookup -exports.lookup = function( test ) { - var testOid = new git.Oid() - , testRef = new git.Ref( testRepo ) - , testBlob = new git.Blob(); +exports.lookup = function(test) { + var testOid = new git.Oid(), + testRef = new git.Ref(testRepo), + testBlob = new git.Blob(); - test.expect( 5 ); + test.expect(5); // Test for function - helper.testFunction( test.equals, testBlob.lookup, 'Blob::Lookup' ); + helper.testFunction(test.equals, testBlob.lookup, 'Blob::Lookup'); // Test repo argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { testBlob.lookup(); - }, 'Throw an exception if no repo Object' ); + }, 'Throw an exception if no repo Object'); // Test Oid argument existence - helper.testException( test.ok, function() { - testBlob.lookup( testRepo ); - }, 'Throw an exception if no oid Object' ); + helper.testException(test.ok, function() { + testBlob.lookup(testRepo); + }, 'Throw an exception if no oid Object'); // Test Callback argument existence - helper.testException( test.ok, function() { - testBlob.lookup( testRepo, testOid ); - }, 'Throw an exception if no callback Object' ); + helper.testException(test.ok, function() { + testBlob.lookup(testRepo, testOid); + }, 'Throw an exception if no callback Object'); - testRepo.open( path.resolve( '../.git' ), function() { + testRepo.open(path.resolve('../.git'), function() { - //testOid.mkstr( '59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5' ); + //testOid.mkstr('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5'); - //testCommit.lookup( testRepo, testOid, function( err ) { - // var tree = new git.Tree( testRepo ) + //testCommit.lookup(testRepo, testOid, function(err) { + // var tree = new git.Tree(testRepo) // , entry = new git.TreeEntry() - // , blob = new git.Blob( testRepo ); + // , blob = new git.Blob(testRepo); - // if( !testCommit.tree( tree ) && tree.entryCount() > 1 ) { - // tree.entryByIndex( entry, 1 ); - // entry.toObject( testRepo, blob ); + // if(!testCommit.tree(tree) && tree.entryCount() > 1) { + // tree.entryByIndex(entry, 1); + // entry.toObject(testRepo, blob); - // //console.log( entry.name() + ':' ); - // //console.log( blob.rawSize() ); - // //console.dir( blob.rawContent() ); + // //console.log(entry.name() + ':'); + // //console.log(blob.rawSize()); + // //console.dir(blob.rawContent()); // } //}); test.done(); - + }); }; // Blob::RawContent -exports.rawContent = function( test ) { +exports.rawContent = function(test) { var testOid = new git.Oid() , testBlob = new git.Blob() , testCommit = new git.Commit(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testBlob.rawContent, 'Blob::RawContent' ); + helper.testFunction(test.equals, testBlob.rawContent, 'Blob::RawContent'); - testRepo.open( path.resolve( '../.git' ), function() { - testOid.mkstr( '59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5' ); + testRepo.open(path.resolve('../.git'), function() { + testOid.mkstr('59b20b8d5c6ff8d09518454d4dd8b7b30f095ab5'); - testCommit.lookup( testRepo, testOid, function( err ) { - var tree = new git.Tree( testRepo ), + testCommit.lookup(testRepo, testOid, function(err) { + var tree = new git.Tree(testRepo), entry = new git.TreeEntry(), - blob = new git.Blob( testRepo ); + blob = new git.Blob(testRepo); - //if( !testCommit.tree( tree ) && tree.entryCount() > 1 ) { - // tree.entryByIndex( entry, 1 ); - // entry.toObject( testRepo, blob ); + //if(!testCommit.tree(tree) && tree.entryCount() > 1) { + // tree.entryByIndex(entry, 1); + // entry.toObject(testRepo, blob); - // //console.log( entry.name() + ':' ); - // //console.log( blob.rawSize() ); - // //console.dir( blob.rawContent() ); + // //console.log(entry.name() + ':'); + // //console.log(blob.rawSize()); + // //console.dir(blob.rawContent()); //} }); }); - + test.done(); }; // Blob::RawSize -exports.rawSize = function( test ) { +exports.rawSize = function(test) { var testOid = new git.Oid(), testBlob = new git.Blob(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testBlob.rawSize, 'Blob::RawSize' ); - + helper.testFunction(test.equals, testBlob.rawSize, 'Blob::RawSize'); + test.done(); }; // Blob::Close -exports.close = function( test ) { +exports.close = function(test) { var testOid = new git.Oid(), testBlob = new git.Blob(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testBlob.close, 'Blob::Close' ); - + helper.testFunction(test.equals, testBlob.close, 'Blob::Close'); + test.done(); }; // Blob::CreateFromFile -exports.createFromFile = function( test ) { +exports.createFromFile = function(test) { var testOid = new git.Oid(), testBlob = new git.Blob(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testBlob.createFromFile, 'Blob::Close' ); - + helper.testFunction(test.equals, testBlob.createFromFile, 'Blob::Close'); + test.done(); }; // Blob::CreateFromBuffer -exports.createFromBuffer = function( test ) { +exports.createFromBuffer = function(test) { var testOid = new git.Oid(), testBlob = new git.Blob(); - test.expect( 2 ); + test.expect(2); // Test for function - helper.testFunction( test.equals, testBlob.createFromBuffer, 'Blob::CreateFromBuffer' ); - + helper.testFunction(test.equals, testBlob.createFromBuffer, 'Blob::CreateFromBuffer'); + test.done(); }; diff --git a/test/raw-commit.js b/test/raw-commit.js index 02479b4ad..e66443ca5 100644 --- a/test/raw-commit.js +++ b/test/raw-commit.js @@ -1,25 +1,25 @@ -var git = require( '../' ).raw, - rimraf = require( 'rimraf' ), - path = require( 'path' ); +var git = require('../').raw, + rimraf = require('rimraf'), + path = require('path'); var testRepo = new git.Repo(); var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; @@ -28,14 +28,14 @@ var helper = { * Commit */ exports.constructor = function(test){ - test.expect( 3 ); + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Commit, 'Commit' ); + helper.testFunction(test.equals, git.Commit, 'Commit'); - testRepo.open( path.resolve( '../.git' ), function( err ) { + testRepo.open(path.resolve('../.git'), function(err) { // Ensure we get an instance of Commit - test.ok( new git.Commit( testRepo ) instanceof git.Commit, 'Invocation returns an instance of Commit' ); + test.ok(new git.Commit(testRepo) instanceof git.Commit, 'Invocation returns an instance of Commit'); test.done(); }); @@ -56,26 +56,26 @@ exports.lookup = function(test) { helper.testFunction(test.equals, testCommit.lookup, 'Commit::Lookup'); // Test repo argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { testCommit.lookup(); - }, 'Throw an exception if no repo' ); + }, 'Throw an exception if no repo'); // Test oid argument existence helper.testException(test.ok, function() { testCommit.lookup(testRepo); - }, 'Throw an exception if no oid' ); + }, 'Throw an exception if no oid'); // Test callback argument existence helper.testException(test.ok, function() { testCommit.lookup(testOid); - }, 'Throw an exception if no callback' ); + }, 'Throw an exception if no callback'); // Test that all arguments result correctly helper.testException(test.ifError, function() { - testCommit.lookup(testRepo, testOid, function() {} ); - }, 'No exception is thrown with proper arguments' ); + testCommit.lookup(testRepo, testOid, function() {}); + }, 'No exception is thrown with proper arguments'); - testRepo.open( path.resolve('../.git'), function() { + testRepo.open(path.resolve('../.git'), function() { // Test invalid commit testOid.mkstr('100644'); testCommit.lookup(testRepo, testOid, function(err) { @@ -83,10 +83,10 @@ exports.lookup = function(test) { // Test valid commit testOid.mkstr('cb76e3c030ab29db332aff3b297dc39451a84762'); - testCommit.lookup( testRepo, testOid, function(err) { + testCommit.lookup(testRepo, testOid, function(err) { test.equals(null, err, 'Valid commit'); - //test.equals( 'Updated gitignore and raw-commit test', testCommit.messageShort(), 'Commit message is valid' ); + //test.equals('Updated gitignore and raw-commit test', testCommit.messageShort(), 'Commit message is valid'); test.done(); }); diff --git a/test/raw-error.js b/test/raw-error.js index 622f4d54e..3c23a4244 100644 --- a/test/raw-error.js +++ b/test/raw-error.js @@ -1,23 +1,23 @@ -var git = require( '../' ).raw, +var git = require('../').raw, rimraf = require('rimraf'); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; diff --git a/test/raw-object.js b/test/raw-object.js index 7a04f76f7..df9235a8b 100644 --- a/test/raw-object.js +++ b/test/raw-object.js @@ -1,23 +1,23 @@ -var git = require( '../' ).raw, +var git = require('../').raw, rimraf = require('rimraf'); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; @@ -25,14 +25,14 @@ var helper = { var repo = new git.Repo(); // Obj -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Object, 'GitObject' ); + helper.testFunction(test.equals, git.Object, 'GitObject'); // Ensure we get an instance of Obj - test.ok( new git.Object() instanceof git.Object, 'Invocation returns an instance of GitObject' ); + test.ok(new git.Object() instanceof git.Object, 'Invocation returns an instance of GitObject'); test.done(); }; diff --git a/test/raw-oid.js b/test/raw-oid.js index d66b3c966..20219a6f8 100644 --- a/test/raw-oid.js +++ b/test/raw-oid.js @@ -1,23 +1,23 @@ -var git = require( '../' ).raw, +var git = require('../').raw, rimraf = require('rimraf'); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; @@ -30,69 +30,69 @@ exports.constructor = function(test){ helper.testFunction(test.equals, git.Oid, 'Oid'); // Ensure we get an instance of Oid - test.ok( new git.Oid() instanceof git.Oid, 'Invocation returns an instance of Oid' ); + test.ok(new git.Oid() instanceof git.Oid, 'Invocation returns an instance of Oid'); test.done(); }; // Oid::Mkstr -exports.mkstr = function( test ) { +exports.mkstr = function(test) { var testOid = new git.Oid(); - test.expect( 6 ); + test.expect(6); // Test for function - helper.testFunction( test.equals, testOid.mkstr, 'Oid::Mkstr' ); + helper.testFunction(test.equals, testOid.mkstr, 'Oid::Mkstr'); // Test path argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { testOid.mkstr(); - }, 'Throw an exception if no hex String' ); + }, 'Throw an exception if no hex String'); // Test that both arguments result correctly - helper.testException( test.ifError, function() { - testOid.mkstr( "somestr" ); - }, 'No exception is thrown with proper arguments' ); + helper.testException(test.ifError, function() { + testOid.mkstr("somestr"); + }, 'No exception is thrown with proper arguments'); // Test invalid hex id string test.equals(git.Error.returnCodes.GIT_ERROR, testOid.mkstr('1392DLFJIOS'), 'Invalid hex id String'); // Test valid hex id string - test.equals(git.Error.returnCodes.GIT_OK, testOid.mkstr( '1810DFF58D8A660512D4832E740F692884338CCD' ), 'Valid hex id String'); + test.equals(git.Error.returnCodes.GIT_OK, testOid.mkstr('1810DFF58D8A660512D4832E740F692884338CCD'), 'Valid hex id String'); test.done(); }; // Oid::Fmt -exports.fmt = function( test ) { +exports.fmt = function(test) { var testOid = new git.Oid(); - test.expect( 3 ); + test.expect(3); // Test for function - helper.testFunction( test.equals, testOid.fmt, 'Oid::Fmt' ); + helper.testFunction(test.equals, testOid.fmt, 'Oid::Fmt'); // Test valid hex id string - testOid.mkstr( '1810DFF58D8A660512D4832E740F692884338CCD' ); + testOid.mkstr('1810DFF58D8A660512D4832E740F692884338CCD'); // Slight hackery to get this to work... should investigate oid fmt - test.equals( '1810DFF58D8A660512D4832E740F692884338CCD', testOid.fmt().substring(0, 40).toUpperCase(), 'Valid hex id String' ); + test.equals('1810DFF58D8A660512D4832E740F692884338CCD', testOid.fmt().substring(0, 40).toUpperCase(), 'Valid hex id String'); test.done(); }; // Oid::Fmt -exports.toString = function( test ) { +exports.toString = function(test) { var testOid = new git.Oid(); - test.expect( 3 ); + test.expect(3); // Test for function - helper.testFunction( test.equals, testOid.toString, 'Oid::ToString' ); + helper.testFunction(test.equals, testOid.toString, 'Oid::ToString'); // Test valid hex id string - testOid.mkstr( '1810DFF58D8A660512D4832E740F692884338CCD' ); - test.equals( '1810DFF58D8A660512D4832E740F692884338CCD', testOid.toString( 40 ).toUpperCase(), 'Valid hex id String' ); + testOid.mkstr('1810DFF58D8A660512D4832E740F692884338CCD'); + test.equals('1810DFF58D8A660512D4832E740F692884338CCD', testOid.toString(40).toUpperCase(), 'Valid hex id String'); test.done(); }; diff --git a/test/raw-reference.js b/test/raw-reference.js index 08b003979..06afa0aaa 100644 --- a/test/raw-reference.js +++ b/test/raw-reference.js @@ -1,79 +1,79 @@ -var git = require( '../' ).raw, +var git = require('../').raw, rimraf = require('rimraf'); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, - // Test code and handle exception thrown - testException: function( test, fun, label ) { + // Test code and handle exception thrown + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; // Ref -exports.constructor = function( test ){ - test.expect( 3 ); +exports.constructor = function(test){ + test.expect(3); // Test for function - helper.testFunction( test.equals, git.Ref, 'Ref' ); - + helper.testFunction(test.equals, git.Ref, 'Ref'); + // Ensure we get an instance of Ref - test.ok( new git.Ref() instanceof git.Ref, 'Invocation returns an instance of Ref' ); + test.ok(new git.Ref() instanceof git.Ref, 'Invocation returns an instance of Ref'); test.done(); }; // Ref::Lookup -exports.lookup = function( test ) { +exports.lookup = function(test) { var testRepo = new git.Repo(), master = new git.Ref(); - test.expect( 5 ); + test.expect(5); // Test for function - helper.testFunction( test.equals, master.lookup, 'Ref::Lookup' ); + helper.testFunction(test.equals, master.lookup, 'Ref::Lookup'); // Test repo argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { master.lookup(); - }, 'Throw an exception if no repo' ); - + }, 'Throw an exception if no repo'); + // Test name argument existence - helper.testException( test.ok, function() { - master.lookup( testRepo ); - }, 'Throw an exception if no name' ); + helper.testException(test.ok, function() { + master.lookup(testRepo); + }, 'Throw an exception if no name'); // Test callback argument existence - helper.testException( test.ok, function() { - master.lookup( testRepo, 'refs/heads/master' ); - }, 'Throw an exception if no callback' ); + helper.testException(test.ok, function() { + master.lookup(testRepo, 'refs/heads/master'); + }, 'Throw an exception if no callback'); // Cleanup, remove test repo directory - if it exists - rimraf( './test.git', function() { + rimraf('./test.git', function() { // // Create bare repo and test for creation - // testRepo.init( './test.git', true, function( err, path, is_bare ) { - // test.equals( 0, err, 'Successfully created bare repository' ); + // testRepo.init('./test.git', true, function(err, path, is_bare) { + // test.equals(0, err, 'Successfully created bare repository'); // // Verify repo exists - // testRepo.open( './test.git', function(err, path) { - // test.equals( 0, err, 'Valid repository created' ); - // test.equals( true, is_bare, 'Returns valid is_bare value' ); + // testRepo.open('./test.git', function(err, path) { + // test.equals(0, err, 'Valid repository created'); + // test.equals(true, is_bare, 'Returns valid is_bare value'); - // testRepo.free(); + // testRepo.free(); // // Cleanup, remove test repo directory - // rimraf( './test.git', function() { + // rimraf('./test.git', function() { test.done(); // }); // }); diff --git a/test/raw-repo.js b/test/raw-repo.js index 81ad6672b..b6c475e21 100644 --- a/test/raw-repo.js +++ b/test/raw-repo.js @@ -1,25 +1,25 @@ -var git = require( '../' ).raw, +var git = require('../').raw, rimraf = require('rimraf'), - path = require( 'path' ), - fs = require( 'fs' ); + path = require('path'), + fs = require('fs'); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; @@ -47,9 +47,9 @@ exports.open = function(test) { helper.testFunction(test.equals, testRepo.open, 'Repo::Open'); // Test path argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { testRepo.open(); - }, 'Throw an exception if no path' ); + }, 'Throw an exception if no path'); // Test callback argument existence helper.testException(test.ok, function() { @@ -82,28 +82,28 @@ exports.free = function(test) { }; // Repo::Init -exports.init = function( test ) { +exports.init = function(test) { var testRepo = new git.Repo(); - test.expect( 7 ); + test.expect(7); // Test for function - helper.testFunction( test.equals, testRepo.init, 'Repo::Init' ); + helper.testFunction(test.equals, testRepo.init, 'Repo::Init'); // Test path argument existence - helper.testException( test.ok, function() { + helper.testException(test.ok, function() { testRepo.init(); - }, 'Throw an exception if no path' ); + }, 'Throw an exception if no path'); // Test is_bare argument existence - helper.testException( test.ok, function() { - testRepo.init( "some/path" ); - }, 'Throw an exception if no is_bare' ); + helper.testException(test.ok, function() { + testRepo.init("some/path"); + }, 'Throw an exception if no is_bare'); // Test callback argument existence - helper.testException( test.ok, function() { - testRepo.init( "some/path", true ); - }, 'Throw an exception if no callback' ); + helper.testException(test.ok, function() { + testRepo.init("some/path", true); + }, 'Throw an exception if no callback'); // Cleanup, remove test repo directory - if it exists rimraf('./test.git', function() { diff --git a/test/raw-revwalk.js b/test/raw-revwalk.js index c78cede3d..e7338fa32 100644 --- a/test/raw-revwalk.js +++ b/test/raw-revwalk.js @@ -1,4 +1,4 @@ -var git = require( '../' ).raw, +var git = require('../').raw, path = require('path'), rimraf = require('rimraf'); @@ -7,20 +7,20 @@ var testRepo = new git.Repo(); // Helper functions var helper = { // Test if obj is a true function - testFunction: function( test, obj, label ) { + testFunction: function(test, obj, label) { // The object reports itself as a function - test( typeof obj, 'function', label +' reports as a function.' ); + test(typeof obj, 'function', label +' reports as a function.'); // This ensures the repo is actually a derivative of the Function [[Class]] - test( toString.call( obj ), '[object Function]', label +' [[Class]] is of type function.' ); + test(toString.call(obj), '[object Function]', label +' [[Class]] is of type function.'); }, // Test code and handle exception thrown - testException: function( test, fun, label ) { + testException: function(test, fun, label) { try { fun(); - test( false, label ); + test(false, label); } catch (ex) { - test( true, label ); + test(true, label); } } }; From 1ac367ac834622a16787e506769f966930c8695e Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:17:56 +1300 Subject: [PATCH 113/120] Fix improper use of delete --- src/commit.cc | 8 +++----- src/diff_list.cc | 3 +-- src/reference.cc | 4 ++-- src/revwalk.cc | 8 ++------ src/tree.cc | 5 ++--- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/commit.cc b/src/commit.cc index 05cd27efc..2d0f32142 100755 --- a/src/commit.cc +++ b/src/commit.cc @@ -187,7 +187,6 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { HandleScope scope; FetchDetailsBaton* baton = static_cast(req->data); - delete req; if (baton->error) { Local argv[1] = { @@ -251,6 +250,7 @@ void GitCommit::FetchDetailsAfterWork(uv_work_t *req) { node::FatalException(try_catch); } } + delete req; } Handle GitCommit::Lookup(const Arguments& args) { @@ -307,9 +307,7 @@ void GitCommit::LookupWork(uv_work_t *req) { void GitCommit::LookupAfterWork(uv_work_t *req) { HandleScope scope; - LookupBaton *baton = static_cast(req->data); - delete req; if (baton->error) { Local argv[1] = { @@ -340,6 +338,7 @@ void GitCommit::LookupAfterWork(uv_work_t *req) { node::FatalException(try_catch); } } + delete req; } Handle GitCommit::Close(const Arguments& args) { @@ -436,9 +435,7 @@ void GitCommit::ParentWork(uv_work_t* req) { void GitCommit::ParentAfterWork(uv_work_t* req) { HandleScope scope; - ParentBaton* baton = static_cast(req->data); - delete req; if (baton->error) { Local argv[1] = { @@ -470,6 +467,7 @@ void GitCommit::ParentAfterWork(uv_work_t* req) { } } baton->commit->Unref(); + delete req; } Persistent GitCommit::constructor_template; diff --git a/src/diff_list.cc b/src/diff_list.cc index 09bcc2ca2..46d14db47 100755 --- a/src/diff_list.cc +++ b/src/diff_list.cc @@ -232,9 +232,7 @@ void GitDiffList::TreeToTreeWork(uv_work_t *req) { void GitDiffList::TreeToTreeAfterWork(uv_work_t *req) { HandleScope scope; - TreeToTreeBaton *baton = static_cast(req->data); - delete req; if (baton->error) { Local argv[1] = { @@ -261,6 +259,7 @@ void GitDiffList::TreeToTreeAfterWork(uv_work_t *req) { node::FatalException(try_catch); } } + delete req; } Handle GitDiffList::Walk(const Arguments& args) { diff --git a/src/reference.cc b/src/reference.cc index 58a4f64cd..0993635d9 100755 --- a/src/reference.cc +++ b/src/reference.cc @@ -108,9 +108,8 @@ void GitReference::EIO_Lookup(uv_work_t *req) { void GitReference::EIO_AfterLookup(uv_work_t *req) { HandleScope scope; - lookup_request *ar = static_cast(req->data); - delete req; + ar->ref->Unref(); Local argv[1]; @@ -126,6 +125,7 @@ void GitReference::EIO_AfterLookup(uv_work_t *req) { ar->callback.Dispose(); delete ar; + delete req; } Handle GitReference::Oid(const Arguments& args) { diff --git a/src/revwalk.cc b/src/revwalk.cc index 7ee6f5569..23a9d96c6 100755 --- a/src/revwalk.cc +++ b/src/revwalk.cc @@ -134,9 +134,7 @@ void GitRevWalk::PushWork(uv_work_t *req) { void GitRevWalk::PushAfterWork(uv_work_t *req) { HandleScope scope; - PushBaton *baton = static_cast(req->data); - delete req; Local argv[1]; if (baton->error) { @@ -146,12 +144,11 @@ void GitRevWalk::PushAfterWork(uv_work_t *req) { } TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - if (try_catch.HasCaught()) { node::FatalException(try_catch); } + delete req; } Handle GitRevWalk::Next(const Arguments& args) { @@ -189,9 +186,7 @@ void GitRevWalk::NextWork(uv_work_t *req) { void GitRevWalk::NextAfterWork(uv_work_t *req) { HandleScope scope; - NextBaton *baton = static_cast(req->data); - delete req; if (baton->error) { Local argv[1] = { @@ -225,6 +220,7 @@ void GitRevWalk::NextAfterWork(uv_work_t *req) { FatalException(try_catch); } } + delete req; } Handle GitRevWalk::Free(const Arguments& args) { diff --git a/src/tree.cc b/src/tree.cc index 8d39bb5de..14fa22efa 100755 --- a/src/tree.cc +++ b/src/tree.cc @@ -200,9 +200,6 @@ void GitTree::EIO_EntryByIndex(uv_work_t *req) { void GitTree::EIO_AfterEntryByIndex(uv_work_t *req) { entryindex_request *er = static_cast(req->data); - delete req; - er->tree->Unref(); - Handle argv[0]; TryCatch try_catch; @@ -214,6 +211,8 @@ void GitTree::EIO_AfterEntryByIndex(uv_work_t *req) { er->callback.Dispose(); + delete req; + er->tree->Unref(); delete er; } From 0b13fb51449c08a904b257173ddb6db7457e33ec Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:18:57 +1300 Subject: [PATCH 114/120] Removed some unused header entries --- include/repo.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/include/repo.h b/include/repo.h index b6d82f8a4..e5493b11d 100755 --- a/include/repo.h +++ b/include/repo.h @@ -20,13 +20,10 @@ class GitRepo : public ObjectWrap { public: static Persistent constructor_template; static void Initialize(Handle target); + git_repository* GetValue(); void SetValue(git_repository* repo); - // Asynchronous - int Open(const char* path); - int Init(const char* path, bool is_bare); - // Synchronous void Free(); @@ -39,10 +36,6 @@ class GitRepo : public ObjectWrap { static void OpenWork(uv_work_t* req); static void OpenAfterWork(uv_work_t* req); - static Handle Lookup(const Arguments& args); - static void EIO_Lookup(uv_work_t* req); - static void EIO_AfterLookup(uv_work_t* req); - static Handle Free(const Arguments& args); static Handle Init(const Arguments& args); @@ -64,11 +57,6 @@ class GitRepo : public ObjectWrap { Persistent callback; }; - struct lookup_request { - GitRepo* repo; - Persistent callback; - }; - struct InitBaton { uv_work_t request; const git_error* error; From 58a1276c133cd967faa4d7bb5a1123b41d502169 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:19:40 +1300 Subject: [PATCH 115/120] Code style normalization --- src/error.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/error.cc b/src/error.cc index 85c87dc74..9a7565607 100755 --- a/src/error.cc +++ b/src/error.cc @@ -86,11 +86,14 @@ void GitError::Initialize (Handle target) { } Local GitError::WrapError(const git_error* error) { + Local gitError = GitError::constructor_template->NewInstance(); Local stackTrace = StackTrace::CurrentStackTrace(10); + gitError->Set(String::NewSymbol("stackTrace"), cvv8::CastToJS(stackTrace->AsArray())); gitError->Set(String::NewSymbol("message"), String::New(error->message)); gitError->Set(String::NewSymbol("code"), Integer::New(error->klass)); + return gitError; } @@ -100,7 +103,7 @@ Handle GitError::New(const Arguments& args) { GitError *error = new GitError(); error->Wrap(args.This()); - return scope.Close( args.This() ); + return scope.Close(args.This()); } Persistent GitError::constructor_template; From 5d72807fe20365c85d4c9820b02c881b77029e35 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:21:22 +1300 Subject: [PATCH 116/120] Removed sync functions, updated lookup --- src/repo.cc | 96 +++++------------------------------------------------ 1 file changed, 8 insertions(+), 88 deletions(-) diff --git a/src/repo.cc b/src/repo.cc index 334d1f7ff..3104b62cc 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -16,6 +16,8 @@ #include "../include/commit.h" #include "../include/error.h" +#include "../include/functions/string.h" + using namespace v8; using namespace node; @@ -37,7 +39,7 @@ void GitRepo::Initialize(Handle target) { } git_repository* GitRepo::GetValue() { - return this->repo; + return this->repo; } void GitRepo::SetValue(git_repository* repo) { @@ -71,12 +73,11 @@ Handle GitRepo::Open(const Arguments& args) { OpenBaton *baton = new OpenBaton(); baton->request.data = baton; baton->error = NULL; - String::Utf8Value path(args[0]); - baton->path = *path; + baton->path = stringArgToString(args[0]->ToString());; baton->repo = ObjectWrap::Unwrap(args.This()); + baton->callback = Persistent::New(Handle::Cast(args[1])); + baton->repo->Ref(); - baton->rawRepo = baton->repo->GetValue(); - baton->callback = Persistent::New(Local::Cast(args[1])); uv_queue_work(uv_default_loop(), &baton->request, OpenWork, (uv_after_work_cb)OpenAfterWork); @@ -96,9 +97,6 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { HandleScope scope; OpenBaton *baton = static_cast(req->data); - delete req; - - baton->repo->Unref(); if (baton->error) { Local argv[1] = { @@ -106,9 +104,7 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { }; TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - if (try_catch.HasCaught()) { node::FatalException(try_catch); } @@ -127,84 +123,8 @@ void GitRepo::OpenAfterWork(uv_work_t *req) { node::FatalException(try_catch); } } -} - -Handle GitRepo::Lookup(const Arguments& args) { - HandleScope scope; - - GitRepo *repo = ObjectWrap::Unwrap(args.This()); - Local callback; - - if(args.Length() == 0 || !args[0]->IsObject()) { - return ThrowException(Exception::Error(String::New("Object is required and must be a Object."))); - } - - if(args.Length() == 1 || !args[1]->IsObject()) { - return ThrowException(Exception::Error(String::New("GitRepo is required and must be a Object."))); - } - - if(args.Length() == 2 || !args[2]->IsObject()) { - return ThrowException(Exception::Error(String::New("Oid is required and must be a Object."))); - } - - if(args.Length() == 3 || !args[3]->IsFunction()) { - return ThrowException(Exception::Error(String::New("Callback is required and must be a Function."))); - } - - callback = Local::Cast(args[3]); - - lookup_request *ar = new lookup_request(); - ar->repo = repo; - ar->callback = Persistent::New(callback); - - repo->Ref(); - - //eio_custom(EIO_LookupRef, EIO_PRI_DEFAULT, EIO_AfterLookupRef, ar); - //ev_ref(EV_DEFAULT_UC); - - return scope.Close( Undefined() ); -} - -void GitRepo::EIO_Lookup(uv_work_t *req) { - //lookup_request *ar = static_cast(req->data); - // - //String::Utf8Value name(ar->name); - //git_reference *ref; - // - //int err = ar->repo->LookupRef((git_reference **)ref, *name); - //ar->err = Persistent::New(Integer::New(err)); - // - //if(Int32::Cast(*ar->err)->Value() == 0) { - // ar->ref->SetValue(*&ref); - //} - // - //return 0; -} - -void GitRepo::EIO_AfterLookup(uv_work_t *req) { - //HandleScope scope; - - //lookup_request *ar = static_cast(req->data); - // delete req; - //ar->repo->Unref(); - - //Local argv[1]; - //argv[0] = Number::Cast(*ar->err); - - //TryCatch try_catch; - - //ar->callback->Call(Context::GetCurrent()->Global(), 1, argv); - - //if(try_catch.HasCaught()) - // FatalException(try_catch); - // - //ar->err.Dispose(); - //ar->name.Dispose(); - //ar->callback.Dispose(); - - //delete ar; - - //return 0; + delete req; + baton->repo->Unref(); } Handle GitRepo::Free(const Arguments& args) { From 226f24157c2b5404552a1d153e9e577f085885ed Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:22:30 +1300 Subject: [PATCH 117/120] Re-order deletions to prevent segfault --- src/repo.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/repo.cc b/src/repo.cc index 3104b62cc..18aec2471 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -30,7 +30,6 @@ void GitRepo::Initialize(Handle target) { tpl->SetClassName(String::NewSymbol("Repo")); NODE_SET_PROTOTYPE_METHOD(tpl, "open", Open); - NODE_SET_PROTOTYPE_METHOD(tpl, "lookup", Lookup); NODE_SET_PROTOTYPE_METHOD(tpl, "free", Free); NODE_SET_PROTOTYPE_METHOD(tpl, "init", Init); @@ -182,8 +181,6 @@ void GitRepo::InitAfterWork(uv_work_t *req) { HandleScope scope; InitBaton *baton = static_cast(req->data); - delete req; - baton->repo->Unref(); Local argv[1]; if (baton->error) { @@ -193,12 +190,12 @@ void GitRepo::InitAfterWork(uv_work_t *req) { } TryCatch try_catch; - baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); - if (try_catch.HasCaught()) { node::FatalException(try_catch); } + delete req; + baton->repo->Unref(); } Persistent GitRepo::constructor_template; From 58e43b182b10c8226b45efdac2e1c9d4ec65dfaf Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:24:04 +1300 Subject: [PATCH 118/120] Remove unused include --- src/repo.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/repo.cc b/src/repo.cc index 18aec2471..42e05026f 100755 --- a/src/repo.cc +++ b/src/repo.cc @@ -7,7 +7,6 @@ #include #include -#include #include "../vendor/libgit2/include/git2.h" From 123992094872e9d3146fb2a9468243316d606346 Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:24:40 +1300 Subject: [PATCH 119/120] Version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e29c00998..a3e7c9f5f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.0.72", + "version": "0.0.73", "homepage": "https://github.com/tbranyen/nodegit", "keywords": [ "libgit2", From f0de6d280d092646d051cf5d020abf8388e8e51a Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 21 Mar 2013 22:26:01 +1300 Subject: [PATCH 120/120] Upadted libgit2 --- vendor/libgit2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/libgit2 b/vendor/libgit2 index b70bf922a..7dbf4039a 160000 --- a/vendor/libgit2 +++ b/vendor/libgit2 @@ -1 +1 @@ -Subproject commit b70bf922a1de35722904930c42467e95c889562f +Subproject commit 7dbf4039ae0881407fc9ead24c09c1d7cfd4103a