diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b375355..647bcb660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Change Log +## [0.9.0](https://github.com/nodegit/nodegit/releases/tag/v0.9.0) (2016-01-21) + +[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.8.0...0.9.0) + +- Thread safe fix to stop crashing on releasing mutexes [PR #876](https://github.com/nodegit/nodegit/pull/876) +- `Submodule#setIgnore`, `Submodule#setUpdate`, and `Submodule#setUrl` are now all async. `Submodule#status` and `Submodule#location` are now available [PR #867](https://github.com/nodegit/nodegit/pull/867) and [PR #870](https://github.com/nodegit/nodegit/pull/870) +- `Remote#defaultBranch` is now available [PR #872](https://github.com/nodegit/nodegit/pull/872) +- `Repository#mergeBranches` now takes in a `MergeOptions` parameter [PR #873](https://github.com/nodegit/nodegit/pull/873) +- Remove a NodeGit specific hack to make `Index#addAll` faster since that is fixed in libgit2 [PR #875](https://github.com/nodegit/nodegit/pull/875) + ## [0.8.0](https://github.com/nodegit/nodegit/releases/tag/v0.8.0) (2016-01-15) [Full Changelog](https://github.com/nodegit/nodegit/compare/v0.7.0...0.8.0) @@ -7,7 +17,7 @@ - Thread safe locking has been added and currently is defaulted to off. Use `NodeGit.enableThreadSafety()` to turn on - NodeGit no longer requires a specific Promise object from the `nodegit-promise` library to be passed in. You can now use whatever you want! - `Repository#stageFilemode` now can accept an array of strings for files to update -- `Submodule#addToIndex`, `Submodule#addFinalize`, `Submodule#init`, `Submodule#open`, `Submodule#sync`, and `Submodule#update` are now all async methods +- `Submodule#addToIndex`, `Submodule#addFinalize`, `Submodule#init`, `Submodule#open`, `Submodule#sync`, and `Submodule#update` are now all async methodss ## [0.7.0](https://github.com/nodegit/nodegit/releases/tag/v0.7.0) (2016-01-08) diff --git a/README.md b/README.md index 8366dee1d..83c6dcb4d 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ NodeGit -**Stable: 0.8.0** +**Stable: 0.9.0** ## Have a problem? Come chat with us! ## @@ -39,12 +39,12 @@ NodeGit ## Maintained by ## Tim Branyen [@tbranyen](http://twitter.com/tbranyen), -John Haley [@johnhaley81](http://twitter.com/johnhaley81), -Max Korp [@maxkorp](http://twitter.com/MaximilianoKorp), and -Steve Smith [@orderedlist](https://twitter.com/orderedlist) with help from tons of +John Haley [@johnhaley81](http://twitter.com/johnhaley81), and +Max Korp [@maxkorp](http://twitter.com/MaximilianoKorp) with help from tons of [awesome contributors](https://github.com/nodegit/nodegit/contributors)! ### Alumni Maintainers ### +Steve Smith [@orderedlist](https://twitter.com/orderedlist), Michael Robinson [@codeofinterest](http://twitter.com/codeofinterest), and Nick Kallen [@nk](http://twitter.com/nk) @@ -61,20 +61,42 @@ dependencies. npm install nodegit ``` -**Note: NodeGit will only work on io.js Windows with [the iojs binary instead of node](https://github.com/rvagg/pangyp/issues/4).** +If you receive errors about libstdc++, which are commonly experienced when +building on Travis-CI, you can fix this by upgrading to the latest +libstdc++-4.9. -If you encounter problems while installing, you should try the [Building from -source](http://www.nodegit.org/guides/install/from-source/) instructions. +In Ubuntu: + +``` sh +sudo add-apt-repository ppa:ubuntu-toolchain-r/test +sudo apt-get update +sudo apt-get install libstdc++-4.9-dev +``` + +In Travis: + +``` yaml +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libstdc++-4.9-dev +``` + +If you are still encountering problems while installing, you should try the +[Building from source](http://www.nodegit.org/guides/install/from-source/) +instructions. ## API examples. ## ### Cloning a repository and reading a file: ### ``` javascript -var clone = require("nodegit").Clone.clone; +var Git = require("nodegit"); -// Clone a given repository into a specific folder. -clone("https://github.com/nodegit/nodegit", "tmp", null) +// Clone a given repository into the `./tmp` folder. +Git.Clone("https://github.com/nodegit/nodegit", "./tmp") // Look up this known commit. .then(function(repo) { // Use a known commit sha from this repository. @@ -110,10 +132,10 @@ clone("https://github.com/nodegit/nodegit", "tmp", null) ### Emulating git log: ### ``` javascript -var open = require("nodegit").Repository.open; +var Git = require("nodegit"); // Open the repository directory. -open("tmp") +Git.Repository.open("tmp") // Open the master branch. .then(function(repo) { return repo.getMasterCommit(); @@ -163,41 +185,3 @@ You will need to build locally before running the tests. See above. ``` bash npm test ``` - -## Migrating from old versions. ## - -The bump from 0.1.4 to 0.2.0 was a big one. Many things changed, see here: -https://github.com/nodegit/nodegit/compare/v0.1.4...v0.2.0 - -This update is wholly and entirely a breaking one, and older versions won't be -maintained. For the purpose of migration, perhaps the biggest point to make -is that async methods can now use promises, rather than just taking callbacks. -Additionally, lots of method and property names have changed. - -## nw.js (Node-Webkit) ## - -### Native compilation for nw.js ### -A common issue is with NodeGit not functioning properly inside of -[nw.js](http://github.com/nwjs/nw.js) applications. Because NodeGit -is a native module, it has to be rebuilt for node-webkit using -[nw-gyp](http://github.com/rogerwang/nw-gyp). By default, NodeGit will look -in the root package's package.json for an `engines` property, and within look -for a `nw.js` property (or a `node-webkit` if the prior isn't found) that holds -a specific version of nw.js. The value of this property is what will get passed -as the `--target` argument to `nw-gyp configure`. - -### Version incompatibility ### -Prior to version 0.2.6, NodeGit used [nan](http://github.com/rvagg/nan) v1.4.3. -As of 0.2.6, NodeGit uses nan v1.5.1 to provide support for io.js. Unfortunately, -this breaks some nw.js compatibility. With nw.js 0.12+, the name was changed to -nw.js from node-webkit. The alpha currently still breaks with NodeGit due to the -nan update, but should be fixed in the final v0.12.0 release. Ã…pplications using -previous versions of node webkit have 2 options: -1) Use an older version (v0.2.4 or earlier) of NodeGit -2) Use [npm shrinkwrap](https://docs.npmjs.com/cli/shrinkwrap) to force NodeGit to -use nan v1.4.3. Since the binary always recompiles when being used with nw.js, you -shouldn't have to do anything else to make sure it works. As of NodeGit v0.2.6, -the change to nan v1.4.3 doesn't cause any problems. - -Currently, support for nw.js is limited, although we intend to support it better -in the future. diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json index d9658df84..a64a9b4e9 100644 --- a/generate/input/descriptor.json +++ b/generate/input/descriptor.json @@ -1602,7 +1602,18 @@ } }, "git_remote_default_branch": { - "ignore": true + "isAsync": true, + "args": { + "out": { + "isReturn": true + }, + "remote": { + "isSelf": true + } + }, + "return": { + "isErrorCode": true + } }, "git_remote_delete": { "isAsync": true, @@ -2000,7 +2011,19 @@ } }, "git_submodule_location": { - "ignore": true + "isAsync": true, + "args": { + "location_status": { + "shouldAlloc": true, + "isReturn": true + }, + "submodule": { + "isSelf": true + } + }, + "return": { + "isErrorCode": true + } }, "git_submodule_open": { "isAsync": true, @@ -2027,8 +2050,35 @@ "isErrorCode": true } }, + "git_submodule_set_ignore": { + "isAsync": true, + "return": { + "isErrorCode": true + } + }, + "git_submodule_set_update": { + "isAsync": true, + "return": { + "isErrorCode": true + } + }, + "git_submodule_set_url": { + "isAsync": true, + "return": { + "isErrorCode": true + } + }, "git_submodule_status": { - "ignore": true + "isAsync": true, + "args": { + "status": { + "isReturn": true, + "shouldAlloc": true + } + }, + "return": { + "isErrorCode": true + } }, "git_submodule_sync": { "isAsync": true, diff --git a/generate/templates/manual/src/lock_master.cc b/generate/templates/manual/src/lock_master.cc index f59145b33..d7d8239f5 100644 --- a/generate/templates/manual/src/lock_master.cc +++ b/generate/templates/manual/src/lock_master.cc @@ -188,9 +188,13 @@ void LockMasterImpl::Lock(bool acquireMutexes) { } void LockMasterImpl::Unlock(bool releaseMutexes) { - std::vector objectMutexes = GetMutexes(releaseMutexes * -1); + // Get the mutexes but don't decrement their use count until after we've + // unlocked them all. + std::vector objectMutexes = GetMutexes(0); std::for_each(objectMutexes.begin(), objectMutexes.end(), uv_mutex_unlock); + + GetMutexes(releaseMutexes * -1); } void LockMasterImpl::CleanupMutexes() { diff --git a/lib/index.js b/lib/index.js index a7f41571e..be905be60 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,8 +1,6 @@ var NodeGit = require("../"); var Index = NodeGit.Index; -var Status = NodeGit.Status; -var Pathspec = NodeGit.Pathspec; /** * Return an array of the entries in this index. @@ -21,28 +19,7 @@ Index.prototype.entries = function() { var addAll = Index.prototype.addAll; Index.prototype.addAll = function(pathspec, flags, matchedCallback) { - // This status path code is here to speedup addall, which currently is - // excessively slow due to adding every single unignored file to the index - // even if it has no changes. Remove this when it's fixed in libgit2 - // https://github.com/libgit2/libgit2/issues/2687 - var paths = []; - var repo = this.owner(); - var statusCB = function(path) { - paths.push(path); - }; - var idx = this; - var ps = Pathspec.create(pathspec || "*"); - - return Status.foreach(repo, statusCB) - .then(function() { - return paths; - }) - .then(function(paths) { - paths = paths.filter(function(path) { - return !!(ps.matchesPath(0, path)); - }); - return addAll.call(idx, paths, flags, matchedCallback, null); - }); + return addAll.call(this, pathspec || "*", flags, matchedCallback, null); }; var removeAll = Index.prototype.removeAll; diff --git a/lib/repository.js b/lib/repository.js index 8234ce083..31390f0ed 100644 --- a/lib/repository.js +++ b/lib/repository.js @@ -725,7 +725,6 @@ Repository.prototype.fetchAll = function( }); }; - /** * Merge a branch onto another branch * @@ -733,15 +732,18 @@ Repository.prototype.fetchAll = function( * @param {String|Ref} from * @param {Signature} signature * @param {Merge.PREFERENCE} mergePreference + * @param {MergeOptions} mergeOptions * @return {Oid|Index} A commit id for a succesful merge or an index for a * merge with conflicts */ Repository.prototype.mergeBranches = - function(to, from, signature, mergePreference) { + function(to, from, signature, mergePreference, mergeOptions) { var repo = this; var fromBranch; var toBranch; + mergePreference = mergePreference || NodeGit.Merge.PREFERENCE.NONE; + mergeOptions = normalizeOptions(mergeOptions, NodeGit.MergeOptions); signature = signature || repo.defaultSignature(); @@ -806,7 +808,12 @@ Repository.prototype.mergeBranches = }) .then(function(headRef) { updateHead = !!headRef && (headRef.name() === toBranch.name()); - return NodeGit.Merge.commits(repo, toCommitOid, fromCommitOid); + return NodeGit.Merge.commits( + repo, + toCommitOid, + fromCommitOid, + mergeOptions + ); }) .then(function(index) { // if we have conflicts then throw the index @@ -834,8 +841,8 @@ Repository.prototype.mergeBranches = [toCommitOid, fromCommitOid]); }) .then(function(commit) { - // // we've updated the checked out branch, so make sure we update - // // head so that our index isn't messed up + // we've updated the checked out branch, so make sure we update + // head so that our index isn't messed up if (updateHead) { return repo.getBranch(to) .then(function(branch) { diff --git a/package.json b/package.json index 13daa9d4d..bb94ca07d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "nodegit", "description": "Node.js libgit2 asynchronous native bindings", - "version": "0.8.0", + "version": "0.9.0", "homepage": "http://nodegit.org", "keywords": [ "libgit2", diff --git a/test/tests/remote.js b/test/tests/remote.js index 82bb91b33..747bf2eba 100644 --- a/test/tests/remote.js +++ b/test/tests/remote.js @@ -150,6 +150,22 @@ describe("Remote", function() { }); }); + it("can get the default branch of a remote", function() { + var remoteCallbacks = { + certificateCheck: function() { + return 1; + } + }; + + var remote = this.remote; + + return remote.connect(NodeGit.Enums.DIRECTION.FETCH, remoteCallbacks) + .then(function() { return remote.defaultBranch(); }) + .then(function(branchName) { + assert.equal("refs/heads/master", branchName); + }); + }); + it("can fetch from a remote", function() { return this.repository.fetch("origin", { callbacks: { diff --git a/test/tests/submodule.js b/test/tests/submodule.js index 6b920c811..002b4ef12 100644 --- a/test/tests/submodule.js +++ b/test/tests/submodule.js @@ -16,18 +16,18 @@ describe("Submodule", function() { return RepoUtils.createRepository(repoPath) .then(function(repo) { test.repository = repo; + return Repository.open(local("../repos/workdir")); + }) + .then(function(repo) { + test.workdirRepository = repo; }); }); it("can walk over the submodules", function() { - var repo; + var repo = this.workdirRepository; var submoduleName = "vendor/libgit2"; - return Repository.open(local("../repos/workdir")) - .then(function(_repo) { - repo = _repo; - return repo.getSubmoduleNames(); - }) + return repo.getSubmoduleNames() .then(function(submodules) { assert.equal(submodules.length, 1); @@ -43,6 +43,69 @@ describe("Submodule", function() { }); }); + it("can get submodule status", function() { + var repo = this.workdirRepository; + var submoduleName = "vendor/libgit2"; + + return Submodule.status(repo, submoduleName, Submodule.IGNORE.NONE) + .then(function(status) { + assert.equal(Submodule.STATUS.IN_CONFIG, status); + }); + }); + + it("can get submodule location", function() { + var repo = this.workdirRepository; + var submoduleName = "vendor/libgit2"; + + return Submodule.lookup(repo, submoduleName) + .then(function(submodule) { + return submodule.location(); + }) + .then(function(status) { + assert.equal(Submodule.STATUS.IN_CONFIG, status); + }); + }); + + it("can set submodule ignore", function() { + var repo = this.workdirRepository; + var submoduleName = "vendor/libgit2"; + + return Submodule.setIgnore(repo, submoduleName, Submodule.IGNORE.ALL) + .then(function() { + return Submodule.lookup(repo, submoduleName); + }) + .then(function(submodule) { + assert.equal(Submodule.IGNORE.ALL, submodule.ignore()); + }); + }); + + it("can set submodule url", function() { + var repo = this.workdirRepository; + var submoduleName = "vendor/libgit2"; + var submoduleUrl = "https://github.com/githubtraining/hellogitworld.git"; + + return Submodule.setUrl(repo, submoduleName, submoduleUrl) + .then(function() { + return Submodule.lookup(repo, submoduleName); + }) + .then(function(submodule) { + assert.equal(submoduleUrl, submodule.url()); + }); + }); + + it("can set submodule update", function() { + var repo = this.workdirRepository; + var submoduleName = "vendor/libgit2"; + + return Submodule.setUpdate(repo, submoduleName, Submodule.UPDATE.NONE) + .then(function() { + return Submodule.lookup(repo, submoduleName); + }) + .then(function(submodule) { + assert.equal(Submodule.UPDATE.NONE, submodule.updateStrategy()); + }); + }); + it("can setup and finalize submodule add", function() { var repo = this.repository; var submodulePath = "hellogitworld";