From d0f834fe60305306e2a920f5e6e9aa219e1058f1 Mon Sep 17 00:00:00 2001 From: John Haley Date: Thu, 20 Nov 2014 11:14:35 -0700 Subject: [PATCH 1/3] Added blank branch.js test file --- test/tests/branch.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/tests/branch.js diff --git a/test/tests/branch.js b/test/tests/branch.js new file mode 100644 index 000000000..e69de29bb From dd5acb9a2cde02e8d1a5428b80e1231877f2f455 Mon Sep 17 00:00:00 2001 From: John Haley Date: Thu, 20 Nov 2014 11:51:01 -0700 Subject: [PATCH 2/3] Renamed getBranch and getMaster to more a more accurate name --- README.md | 6 ++-- example/apps/git_profanity_check.js | 43 ++++++++++++----------------- example/walk-history.js | 6 ++-- example/walk-tree.js | 6 ++-- generate/descriptor.json | 13 +++++++++ lib/repository.js | 8 +++--- test/tests/commit.js | 4 +-- test/tests/revwalk.js | 14 +++++----- 8 files changed, 53 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 941847d24..fed19d049 100644 --- a/README.md +++ b/README.md @@ -134,12 +134,12 @@ var open = require("nodegit").Repository.open; open("tmp") // Open the master branch. .then(function(repo) { - return repo.getMaster(); + return repo.getMasterCommit(); }) // Display information about commits on master. - .then(function(branch) { + .then(function(firstCommitOnMaster) { // Create a new history event emitter. - var history = branch.history(); + var history = firstCommitOnMaster.history(); // Create a counter to only show up to 9 entries. var count = 0; diff --git a/example/apps/git_profanity_check.js b/example/apps/git_profanity_check.js index 7f0674849..ab38eb919 100644 --- a/example/apps/git_profanity_check.js +++ b/example/apps/git_profanity_check.js @@ -35,32 +35,25 @@ else { } // Open repository. -git.Repo.open(path, function(err, repo) { - if (err) { - throw new Error(err); - } - +git.Repo.open(path) +.then(function(repo) { // Open branch, default to master. - repo.getBranch(branch, function(err, branch) { - if (err) { - throw new Error(err); + return repo.getBranchCommit(branch); +}).then(function(firstCommit) { + // Iterate history + var history = firstCommit.history(); + + // Iterate over every commit message and test for words. + history.on('commit', function(commit) { + var message = commit.message(); + + if (reCurse.test(message)) { + console.log('Curse detected in commit', commit.sha()); + console.log('=> ', message); + return; } - - // Iterate history - var history = branch.history(); - - // Iterate over every commit message and test for words. - history.on('commit', function(commit) { - var message = commit.message(); - - if (reCurse.test(message)) { - console.log('Curse detected in commit', commit.sha()); - console.log('=> ', message); - return; - } - }); - - // Start history iteration. - history.start(); }); + + // Start history iteration. + history.start(); }); diff --git a/example/walk-history.js b/example/walk-history.js index 7f6824a8a..f12e6503f 100644 --- a/example/walk-history.js +++ b/example/walk-history.js @@ -6,10 +6,10 @@ var nodegit = require('../'), // that look very similar to calling `git log` from the command line nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { - return repo.getMaster(); -}).then(function(branch){ + return repo.getMasterCommit(); +}).then(function(firstCommitOnMaster){ // History returns an event. - var history = branch.history(sort.Time); + var history = firstCommitOnMaster.history(sort.Time); // History emits 'commit' event for each commit in the branch's history history.on('commit', function(commit) { diff --git a/example/walk-tree.js b/example/walk-tree.js index 3f2454849..9278eb345 100644 --- a/example/walk-tree.js +++ b/example/walk-tree.js @@ -6,9 +6,9 @@ var nodegit = require('../'), // tree (directory), or a file. nodegit.Repository.open(path.resolve(__dirname, '../.git')).then(function(repo) { - return repo.getMaster(); -}).then(function(branch) { - return branch.getTree(); + return repo.getMasterCommit(); +}).then(function(firstCommitOnMaster) { + return firstCommitOnMaster.getTree(); }).then(function(tree) { // `walk()` returns an event. var walker = tree.walk(); diff --git a/generate/descriptor.json b/generate/descriptor.json index 426c6e63c..7149834fd 100644 --- a/generate/descriptor.json +++ b/generate/descriptor.json @@ -87,6 +87,19 @@ "functions": { "git_branch_next": { "ignore": true + }, + "git_branch_create": { + "args": { + "force": { + "isOptional": true + }, + "signature": { + "isOptional": true + }, + "log_message": { + "isOptional": true + } + } } } }, diff --git a/lib/repository.js b/lib/repository.js index 2ee9ee71a..91eaa7ede 100644 --- a/lib/repository.js +++ b/lib/repository.js @@ -24,7 +24,7 @@ Object.defineProperty(Repository.prototype, "openIndex", { * @param {Function} callback * @return {Branch} */ -Repository.prototype.getBranch = function(name, callback) { +Repository.prototype.getBranchCommit = function(name, callback) { var repository = this; return this.getReference("refs/heads/" + name).then(function(reference) { @@ -262,13 +262,13 @@ Repository.prototype.createRevWalk = function() { }; /** - * Retrieve the master branch. + * Retrieve the master branch commit. * * @param {Function} callback * @return {Branch} */ -Repository.prototype.getMaster = function(callback) { - return this.getBranch("master", callback); +Repository.prototype.getMasterCommit = function(callback) { + return this.getBranchCommit("master", callback); }; /** diff --git a/test/tests/commit.js b/test/tests/commit.js index d76e38dde..61b847cd8 100644 --- a/test/tests/commit.js +++ b/test/tests/commit.js @@ -177,8 +177,8 @@ describe("Commit", function() { it("can fetch the master branch HEAD", function() { var repository = this.repository; - return repository.getBranch("master").then(function(branch) { - return repository.getCommit(branch.sha()); + return repository.getBranchCommit("master").then(function(commit) { + return repository.getCommit(commit.sha()); }); }); diff --git a/test/tests/revwalk.js b/test/tests/revwalk.js index a8aea1b20..21e10a172 100644 --- a/test/tests/revwalk.js +++ b/test/tests/revwalk.js @@ -12,8 +12,8 @@ describe("Revwalk", function() { var test = this; return Repository.open(reposPath).then(function(repository) { test.repository = repository; - return test.repository.getBranch("rev-walk").then(function(branch) { - test.branch = branch; + return test.repository.getBranchCommit("rev-walk").then(function(commit) { + test.commit = commit; done(); }); }); @@ -21,7 +21,7 @@ describe("Revwalk", function() { beforeEach(function() { this.walker = this.repository.createRevWalk(); - this.walker.push(this.branch.id()); + this.walker.push(this.commit.id()); }); it("can create a walker", function() { @@ -29,7 +29,7 @@ describe("Revwalk", function() { }); it("can push an object", function() { - var sha = this.branch.sha(); + var sha = this.commit.sha(); return this.walker.next().then(function(commit) { assert.equal(sha, commit); @@ -49,7 +49,7 @@ describe("Revwalk", function() { assert.equal(commit.toString(), "b8a94aefb22d0534cc0e5acf533989c13d8725dc"); test.walker = test.repository.createRevWalk(); - test.walker.push(test.branch.id()); + test.walker.push(test.commit.id()); test.walker.hide( Oid.fromString("b8a94aefb22d0534cc0e5acf533989c13d8725dc")); @@ -89,9 +89,9 @@ describe("Revwalk", function() { this.timeout(10000); return Repository.open(reposPath).then(function(repository) { var walker = repository.createRevWalk(); - return repository.getMaster().then(function(master) { + return repository.getMasterCommit().then(function(firstCommitOnMaster) { var did = false; - walker.walk(master, function(error, commit) { + walker.walk(firstCommitOnMaster, function(error, commit) { for (var i = 0; i < 1000; i++) { if (true) { commit.author().name(); From e1caaa5a543fbbe0d471386223d0058187f25afe Mon Sep 17 00:00:00 2001 From: John Haley Date: Thu, 20 Nov 2014 14:43:15 -0700 Subject: [PATCH 3/3] Added tests for branch create delete isHead --- generate/descriptor.json | 17 +++++++++-- lib/branch.js | 5 ++++ lib/refs.js | 9 ++++++ lib/repository.js | 63 +++++++++++++++++++++++++++++++++++++--- test/tests/branch.js | 63 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 150 insertions(+), 7 deletions(-) create mode 100644 lib/branch.js diff --git a/generate/descriptor.json b/generate/descriptor.json index 7149834fd..eb55e625d 100644 --- a/generate/descriptor.json +++ b/generate/descriptor.json @@ -85,9 +85,6 @@ }, "branch": { "functions": { - "git_branch_next": { - "ignore": true - }, "git_branch_create": { "args": { "force": { @@ -100,6 +97,20 @@ "isOptional": true } } + }, + "git_branch_next": { + "ignore": true + }, + "git_branch_set_upstream": { + "isAsync": false, + "args": { + "upstream_name": { + "isOptional": true + } + } + }, + "git_branch_upstream": { + "isAsync": false } } }, diff --git a/lib/branch.js b/lib/branch.js new file mode 100644 index 000000000..a437f1de6 --- /dev/null +++ b/lib/branch.js @@ -0,0 +1,5 @@ +var NodeGit = require("../"); + +var Branch = NodeGit.Branch; + +module.exports = Branch; diff --git a/lib/refs.js b/lib/refs.js index ee7d60c41..c6775d58d 100644 --- a/lib/refs.js +++ b/lib/refs.js @@ -1,6 +1,7 @@ var NodeGit = require("../"); var Reference = NodeGit.Refs; +var Branch = NodeGit.Branch; Reference.Type = { Oid: 1, @@ -32,4 +33,12 @@ Reference.prototype.toString = function() { return this.name(); }; +/** + * Returns if the ref is pointed at by HEAD + * @return {bool} + */ +Reference.prototype.isHead = function() { + return Branch.isHead(this); +}; + module.exports = Reference; diff --git a/lib/repository.js b/lib/repository.js index 91eaa7ede..bd6a9c0bf 100644 --- a/lib/repository.js +++ b/lib/repository.js @@ -18,16 +18,71 @@ Object.defineProperty(Repository.prototype, "openIndex", { }); /** - * Look up a branch"s most recent commit. + * Creates a branch with the passed in name pointing to the commit + * + * @param {String} name Branch name, e.g. "master" + * @param {Commit|String|Oid} commit The commit the branch will point to + * @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} + */ +Repository.prototype.createBranch = +function(name, commit, force, signature, logMessage) { + var repo = this; + + if (commit instanceof Commit) { + return NodeGit.Branch.create( + repo, + name, + commit, + force ? 1 : 0, + signature, + logMessage); + } + else { + return repo.getCommit(commit).then(function(commit) { + return NodeGit.Branch.create( + repo, + name, + commit, + force ? 1 : 0, + signature, + logMessage); + }); + } +}; + +/** + * Look up a branch + * + * @param {String} name Branch name, e.g. "master" + * @param {Function} callback + * @return {Ref} + */ +Repository.prototype.getBranch = function(name, callback) { + name = ~name.indexOf("refs/heads/") ? name : "refs/heads/" + name; + + return this.getReference(name).then(function(reference) { + if (typeof callback === "function") { + callback(null, reference); + } + + return reference; + }, callback); +}; + +/** + * Look up a branch's most recent commit. * * @param {String} name Branch name, e.g. "master" * @param {Function} callback - * @return {Branch} + * @return {Commit} */ Repository.prototype.getBranchCommit = function(name, callback) { var repository = this; - return this.getReference("refs/heads/" + name).then(function(reference) { + return this.getBranch(name).then(function(reference) { return repository.getCommit(reference.target()).then(function(commit) { if (typeof callback === "function") { callback(null, commit); @@ -265,7 +320,7 @@ Repository.prototype.createRevWalk = function() { * Retrieve the master branch commit. * * @param {Function} callback - * @return {Branch} + * @return {Commit} */ Repository.prototype.getMasterCommit = function(callback) { return this.getBranchCommit("master", callback); diff --git a/test/tests/branch.js b/test/tests/branch.js index e69de29bb..6b717e476 100644 --- a/test/tests/branch.js +++ b/test/tests/branch.js @@ -0,0 +1,63 @@ +var assert = require("assert"); +var path = require("path"); + +describe("Branch", function() { + var reposPath = path.resolve("test/repos/workdir/.git"); + + var Repository = require("../../lib/repository"); + var Branch = require("../../lib/branch"); + var branchName = "test-branch"; + var fullBranchName = "refs/heads/" + branchName; + + before(function() { + var test = this; + + return Repository.open(reposPath).then(function(repository) { + test.repo = repository; + }); + }); + + beforeEach(function() { + var test = this; + var repo = test.repo; + + return repo.getMasterCommit().then(function(masterCommit) { + test.masterCommit = masterCommit; + + return repo.createBranch(branchName, masterCommit, true) + .then(function(branch) { + test.branch = branch; + }); + }); + }); + + it("can create a branch", function() { + var branch = this.branch; + var masterCommit = this.masterCommit; + + assert.equal(branch.name(), fullBranchName); + assert.equal(branch.target().toString(), masterCommit.sha()); + }); + + it("can delete a branch", function() { + var repo = this.repo; + + Branch.delete(this.branch); + + return repo.getBranch(branchName).then(function() { + // branch wasn't deleted + assert.ok(false); + }, function() { + // branch was deleted! + assert.ok(true); + }); + }); + + it("can see if the branch is pointed to by head", function() { + var repo = this.repo; + + return repo.getBranch("master").then(function(branch) { + assert.ok(branch.isHead()); + }); + }); +});