Browse files

Add Repository.getHeadBlob(path)

Closes #3
  • Loading branch information...
1 parent 88a4942 commit e3a0f5b9045040c874b07343e983c95df9f04f6c @gjtorikian gjtorikian committed with kevinsawicki Mar 28, 2013
Showing with 70 additions and 0 deletions.
  1. +4 −0 README.md
  2. +18 −0 spec/git-spec.coffee
  3. +47 −0 src/repository.cc
  4. +1 −0 src/repository.h
View
4 README.md
@@ -38,6 +38,10 @@ repository = git.open('/Users/me/repos/node')
### Repository.getDiffStats(path)
+### Repository.getHeadBlob(path)
+
+Similar to `git show HEAD:<path>`. Retrieves the blob as defined in HEAD.
+
### Repository.getHead()
### Repository.getLineDiffs(path, text)
View
18 spec/git-spec.coffee
@@ -190,6 +190,24 @@ describe "git", ->
fs.writeFileSync(filePath, 'changing\nb.txt\nwith lines', 'utf8')
expect(repo.getDiffStats('b.txt')).toEqual {added: 0, deleted: 0}
+ describe '.getHeadBlob(path)', ->
+ repo = null
+
+ beforeEach ->
+ repoDirectory = temp.mkdirSync('node-git-repo-')
+ wrench.copyDirSyncRecursive(path.join(__dirname, 'fixtures/master.git'), path.join(repoDirectory, '.git'))
+ repo = git.open(repoDirectory)
+
+ describe 'when a path is modified', ->
+ it 'returns the original', ->
+ filePath = path.join(repo.getWorkingDirectory(), 'a.txt')
+ fs.writeFileSync(filePath, 'changing\na.txt', 'utf8')
+ expect(repo.getHeadBlob('a.txt')).toBe 'first line\n'
+
+ describe 'when a path is not modified', ->
+ it 'returns the original', ->
+ expect(repo.getHeadBlob('a.txt')).toBe 'first line\n'
+
describe '.getStatus([path])', ->
repo = null
View
47 src/repository.cc
@@ -45,6 +45,9 @@ void Repository::Init(Handle<Object> target) {
Local<Function> getDiffStats = FunctionTemplate::New(Repository::GetDiffStats)->GetFunction();
tpl->PrototypeTemplate()->Set(String::NewSymbol("getDiffStats"), getDiffStats);
+ Local<Function> GetHeadBlob = FunctionTemplate::New(Repository::GetHeadBlob)->GetFunction();
+ tpl->PrototypeTemplate()->Set(String::NewSymbol("getHeadBlob"), GetHeadBlob);
+
Local<Function> getCommitCount = FunctionTemplate::New(Repository::GetCommitCount)->GetFunction();
tpl->PrototypeTemplate()->Set(String::NewSymbol("getCommitCount"), getCommitCount);
@@ -323,6 +326,50 @@ Handle<Value> Repository::GetDiffStats(const Arguments& args) {
return scope.Close(result);
}
+Handle<Value> Repository::GetHeadBlob(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1)
+ return scope.Close(Null());
+
+ String::Utf8Value utf8Path(Local<String>::Cast(args[0]));
+ string path(*utf8Path);
+
+ git_repository *repo = GetRepository(args);
+ git_reference *head;
+ if (git_repository_head(&head, repo) != GIT_OK)
+ return scope.Close(Null());
+
+ const git_oid *sha = git_reference_target(head);
+ git_commit *commit;
+ int commitStatus = git_commit_lookup(&commit, repo, sha);
+ git_reference_free(head);
+ if (commitStatus != GIT_OK)
+ return scope.Close(Null());
+
+ git_tree *tree;
+ int treeStatus = git_commit_tree(&tree, commit);
+ git_commit_free(commit);
+ if (treeStatus != GIT_OK)
+ return scope.Close(Null());
+
+ git_tree_entry *treeEntry;
+ git_tree_entry_bypath(&treeEntry, tree, path.data());
+ git_blob *blob = NULL;
+ if (treeEntry != NULL) {
+ const git_oid *blobSha = git_tree_entry_id(treeEntry);
+ if (blobSha == NULL || git_blob_lookup(&blob, repo, blobSha) != GIT_OK)
+ blob = NULL;
+ }
+ git_tree_free(tree);
+ if (blob == NULL)
+ return scope.Close(Null());
+
+ const char *content = (const char *) git_blob_rawcontent(blob);
+ git_blob_free(blob);
+
+ return scope.Close(String::NewSymbol(content));
+}
+
int Repository::StatusCallback(const char *path, unsigned int status, void *payload) {
map<string, unsigned int> *statuses = (map<string, unsigned int> *) payload;
statuses->insert(pair<string, unsigned int>(string(path), status));
View
1 src/repository.h
@@ -21,6 +21,7 @@ class Repository : public node::ObjectWrap {
static Handle<Value> CheckoutHead(const Arguments& args);
static Handle<Value> GetReferenceTarget(const Arguments& args);
static Handle<Value> GetDiffStats(const Arguments& args);
+ static Handle<Value> GetHeadBlob(const Arguments& args);
static Handle<Value> GetCommitCount(const Arguments& args);
static Handle<Value> GetMergeBase(const Arguments& args);
static Handle<Value> Release(const Arguments& args);

0 comments on commit e3a0f5b

Please sign in to comment.