diff --git a/CHANGELOG.md b/CHANGELOG.md index 5746adfc5..a94ef89c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## [0.11.0](https://github.com/nodegit/nodegit/releases/tag/v0.11.1) (2016-02-09) + +[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.0...v0.11.1) + +- Numerous fixes and perf boosts to file history +- Several doc fixes + ## [0.11.0](https://github.com/nodegit/nodegit/releases/tag/v0.11.0) (2016-02-04) [Full Changelog](https://github.com/nodegit/nodegit/compare/v0.10.0...v0.11.0) diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc index 2ad9a24ed..0f511969f 100644 --- a/generate/templates/manual/revwalk/file_history_walk.cc +++ b/generate/templates/manual/revwalk/file_history_walk.cc @@ -55,6 +55,10 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() } git_diff *diffs; + git_diff_options opts = GIT_DIFF_OPTIONS_INIT; + char *file_path = strdup(baton->file_path); + opts.pathspec.strings = &file_path; + opts.pathspec.count = 1; git_commit *parent; unsigned int parents = git_commit_parentcount(nextCommit); if (parents > 1) { @@ -67,19 +71,23 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() } if ( (baton->error_code = git_commit_tree(&parentTree, parent)) != GIT_OK || - (baton->error_code = git_diff_tree_to_tree(&diffs, repo, parentTree, thisTree, NULL)) != GIT_OK + (baton->error_code = git_diff_tree_to_tree(&diffs, repo, parentTree, thisTree, &opts)) != GIT_OK ) { git_commit_free(nextCommit); git_commit_free(parent); break; } } else { - if ((baton->error_code = git_diff_tree_to_tree(&diffs, repo, NULL, thisTree, NULL)) != GIT_OK) { + if ((baton->error_code = git_diff_tree_to_tree(&diffs, repo, NULL, thisTree, &opts)) != GIT_OK) { git_commit_free(nextCommit); break; } } + free(file_path); + opts.pathspec.strings = NULL; + opts.pathspec.count = 0; + bool flag = false; bool doRenamedPass = false; unsigned int numDeltas = git_diff_num_deltas(diffs); @@ -127,10 +135,29 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() } } - if ( - doRenamedPass && - (baton->error_code = git_diff_find_similar(diffs, NULL)) == GIT_OK - ) { + if (doRenamedPass) { + git_diff_free(diffs); + + if (parents == 1) { + if ((baton->error_code = git_diff_tree_to_tree(&diffs, repo, parentTree, thisTree, NULL)) != GIT_OK) { + git_commit_free(nextCommit); + break; + } + if ((baton->error_code = git_diff_find_similar(diffs, NULL)) != GIT_OK) { + git_commit_free(nextCommit); + break; + } + } else { + if ((baton->error_code = git_diff_tree_to_tree(&diffs, repo, NULL, thisTree, NULL)) != GIT_OK) { + git_commit_free(nextCommit); + break; + } + if((baton->error_code = git_diff_find_similar(diffs, NULL)) != GIT_OK) { + git_commit_free(nextCommit); + break; + } + } + flag = false; numDeltas = git_diff_num_deltas(diffs); for (unsigned int j = 0; j < numDeltas; ++j) { @@ -148,13 +175,20 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() const git_diff_delta *delta = git_patch_get_delta(nextPatch); bool isEqualOldFile = !strcmp(delta->old_file.path, baton->file_path); bool isEqualNewFile = !strcmp(delta->new_file.path, baton->file_path); + int oldLen = strlen(delta->old_file.path); + int newLen = strlen(delta->new_file.path); + char *outPair = new char[oldLen + newLen + 2]; + strcpy(outPair, delta->new_file.path); + outPair[newLen] = '\n'; + outPair[newLen + 1] = '\0'; + strcat(outPair, delta->old_file.path); if (isEqualNewFile) { std::pair > *historyEntry; if (!isEqualOldFile) { historyEntry = new std::pair >( nextCommit, - std::pair(strdup(delta->old_file.path), delta->status) + std::pair(strdup(outPair), delta->status) ); } else { historyEntry = new std::pair >( @@ -164,8 +198,18 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() } baton->out->push_back(historyEntry); flag = true; + } else if (isEqualOldFile) { + std::pair > *historyEntry; + historyEntry = new std::pair >( + nextCommit, + std::pair(strdup(outPair), delta->status) + ); + baton->out->push_back(historyEntry); + flag = true; } + delete[] outPair; + git_patch_free(nextPatch); if (flag) { @@ -220,7 +264,13 @@ void GitRevwalk::FileHistoryWalkWorker::HandleOKCallback() Nan::Set(historyEntry, Nan::New("commit").ToLocalChecked(), GitCommit::New(batonResult->first, true)); Nan::Set(historyEntry, Nan::New("status").ToLocalChecked(), Nan::New(batonResult->second.second)); if (batonResult->second.second == GIT_DELTA_RENAMED) { - Nan::Set(historyEntry, Nan::New("oldName").ToLocalChecked(), Nan::New(batonResult->second.first).ToLocalChecked()); + char *namePair = batonResult->second.first; + char *split = strchr(namePair, '\n'); + *split = '\0'; + char *oldName = split + 1; + + Nan::Set(historyEntry, Nan::New("oldName").ToLocalChecked(), Nan::New(oldName).ToLocalChecked()); + Nan::Set(historyEntry, Nan::New("newName").ToLocalChecked(), Nan::New(namePair).ToLocalChecked()); } Nan::Set(result, Nan::New(i), historyEntry); diff --git a/lib/commit.js b/lib/commit.js index 2f7627ce7..116af204b 100644 --- a/lib/commit.js +++ b/lib/commit.js @@ -151,7 +151,7 @@ Commit.prototype.getParents = function(limit, callback) { * Retrieve the commit"s parent shas. * * @param {Function} callback - * @return {Array} array of oids + * @return {Array} array of oids */ Commit.prototype.parents = function() { var result = []; diff --git a/lib/convenient_hunks.js b/lib/convenient_hunks.js index 7c8edb17a..774e8e4a3 100644 --- a/lib/convenient_hunks.js +++ b/lib/convenient_hunks.js @@ -60,4 +60,4 @@ var oldStart = ConvenientHunk.prototype.oldStart; */ ConvenientHunk.prototype.oldStart = oldStart; - exports.module = ConvenientHunk; +module.exports = ConvenientHunk; diff --git a/lib/convenient_patch.js b/lib/convenient_patch.js index b8f3d86e5..518533554 100644 --- a/lib/convenient_patch.js +++ b/lib/convenient_patch.js @@ -4,15 +4,15 @@ var ConvenientPatch = NodeGit.ConvenientPatch; var oldFile = ConvenientPatch.prototype.oldFile; /** - * Old name of the file - * @return {String} + * Old attributes of the file + * @return {DiffFile} */ ConvenientPatch.prototype.oldFile = oldFile; var newFile = ConvenientPatch.prototype.newFile; /** - * New name of the file - * @return {String} + * New attributes of the file + * @return {DiffFile} */ ConvenientPatch.prototype.newFile = newFile; @@ -129,6 +129,6 @@ var isConflicted = ConvenientPatch.prototype.isConflicted; * Is this a conflicted patch? * @return {Boolean} */ - ConvenientPatch.prototype.isConflicted = isConflicted; +ConvenientPatch.prototype.isConflicted = isConflicted; - exports.module = ConvenientPatch; +module.exports = ConvenientPatch; diff --git a/lib/diff_file.js b/lib/diff_file.js new file mode 100644 index 000000000..2c2dc757e --- /dev/null +++ b/lib/diff_file.js @@ -0,0 +1,40 @@ +var NodeGit = require("../"); + +var DiffFile = NodeGit.DiffFile; + +var flags = DiffFile.prototype.flags; +/** + * Returns the file's flags + * @return {Number} + */ +DiffFile.prototype.flags = flags; + +var id = DiffFile.prototype.id; +/** + * Returns the file's Oid + * @return {Oid} + */ +DiffFile.prototype.id = id; + +var mode = DiffFile.prototype.mode; +/** + * Returns the file's mode + * @return {Number} + */ +DiffFile.prototype.mode = mode; + +var path = DiffFile.prototype.path; +/** + * Returns the file's path + * @return {String} + */ +DiffFile.prototype.path = path; + +var size = DiffFile.prototype.size; +/** + * Returns the file's size + * @return {Number} + */ +DiffFile.prototype.size = size; + +module.exports = DiffFile; diff --git a/lib/repository.js b/lib/repository.js index 50a165bf5..121543ebd 100644 --- a/lib/repository.js +++ b/lib/repository.js @@ -33,7 +33,7 @@ Object.defineProperty(Repository.prototype, "openIndex", { * @param {bool} force Overwrite branch if it exists * @param {Signature} signature Identity to use to populate reflog * @param {String} logMessage One line message to be appended to the reflog - * @return {Ref} + * @return {Reference} */ Repository.prototype.createBranch = function(name, commit, force) { @@ -86,8 +86,8 @@ Repository.discover = function(startPath, acrossFs, ceilingDirs, callback) { * Look up a refs's commit. * * @async - * @param {String|Ref} name Ref name, e.g. "master", "refs/heads/master" - * or Branch Ref + * @param {String|Reference} name Ref name, e.g. "master", "refs/heads/master" + * or Branch Ref * @return {Commit} */ Repository.prototype.getReferenceCommit = function(name, callback) { @@ -108,9 +108,9 @@ Repository.prototype.getReferenceCommit = function(name, callback) { * Look up a branch. Alias for `getReference` * * @async -* @param {String|Ref} name Ref name, e.g. "master", "refs/heads/master" -* or Branch Ref -* @return {Ref} +* @param {String|Reference} name Ref name, e.g. "master", "refs/heads/master" +* or Branch Ref +* @return {Reference} */ Repository.prototype.getBranch = function(name, callback) { return this.getReference(name, callback); @@ -120,7 +120,7 @@ Repository.prototype.getBranch = function(name, callback) { * Look up a branch's most recent commit. Alias to `getReferenceCommit` * * @async -* @param {String|Ref} name Ref name, e.g. "master", "refs/heads/master" +* @param {String|Reference} name Ref name, e.g. "master", "refs/heads/master" * or Branch Ref * @return {Commit} */ @@ -142,8 +142,8 @@ Repository.prototype.getCurrentBranch = function() { * Lookup the reference with the given name. * * @async - * @param {String|Ref} name Ref name, e.g. "master", "refs/heads/master" - * or Branch Ref + * @param {String|Reference} name Ref name, e.g. "master", "refs/heads/master" + * or Branch Ref * @return {Reference} */ Repository.prototype.getReference = function(name, callback) { @@ -549,7 +549,7 @@ Repository.prototype.createCommitOnHead = function( * Create a blob from a buffer * * @param {Buffer} buffer - * @return {Blob} + * @return {Oid} */ Repository.prototype.createBlobFromBuffer = function(buffer, callback) { return Blob.createFromBuffer(this, buffer, buffer.length, callback); @@ -728,8 +728,8 @@ Repository.prototype.fetchAll = function( /** * Merge a branch onto another branch * - * @param {String|Ref} to - * @param {String|Ref} from + * @param {String|Reference} to + * @param {String|Reference} from * @param {Signature} signature * @param {Merge.PREFERENCE} mergePreference * @param {MergeOptions} mergeOptions diff --git a/lib/revwalk.js b/lib/revwalk.js index d3cfa0456..d754259c6 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -129,6 +129,8 @@ Revwalk.prototype.getCommits = function(count) { * @type {Object} * @property {Commit} commit the commit for this entry * @property {Number} status the status of the file in the commit + * @property {String} newName the new name that is provided when status is + * renamed * @property {String} oldName the old name that is provided when status is * renamed */ diff --git a/package.json b/package.json index b41500a0c..29fa3b13d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.11.0", + "version": "0.11.1", "homepage": "http://nodegit.org", "keywords": [ "libgit2", diff --git a/test/tests/revwalk.js b/test/tests/revwalk.js index 518dd3cd3..85d708303 100644 --- a/test/tests/revwalk.js +++ b/test/tests/revwalk.js @@ -235,6 +235,8 @@ describe("Revwalk", function() { var repoPath = local("../repos/renamedFileRepo"); var signature = NodeGit.Signature.create("Foo bar", "foo@bar.com", 123456789, 60); + var headCommit; + return RepoUtils.createRepository(repoPath) .then(function(r) { repo = r; @@ -276,6 +278,7 @@ describe("Revwalk", function() { return NodeGit.Reference.nameToId(repo, "HEAD"); }) .then(function(commitOid) { + headCommit = commitOid.tostrS(); var walker = repo.createRevWalk(); walker.sorting(NodeGit.Revwalk.SORT.TIME); walker.push(commitOid.tostrS()); @@ -283,6 +286,18 @@ describe("Revwalk", function() { }) .then(function(results) { assert.equal(results[0].status, NodeGit.Diff.DELTA.RENAMED); + assert.equal(results[0].newName, fileNameB); + assert.equal(results[0].oldName, fileNameA); + }) + .then(function() { + var walker = repo.createRevWalk(); + walker.sorting(NodeGit.Revwalk.SORT.TIME); + walker.push(headCommit); + return walker.fileHistoryWalk(fileNameA, 5); + }) + .then(function(results) { + assert.equal(results[0].status, NodeGit.Diff.DELTA.RENAMED); + assert.equal(results[0].newName, fileNameB); assert.equal(results[0].oldName, fileNameA); }) .then(function() {