Skip to content

Commit 2d7d237

Browse files
committed
Added blobsOnly flag to walk, if true only blobs & blob executables are returned during a walk
1 parent 42dc736 commit 2d7d237

File tree

3 files changed

+50
-26
lines changed

3 files changed

+50
-26
lines changed

include/tree.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class GitTree : public ObjectWrap {
7272
std::vector<WalkEntry* > rawTreeEntries;
7373

7474
git_tree* rawTree;
75+
bool blobsOnly;
76+
7577
Persistent<Function> entryCallback;
7678
Persistent<Function> endCallback;
7779
};

lib/tree.js

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,34 @@ Tree.prototype.entry = function(path, callback) {
4848
* @fires Tree#entry
4949
* @fires Tree#end
5050
*
51+
* @param {Boolean} [blobsOnly = true] True to emit only blob & blob executable entries.
52+
*
5153
* @return {EventEmitter}
5254
*/
53-
Tree.prototype.walk = function() {
55+
Tree.prototype.walk = function(blobsOnly) {
56+
blobsOnly = typeof blobsOnly === 'undefined' ? true : blobsOnly;
57+
5458
var self = this,
5559
event = new events.EventEmitter(),
5660
entries = [];
5761

58-
self.rawTree.walk(function treeWalkEntries(error, rawEntries) {
62+
var total = 0;
63+
64+
self.rawTree.walk(blobsOnly, function treeWalkEntries(error, rawEntries) {
5965
rawEntries.forEach(function treeWalkEntryEmitter(rawEntry) {
6066
var entry = new git.entry(self.rawRepo, rawEntry);
6167
entries.push(entry);
62-
if (!error) {
63-
/**
64-
* Entry event.
65-
*
66-
* @event Tree#entry
67-
*
68-
* @param {GitError|null} error An error object if there was an issue, null otherwise.
69-
* @param {Entry} entry The tree entry.
70-
*/
71-
event.emit('entry', null, entry);
72-
}
68+
/**
69+
* Entry event.
70+
*
71+
* @event Tree#entry
72+
*
73+
* @param {GitError|null} error An error object if there was an issue, null otherwise.
74+
* @param {Entry} entry The tree entry.
75+
*/
76+
event.emit('entry', null, entry);
7377
});
7478
}, function treeWalkEnd(error) {
75-
if (error) {
76-
event.emit('end', git.error(error), entries);
77-
}
7879
/**
7980
* End event.
8081
*
@@ -83,7 +84,7 @@ Tree.prototype.walk = function() {
8384
* @param {GitError|null} error An error object if there was an issue, null otherwise.
8485
* @param {Entry[]} entries The tree entries.
8586
*/
86-
event.emit('end', null, entries);
87+
event.emit('end', error ? git.error(error) : null, entries);
8788
});
8889

8990
return event;

src/tree.cc

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,15 @@ Handle<Value> GitTree::Walk(const Arguments& args) {
6666
return ThrowException(Exception::Error(String::New("No tree list to Walk.")));
6767
}
6868

69-
if(args.Length() == 0 || !args[0]->IsFunction()) {
70-
return ThrowException(Exception::Error(String::New("Entry callback is required and must be a Function.")));
69+
if(args.Length() == 0 || !args[0]->IsBoolean()) {
70+
return ThrowException(Exception::Error(String::New("Blobs only flag is required and must be a Boolean.")));
7171
}
7272

7373
if(args.Length() == 1 || !args[1]->IsFunction()) {
74+
return ThrowException(Exception::Error(String::New("Entry callback is required and must be a Function.")));
75+
}
76+
77+
if(args.Length() == 2 || !args[2]->IsFunction()) {
7478
return ThrowException(Exception::Error(String::New("End callback is required and must be a Function.")));
7579
}
7680

@@ -82,8 +86,9 @@ Handle<Value> GitTree::Walk(const Arguments& args) {
8286

8387
baton->rawTree = tree->GetValue();
8488
baton->error = NULL;
85-
baton->entryCallback = Persistent<Function>::New(Local<Function>::Cast(args[0]));
86-
baton->endCallback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
89+
baton->blobsOnly = CastFromJS<bool>(args[0]->ToBoolean());
90+
baton->entryCallback = Persistent<Function>::New(Local<Function>::Cast(args[1]));
91+
baton->endCallback = Persistent<Function>::New(Local<Function>::Cast(args[2]));
8792

8893
uv_thread_create(&baton->threadId, WalkWork, baton);
8994

@@ -106,16 +111,32 @@ void GitTree::WalkWork(void* payload) {
106111
baton->asyncEnd.data = baton;
107112
uv_async_send(&baton->asyncEnd);
108113
}
109-
int GitTree::WalkWorkEntry(const char* root, const git_tree_entry* entry, void* payload) {
114+
int GitTree::WalkWorkEntry(const char* root, const git_tree_entry* entry,
115+
void* payload) {
110116
WalkBaton *baton = static_cast<WalkBaton *>(payload);
111117

112118
uv_mutex_lock(&baton->mutex);
113119

114-
GitTree::WalkEntry* walkEntry = new WalkEntry;
115-
walkEntry->rawEntry = git_tree_entry_dup(entry);
116-
walkEntry->root = root;
120+
if (!baton->blobsOnly) {
121+
122+
GitTree::WalkEntry* walkEntry = new WalkEntry;
123+
walkEntry->rawEntry = git_tree_entry_dup(entry);
124+
walkEntry->root = root;
125+
baton->rawTreeEntries.push_back(walkEntry);
117126

118-
baton->rawTreeEntries.push_back(walkEntry);
127+
} else {
128+
git_tree_entry* rawEntry = git_tree_entry_dup(entry);
129+
git_filemode_t fileMode = git_tree_entry_filemode(rawEntry);
130+
131+
if (fileMode == GIT_FILEMODE_BLOB ||
132+
fileMode == GIT_FILEMODE_BLOB_EXECUTABLE) {
133+
134+
GitTree::WalkEntry* walkEntry = new WalkEntry;
135+
walkEntry->rawEntry = rawEntry;
136+
walkEntry->root = root;
137+
baton->rawTreeEntries.push_back(walkEntry);
138+
}
139+
}
119140

120141
uv_mutex_unlock(&baton->mutex);
121142

0 commit comments

Comments
 (0)