From f4cd577701e0e67cf39721bf77c2b19dcece0f1d Mon Sep 17 00:00:00 2001 From: Tyler Wanek Date: Fri, 5 Feb 2016 09:50:29 -0700 Subject: [PATCH 01/10] Hot fix historywalk was dropping deleted events due to rename detection. --- .../templates/manual/revwalk/file_history_walk.cc | 10 +++++++++- lib/revwalk.js | 2 +- test/tests/revwalk.js | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc index 2ad9a24ed..5bf53e394 100644 --- a/generate/templates/manual/revwalk/file_history_walk.cc +++ b/generate/templates/manual/revwalk/file_history_walk.cc @@ -164,6 +164,14 @@ 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(delta->new_file.path), delta->status) + ); + baton->out->push_back(historyEntry); + flag = true; } git_patch_free(nextPatch); @@ -220,7 +228,7 @@ 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()); + Nan::Set(historyEntry, Nan::New("altname").ToLocalChecked(), Nan::New(batonResult->second.first).ToLocalChecked()); } Nan::Set(result, Nan::New(i), historyEntry); diff --git a/lib/revwalk.js b/lib/revwalk.js index d3cfa0456..d0a5c653b 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -129,7 +129,7 @@ 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} oldName the old name that is provided when status is + * @property {String} altname the other name that is provided when status is * renamed */ diff --git a/test/tests/revwalk.js b/test/tests/revwalk.js index 518dd3cd3..b21d59b07 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,7 +286,17 @@ describe("Revwalk", function() { }) .then(function(results) { assert.equal(results[0].status, NodeGit.Diff.DELTA.RENAMED); - assert.equal(results[0].oldName, fileNameA); + assert.equal(results[0].altname, 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].altname, fileNameB); }) .then(function() { return fse.remove(repoPath); From 3b10568ee056ef555ee58246634218a5f19bb780 Mon Sep 17 00:00:00 2001 From: John Vilk Date: Sun, 7 Feb 2016 17:15:50 -0500 Subject: [PATCH 02/10] Fixing newFile/oldFile documentation. --- lib/convenient_patch.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/convenient_patch.js b/lib/convenient_patch.js index b8f3d86e5..258673547 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; From fc288006a44d61cfe5dd379548f68b116c507fcd Mon Sep 17 00:00:00 2001 From: John Vilk Date: Mon, 8 Feb 2016 11:22:09 -0500 Subject: [PATCH 03/10] Basic DiffFile documentation --- lib/diff_file.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 lib/diff_file.js diff --git a/lib/diff_file.js b/lib/diff_file.js new file mode 100644 index 000000000..34ce315ce --- /dev/null +++ b/lib/diff_file.js @@ -0,0 +1,38 @@ +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; From 3d0c85a4782f0ebd4f09c2e661440f2ce9c399f3 Mon Sep 17 00:00:00 2001 From: John Vilk Date: Mon, 8 Feb 2016 11:26:21 -0500 Subject: [PATCH 04/10] [doc] Ref => Reference --- lib/repository.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/repository.js b/lib/repository.js index 50a165bf5..8a4d3935a 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) { @@ -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 From 944db4534379460ef0d07f542ebfcd3fbb8c43fd Mon Sep 17 00:00:00 2001 From: John Vilk Date: Mon, 8 Feb 2016 11:40:57 -0500 Subject: [PATCH 05/10] [doc] Export the module appropriately. --- lib/diff_file.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/diff_file.js b/lib/diff_file.js index 34ce315ce..541454d3c 100644 --- a/lib/diff_file.js +++ b/lib/diff_file.js @@ -36,3 +36,5 @@ var size = DiffFile.prototype.size; * @return {Number} */ DiffFile.prototype.size = size; + +exports.module = DiffFile; From a1009e3ebd0be4e49100242c3660d54225398f69 Mon Sep 17 00:00:00 2001 From: jv-PintoBobcat Date: Mon, 8 Feb 2016 12:22:13 -0600 Subject: [PATCH 06/10] Updated bad jsdoc for Repository#createBlobFromBuffer --- lib/repository.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/repository.js b/lib/repository.js index 50a165bf5..ffcd2695f 100644 --- a/lib/repository.js +++ b/lib/repository.js @@ -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); From 34bd8598bd224011384e270d0dce771faab868d2 Mon Sep 17 00:00:00 2001 From: John Vilk Date: Mon, 8 Feb 2016 15:10:10 -0500 Subject: [PATCH 07/10] Fixing exports line on three modules & typo in documentation. --- lib/commit.js | 2 +- lib/convenient_hunks.js | 2 +- lib/convenient_patch.js | 4 ++-- lib/diff_file.js | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) 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 258673547..518533554 100644 --- a/lib/convenient_patch.js +++ b/lib/convenient_patch.js @@ -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 index 541454d3c..2c2dc757e 100644 --- a/lib/diff_file.js +++ b/lib/diff_file.js @@ -37,4 +37,4 @@ var size = DiffFile.prototype.size; */ DiffFile.prototype.size = size; -exports.module = DiffFile; +module.exports = DiffFile; From c2f6d811a07cd627d7b6f34fa6f12bc28ca66d29 Mon Sep 17 00:00:00 2001 From: Tyler Wanek Date: Tue, 9 Feb 2016 15:45:03 -0700 Subject: [PATCH 08/10] Optimize rename detection in historywalk --- .../manual/revwalk/file_history_walk.cc | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc index 5bf53e394..53c1202fc 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) { From d23ba8723dc56d1167a67c9bd80c2d05fba4c4b1 Mon Sep 17 00:00:00 2001 From: Tyler Wanek Date: Tue, 9 Feb 2016 16:35:36 -0700 Subject: [PATCH 09/10] Provide old and new name instead of just altname --- .../manual/revwalk/file_history_walk.cc | 21 ++++++++++++++++--- lib/revwalk.js | 4 +++- test/tests/revwalk.js | 6 ++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc index 53c1202fc..0f511969f 100644 --- a/generate/templates/manual/revwalk/file_history_walk.cc +++ b/generate/templates/manual/revwalk/file_history_walk.cc @@ -175,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 >( @@ -195,12 +202,14 @@ void GitRevwalk::FileHistoryWalkWorker::Execute() std::pair > *historyEntry; historyEntry = new std::pair >( nextCommit, - std::pair(strdup(delta->new_file.path), delta->status) + std::pair(strdup(outPair), delta->status) ); baton->out->push_back(historyEntry); flag = true; } + delete[] outPair; + git_patch_free(nextPatch); if (flag) { @@ -255,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("altname").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/revwalk.js b/lib/revwalk.js index d0a5c653b..d754259c6 100644 --- a/lib/revwalk.js +++ b/lib/revwalk.js @@ -129,7 +129,9 @@ 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} altname the other name that is provided when status is + * @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/test/tests/revwalk.js b/test/tests/revwalk.js index b21d59b07..85d708303 100644 --- a/test/tests/revwalk.js +++ b/test/tests/revwalk.js @@ -286,7 +286,8 @@ describe("Revwalk", function() { }) .then(function(results) { assert.equal(results[0].status, NodeGit.Diff.DELTA.RENAMED); - assert.equal(results[0].altname, fileNameA); + assert.equal(results[0].newName, fileNameB); + assert.equal(results[0].oldName, fileNameA); }) .then(function() { var walker = repo.createRevWalk(); @@ -296,7 +297,8 @@ describe("Revwalk", function() { }) .then(function(results) { assert.equal(results[0].status, NodeGit.Diff.DELTA.RENAMED); - assert.equal(results[0].altname, fileNameB); + assert.equal(results[0].newName, fileNameB); + assert.equal(results[0].oldName, fileNameA); }) .then(function() { return fse.remove(repoPath); From 8ab11b55f3210a060d13f96cd93ab817fef718b6 Mon Sep 17 00:00:00 2001 From: Maximiliano Korp Date: Tue, 9 Feb 2016 17:23:01 -0700 Subject: [PATCH 10/10] version bump --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) 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/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",