diff --git a/CHANGELOG.md b/CHANGELOG.md
index c00feb8a7..b3d69a4b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,25 @@
# Change Log
-# v0.13.0 [(2016-05-04)](https://github.com/nodegit/nodegit/releases/tag/v0.13.0)
+## v0.13.1 [(2016-06-03)](https://github.com/nodegit/nodegit/releases/tag/v0.13.1)
+
+[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.13.0...v0.13.1)
+
+## Added
+
+- `Repository#discardLines` is now a thing [PR #1021](https://github.com/nodegit/nodegit/pull/1021)
+
+## Modified
+
+- Async methods now use a custom threadpool to prevent thread-locking the event loop [PR #1019](https://github.com/nodegit/nodegit/pull/1019)
+
+## Bug fixes
+
+- Fix building NodeGit from NPM [PR #1026](https://github.com/nodegit/nodegit/pull/1026)
+- Plug a memory leak in `RevWalk.fastWalk` [PR #1030](https://github.com/nodegit/nodegit/pull/1030)
+- Plug a memory leak with `Oid` [PR #1033](https://github.com/nodegit/nodegit/pull/1033)
+- Fixed some underlying libgit2 objects getting freed incorrectly [PR #1036](https://github.com/nodegit/nodegit/pull/1036)
+
+## v0.13.0 [(2016-05-04)](https://github.com/nodegit/nodegit/releases/tag/v0.13.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.12.2...v0.13.0)
@@ -17,7 +36,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
### Modified
-- `Index#add`, `Index#addByPath`, `Index#clear`, `Index#conflictAdd`, `Index#conflictCleanup`, `Index#conflictGet`, `Index#conflictRemove`, `Index.open`, `Index#read`, `Index#readTree`, `Index#remove`, `Index#removeByPath`, `Index#removeDirectory`, `Index#read`, `Index#writeTree`, and `Index#writeTreeTo` are all now asynchronous functions [PR #971](https://github.com/nodegit/nodegit/pull/971)
+- `Index#add`, `Index#addByPath`, `Index#clear`, `Index#conflictAdd`, `Index#conflictCleanup`, `Index#conflictGet`, `Index#conflictRemove`, `Index.open`, `Index#read`, `Index#readTree`, `Index#remove`, `Index#removeByPath`, `Index#removeDirectory`, `Index#read`, `Index#write`, `Index#writeTree`, and `Index#writeTreeTo` are all now asynchronous functions [PR #971](https://github.com/nodegit/nodegit/pull/971)
- Made `ancestoryEntry`, `outEntry` and `theirEntry` optional parameters on `Index#conflictAdd` [PR #997](https://github.com/nodegit/nodegit/pull/997)
- `Repository#refreshIndex` will return an Index object back that has the latest data loaded off of disk [PR #986](https://github.com/nodegit/nodegit/pull/986)
- `Commit.create` is now asynchronous [PR #1022](https://github.com/nodegit/nodegit/pull/1022)
@@ -102,7 +121,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
the existing callback `notify_cb` was updated to reflect that it only
gets called when new deltas are added to the diff.
-- `FetchOptions` and `PushOptions` have gained a `custom_headers`
+- `FetchOptions` and `PushOptions` have gained a `customHeaders`
field to set the extra HTTP header fields to send.
- `Commit#headerField` allows you to look up a specific header
@@ -150,7 +169,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
Additionally, the `TreeEntry` fields have been removed in lieu of the corresponding functions to return
the data.
-# v0.12.2 [(2016-04-07)](https://github.com/nodegit/nodegit/releases/tag/v0.12.2)
+## v0.12.2 [(2016-04-07)](https://github.com/nodegit/nodegit/releases/tag/v0.12.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.12.1...v0.12.2)
@@ -162,7 +181,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Added memory clean up for references [PR #977](https://github.com/nodegit/nodegit/pull/977) and remotes [PR #981](https://github.com/nodegit/nodegit/pull/981)
-# v0.12.1 [(2016-03-30)](https://github.com/nodegit/nodegit/releases/tag/v0.12.1)
+## v0.12.1 [(2016-03-30)](https://github.com/nodegit/nodegit/releases/tag/v0.12.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.12.0...v0.12.1)
@@ -170,7 +189,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed post install script dying on windows [PR #978](https://github.com/nodegit/nodegit/pull/978)
-# v0.12.0 [(2016-03-28)](https://github.com/nodegit/nodegit/releases/tag/v0.12.0)
+## v0.12.0 [(2016-03-28)](https://github.com/nodegit/nodegit/releases/tag/v0.12.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.9...v0.12.0)
@@ -187,19 +206,19 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed install when there is a space in the username on windows [PR #951](https://github.com/nodegit/nodegit/pull/951)
- Bump to nan@2.2.0 [PR #952](https://github.com/nodegit/nodegit/pull/952)
-# v0.11.9 [(2016-03-09)](https://github.com/nodegit/nodegit/releases/tag/v0.11.9)
+## v0.11.9 [(2016-03-09)](https://github.com/nodegit/nodegit/releases/tag/v0.11.9)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.8...v0.11.9)
- Fixed crash when calculating diff via `ConvenientPatch` [PR #945](https://github.com/nodegit/nodegit/pull/945)
-# v0.11.8 [(2016-03-07)](https://github.com/nodegit/nodegit/releases/tag/v0.11.8)
+## v0.11.8 [(2016-03-07)](https://github.com/nodegit/nodegit/releases/tag/v0.11.8)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.7...v0.11.8)
- Removed callback throttling due to segmentation faults. Will be implemented later. [PR #943](https://github.com/nodegit/nodegit/pull/943)
-# v0.11.7 [(2016-03-07)](https://github.com/nodegit/nodegit/releases/tag/v0.11.7)
+## v0.11.7 [(2016-03-07)](https://github.com/nodegit/nodegit/releases/tag/v0.11.7)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.6...v0.11.7)
@@ -209,7 +228,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed unicode in `Diff.blobToBuffer` getting corrupted [PR #935](https://github.com/nodegit/nodegit/pull/935)
- Fixed fetching/pulling to bitbucket in versions > v5.6 of node [PR #942](https://github.com/nodegit/nodegit/pull/942)
-# v0.11.6 [(2016-03-01)](https://github.com/nodegit/nodegit/releases/tag/v0.11.6)
+## v0.11.6 [(2016-03-01)](https://github.com/nodegit/nodegit/releases/tag/v0.11.6)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.5...v0.11.6)
@@ -220,27 +239,27 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed http parsing errors in Node 5.6 [PR #931](https://github.com/nodegit/nodegit/pull/931)
- Fixed `Tree#walk` not returning the correct entries on `end` [PR #929](https://github.com/nodegit/nodegit/pull/929)
-# v0.11.5 [(2016-02-25)](https://github.com/nodegit/nodegit/releases/tag/v0.11.5)
+## v0.11.5 [(2016-02-25)](https://github.com/nodegit/nodegit/releases/tag/v0.11.5)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.4...v0.11.5)
- Fixed crash when calculating a diff [PR #922](https://github.com/nodegit/nodegit/pull/922)
- Fixed an issue with return values getting randomly corrupted [PR #923](https://github.com/nodegit/nodegit/pull/923))
-# v0.11.4 [(2016-02-24)](https://github.com/nodegit/nodegit/releases/tag/v0.11.4)
+## v0.11.4 [(2016-02-24)](https://github.com/nodegit/nodegit/releases/tag/v0.11.4)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.3...v0.11.4)
- Fixed callback out values in callbacks from C++. This affects any NodeGit call that is passed a callback as an option [PR #921](https://github.com/nodegit/nodegit/pull/921)
- Fixed an issue with building the debug version of NodeGit on windows [PR #918](https://github.com/nodegit/nodegit/pull/918)
-# v0.11.3 [(2016-02-22)](https://github.com/nodegit/nodegit/releases/tag/v0.11.3)
+## v0.11.3 [(2016-02-22)](https://github.com/nodegit/nodegit/releases/tag/v0.11.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.2...v0.11.3)
- Fixed an issue where initializing NodeGit would sometimes seg fault. Also fixed an error when fetching concurrently [PR #912](https://github.com/nodegit/nodegit/pull/912)
-# v0.11.2 [(2016-02-18)](https://github.com/nodegit/nodegit/releases/tag/v0.11.2)
+## v0.11.2 [(2016-02-18)](https://github.com/nodegit/nodegit/releases/tag/v0.11.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.1...v0.11.2)
@@ -249,21 +268,21 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed seg-fault in linux that happens when getting the diff of very small files [PR #908](https://github.com/nodegit/nodegit/pull/908)
- Fixed `RevWalk#fastWalk` dying when an error happens in libgit2 [PR #909](https://github.com/nodegit/nodegit/pull/909)
-# v0.11.1 [(2016-02-09)](https://github.com/nodegit/nodegit/releases/tag/v0.11.1)
+## v0.11.1 [(2016-02-09)](https://github.com/nodegit/nodegit/releases/tag/v0.11.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.11.0...v0.11.1)
- Numerous fixes and perf boosts to file history [PR #900](https://github.com/nodegit/nodegit/pull/900)[PR #896](https://github.com/nodegit/nodegit/pull/896)
- Several doc fixes [PR #899](https://github.com/nodegit/nodegit/pull/899)[PR #897](https://github.com/nodegit/nodegit/pull/897)
-# v0.11.0 [(2016-02-04)](https://github.com/nodegit/nodegit/releases/tag/v0.11.0)
+## v0.11.0 [(2016-02-04)](https://github.com/nodegit/nodegit/releases/tag/v0.11.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.10.0...v0.11.0)
- Change `Revert.commit` and `Revert.revert` to by async. [PR #887](https://github.com/nodegit/nodegit/pull/887)
- Added `RevWalk#fileHistoryWalk` for a faster way to retrieve history for a specific file. [PR #889](https://github.com/nodegit/nodegit/pull/889)
-# v0.10.0 [(2016-02-01)](https://github.com/nodegit/nodegit/releases/tag/v0.10.0)
+## v0.10.0 [(2016-02-01)](https://github.com/nodegit/nodegit/releases/tag/v0.10.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.9.0...v0.10.0)
@@ -289,7 +308,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- `rawContent()` contains the unformatted content of the line. This is no longer a string from the line to the end of the file.
- `content()` contains the utf8 formatted content of the line.
-# v0.9.0 [(2016-01-21)](https://github.com/nodegit/nodegit/releases/tag/v0.9.0)
+## v0.9.0 [(2016-01-21)](https://github.com/nodegit/nodegit/releases/tag/v0.9.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.8.0...v0.9.0)
@@ -299,7 +318,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- `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))
-# v0.8.0 [(2016-01-15)](https://github.com/nodegit/nodegit/releases/tag/v0.8.0)
+## v0.8.0 [(2016-01-15)](https://github.com/nodegit/nodegit/releases/tag/v0.8.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.7.0...0.8.0)
@@ -308,7 +327,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- `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 methodss
-# v0.7.0 [(2016-01-08)](https://github.com/nodegit/nodegit/releases/tag/v0.7.0)
+## v0.7.0 [(2016-01-08)](https://github.com/nodegit/nodegit/releases/tag/v0.7.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.6.3...0.7.0)
@@ -317,20 +336,20 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Make GraphDescendentOf asynchronous
- Fixed line length of utf8 stringss
-# v0.6.3 [(2015-12-16)](https://github.com/nodegit/nodegit/releases/tag/v0.6.3)
+## v0.6.3 [(2015-12-16)](https://github.com/nodegit/nodegit/releases/tag/v0.6.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.6.2...0.6.3)
- Fixed a bug where manually building for vanilla node would fail without explicitly
setting the target
-# v0.6.2 [(2015-12-16)](https://github.com/nodegit/nodegit/releases/tag/v0.6.2)
+## v0.6.2 [(2015-12-16)](https://github.com/nodegit/nodegit/releases/tag/v0.6.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.6.1...0.6.2)
- Fixed a bug where manually building on windows would fail (if unable to download a prebuilt binary)
-# v0.6.1 [(2015-12-14)](https://github.com/nodegit/nodegit/releases/tag/v0.6.1)
+## v0.6.1 [(2015-12-14)](https://github.com/nodegit/nodegit/releases/tag/v0.6.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.6.0...0.6.1)
@@ -338,7 +357,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Added Repository.getSubmoduleNames
- Added Submodule.Foreach
-# v0.6.0 [(2015-12-08)](https://github.com/nodegit/nodegit/releases/tag/v0.6.0)
+## v0.6.0 [(2015-12-08)](https://github.com/nodegit/nodegit/releases/tag/v0.6.0)
- Added file mode staging
- Added a fast rev walk to do the rev walk in C++ and bubble the result up to JS
@@ -349,7 +368,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed weirdness in lifecycle scripts
- Added downloading prebuilt binaries for electron
-# v0.4.1 [(2015-06-02)](https://github.com/nodegit/nodegit/tree/0.4.1)
+## v0.4.1 [(2015-06-02)](https://github.com/nodegit/nodegit/tree/0.4.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.4.0...0.4.1)
@@ -413,7 +432,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- stop cleaning on post-install [\#562](https://github.com/nodegit/nodegit/pull/562) ([maxkorp](https://github.com/maxkorp))
-# v0.4.0 [(2015-05-07)](https://github.com/nodegit/nodegit/tree/v0.4.0)
+## v0.4.0 [(2015-05-07)](https://github.com/nodegit/nodegit/tree/v0.4.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.3.3...v0.4.0)
@@ -541,7 +560,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Add automatically generated change log file. [\#465](https://github.com/nodegit/nodegit/pull/465) ([skywinder](https://github.com/skywinder))
-# v0.3.3 [(2015-03-16)](https://github.com/nodegit/nodegit/tree/v0.3.3)
+## v0.3.3 [(2015-03-16)](https://github.com/nodegit/nodegit/tree/v0.3.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.3.2...v0.3.3)
@@ -549,7 +568,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Download all dev dependencies before build [\#491](https://github.com/nodegit/nodegit/pull/491) ([johnhaley81](https://github.com/johnhaley81))
-# v0.3.2 [(2015-03-16)](https://github.com/nodegit/nodegit/tree/v0.3.2)
+## v0.3.2 [(2015-03-16)](https://github.com/nodegit/nodegit/tree/v0.3.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.3.1...v0.3.2)
@@ -561,7 +580,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Confirm builder exists before building [\#490](https://github.com/nodegit/nodegit/pull/490) ([johnhaley81](https://github.com/johnhaley81))
-# v0.3.1 [(2015-03-14)](https://github.com/nodegit/nodegit/tree/v0.3.1)
+## v0.3.1 [(2015-03-14)](https://github.com/nodegit/nodegit/tree/v0.3.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.3.0...v0.3.1)
@@ -569,7 +588,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Revert node-pre-gyp to install not build [\#486](https://github.com/nodegit/nodegit/pull/486) ([tbranyen](https://github.com/tbranyen))
-# v0.3.0 [(2015-03-13)](https://github.com/nodegit/nodegit/tree/v0.3.0)
+## v0.3.0 [(2015-03-13)](https://github.com/nodegit/nodegit/tree/v0.3.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.7...v0.3.0)
@@ -779,11 +798,11 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Enable transfer progress [\#325](https://github.com/nodegit/nodegit/pull/325) ([tbranyen](https://github.com/tbranyen))
-# v0.2.7 [(2015-01-21)](https://github.com/nodegit/nodegit/tree/v0.2.7)
+## v0.2.7 [(2015-01-21)](https://github.com/nodegit/nodegit/tree/v0.2.7)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.6...v0.2.7)
-# v0.2.6 [(2015-01-20)](https://github.com/nodegit/nodegit/tree/v0.2.6)
+## v0.2.6 [(2015-01-20)](https://github.com/nodegit/nodegit/tree/v0.2.6)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.5...v0.2.6)
@@ -791,7 +810,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- \[WIP\] Added in some diff functions from libgit2 [\#348](https://github.com/nodegit/nodegit/pull/348) ([johnhaley81](https://github.com/johnhaley81))
-# v0.2.5 [(2015-01-20)](https://github.com/nodegit/nodegit/tree/v0.2.5)
+## v0.2.5 [(2015-01-20)](https://github.com/nodegit/nodegit/tree/v0.2.5)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.4...v0.2.5)
@@ -857,7 +876,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- moving some deps to devdeps [\#320](https://github.com/nodegit/nodegit/pull/320) ([maxkorp](https://github.com/maxkorp))
-# v0.2.4 [(2014-12-05)](https://github.com/nodegit/nodegit/tree/v0.2.4)
+## v0.2.4 [(2014-12-05)](https://github.com/nodegit/nodegit/tree/v0.2.4)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.3...v0.2.4)
@@ -909,11 +928,11 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Styling [\#295](https://github.com/nodegit/nodegit/pull/295) ([maxkorp](https://github.com/maxkorp))
-# v0.2.3 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.3)
+## v0.2.3 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.2...v0.2.3)
-# v0.2.2 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.2)
+## v0.2.2 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.1...v0.2.2)
@@ -921,7 +940,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Moved some dependencies around to help the generate not fail [\#294](https://github.com/nodegit/nodegit/pull/294) ([johnhaley81](https://github.com/johnhaley81))
-# v0.2.1 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.1)
+## v0.2.1 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.2.0...v0.2.1)
@@ -929,7 +948,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Rewrite installer [\#293](https://github.com/nodegit/nodegit/pull/293) ([johnhaley81](https://github.com/johnhaley81))
-# v0.2.0 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.0)
+## v0.2.0 [(2014-11-25)](https://github.com/nodegit/nodegit/tree/v0.2.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.1.4...v0.2.0)
@@ -1121,7 +1140,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Better installation flow for developing. [\#180](https://github.com/nodegit/nodegit/pull/180) ([tbranyen](https://github.com/tbranyen))
-# v0.1.4 [(2014-06-13)](https://github.com/nodegit/nodegit/tree/v0.1.4)
+## v0.1.4 [(2014-06-13)](https://github.com/nodegit/nodegit/tree/v0.1.4)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.1.3...v0.1.4)
@@ -1143,7 +1162,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fixed: "ReferenceError: error is not defined" [\#169](https://github.com/nodegit/nodegit/pull/169) ([danyshaanan](https://github.com/danyshaanan))
-# v0.1.3 [(2014-05-02)](https://github.com/nodegit/nodegit/tree/v0.1.3)
+## v0.1.3 [(2014-05-02)](https://github.com/nodegit/nodegit/tree/v0.1.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.1.2...v0.1.3)
@@ -1151,7 +1170,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Fix erroneous OS detection for installation in OS X. [\#156](https://github.com/nodegit/nodegit/pull/156) ([tbranyen](https://github.com/tbranyen))
-# v0.1.2 [(2014-05-02)](https://github.com/nodegit/nodegit/tree/v0.1.2)
+## v0.1.2 [(2014-05-02)](https://github.com/nodegit/nodegit/tree/v0.1.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.1.1...v0.1.2)
@@ -1189,7 +1208,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- WIP New installer. [\#140](https://github.com/nodegit/nodegit/pull/140) ([tbranyen](https://github.com/tbranyen))
-# v0.1.1 [(2014-03-23)](https://github.com/nodegit/nodegit/tree/v0.1.1)
+## v0.1.1 [(2014-03-23)](https://github.com/nodegit/nodegit/tree/v0.1.1)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.1.0...v0.1.1)
@@ -1267,7 +1286,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Add system dependencies for OSX install [\#82](https://github.com/nodegit/nodegit/pull/82) ([philschatz](https://github.com/philschatz))
-# v0.1.0 [(2013-09-07)](https://github.com/nodegit/nodegit/tree/v0.1.0)
+## v0.1.0 [(2013-09-07)](https://github.com/nodegit/nodegit/tree/v0.1.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.79...v0.1.0)
@@ -1301,7 +1320,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Updated LICENSE to MIT [\#75](https://github.com/nodegit/nodegit/pull/75) ([tbranyen](https://github.com/tbranyen))
-# v0.0.79 [(2013-04-05)](https://github.com/nodegit/nodegit/tree/v0.0.79)
+## v0.0.79 [(2013-04-05)](https://github.com/nodegit/nodegit/tree/v0.0.79)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.778...v0.0.79)
@@ -1311,7 +1330,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Python error on installing nodegit 0.0.77 [\#59](https://github.com/nodegit/nodegit/issues/59)
-# v0.0.778 [(2013-03-26)](https://github.com/nodegit/nodegit/tree/v0.0.778)
+## v0.0.778 [(2013-03-26)](https://github.com/nodegit/nodegit/tree/v0.0.778)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.77...v0.0.778)
@@ -1319,15 +1338,15 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- See issue \#59 [\#60](https://github.com/nodegit/nodegit/pull/60) ([dctr](https://github.com/dctr))
-# v0.0.77 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.77)
+## v0.0.77 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.77)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.76...v0.0.77)
-# v0.0.76 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.76)
+## v0.0.76 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.76)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.75...v0.0.76)
-# v0.0.75 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.75)
+## v0.0.75 [(2013-03-24)](https://github.com/nodegit/nodegit/tree/v0.0.75)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.74...v0.0.75)
@@ -1357,11 +1376,11 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Comment all code methods [\#1](https://github.com/nodegit/nodegit/issues/1)
-# v0.0.74 [(2013-03-21)](https://github.com/nodegit/nodegit/tree/v0.0.74)
+## v0.0.74 [(2013-03-21)](https://github.com/nodegit/nodegit/tree/v0.0.74)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.73...v0.0.74)
-# v0.0.73 [(2013-03-21)](https://github.com/nodegit/nodegit/tree/v0.0.73)
+## v0.0.73 [(2013-03-21)](https://github.com/nodegit/nodegit/tree/v0.0.73)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.72...v0.0.73)
@@ -1375,11 +1394,11 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Tree each method is synchronous [\#15](https://github.com/nodegit/nodegit/issues/15)
-# v0.0.72 [(2013-03-06)](https://github.com/nodegit/nodegit/tree/v0.0.72)
+## v0.0.72 [(2013-03-06)](https://github.com/nodegit/nodegit/tree/v0.0.72)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.71...v0.0.72)
-# v0.0.71 [(2013-03-06)](https://github.com/nodegit/nodegit/tree/v0.0.71)
+## v0.0.71 [(2013-03-06)](https://github.com/nodegit/nodegit/tree/v0.0.71)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.6...v0.0.71)
@@ -1407,7 +1426,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Refactor [\#37](https://github.com/nodegit/nodegit/pull/37) ([mmalecki](https://github.com/mmalecki))
-# v0.0.6 [(2011-12-19)](https://github.com/nodegit/nodegit/tree/v0.0.6)
+## v0.0.6 [(2011-12-19)](https://github.com/nodegit/nodegit/tree/v0.0.6)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.4...v0.0.6)
@@ -1421,7 +1440,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Node 0.6x fixes [\#34](https://github.com/nodegit/nodegit/pull/34) ([moneal](https://github.com/moneal))
-# v0.0.4 [(2011-05-14)](https://github.com/nodegit/nodegit/tree/v0.0.4)
+## v0.0.4 [(2011-05-14)](https://github.com/nodegit/nodegit/tree/v0.0.4)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.3...v0.0.4)
@@ -1433,7 +1452,7 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Branch history each method is asynchronous [\#11](https://github.com/nodegit/nodegit/issues/11)
-# v0.0.3 [(2011-04-13)](https://github.com/nodegit/nodegit/tree/v0.0.3)
+## v0.0.3 [(2011-04-13)](https://github.com/nodegit/nodegit/tree/v0.0.3)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.2...v0.0.3)
@@ -1443,11 +1462,11 @@ We have added Node 6 as a supported platform! Going forward we aim to have 1:1 s
- Windows link issue [\#12](https://github.com/nodegit/nodegit/issues/12)
-# v0.0.2 [(2011-03-14)](https://github.com/nodegit/nodegit/tree/v0.0.2)
+## v0.0.2 [(2011-03-14)](https://github.com/nodegit/nodegit/tree/v0.0.2)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.0.1...v0.0.2)
-# v0.0.1 [(2011-03-10)](https://github.com/nodegit/nodegit/tree/v0.0.1)
+## v0.0.1 [(2011-03-10)](https://github.com/nodegit/nodegit/tree/v0.0.1)
diff --git a/README.md b/README.md
index 6e8c09e2c..d7047dac6 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ NodeGit
-**Stable: 0.12.2**
+**Stable: 0.13.1**
## Have a problem? Come chat with us! ##
diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json
index fbe9fd4fc..650fc9faa 100644
--- a/generate/input/descriptor.json
+++ b/generate/input/descriptor.json
@@ -1452,7 +1452,7 @@
"ignore": true
},
"oid": {
- "selfFreeing": "true",
+ "selfFreeing": true,
"cpyFunction": "git_oid_cpy",
"freeFunctionName": "free",
"shouldAlloc": true,
diff --git a/generate/templates/manual/include/async_libgit2_queue_worker.h b/generate/templates/manual/include/async_libgit2_queue_worker.h
new file mode 100644
index 000000000..f3ddf2fb3
--- /dev/null
+++ b/generate/templates/manual/include/async_libgit2_queue_worker.h
@@ -0,0 +1,33 @@
+#ifndef ASYNC_LIBGIT2_QUEUE_WORKER_H
+#define ASYNC_LIBGIT2_QUEUE_WORKER_H
+
+#include
+#include
+#include "../include/thread_pool.h"
+#include "../include/nodegit.h"
+
+
+// Runs WorkComplete of the scheduled AsyncWorker,
+// and destroys it. This is run in the uv_default_loop event loop.
+NAN_INLINE void AsyncLibgit2Complete (void* data) {
+ Nan::AsyncWorker *worker = static_cast(data);
+ worker->WorkComplete();
+ worker->Destroy();
+}
+
+// Runs Execute of the scheduled AyncWorker on the dedicated libgit2 thread /
+// event loop, and schedules the WorkComplete callback to run on the
+// uv_default_loop event loop
+NAN_INLINE void AsyncLibgit2Execute (void *vworker) {
+ // execute the worker
+ Nan::AsyncWorker *worker = static_cast(vworker);
+ worker->Execute();
+}
+
+// Schedules the AsyncWorker to run on the dedicated libgit2 thread / event loop,
+// and on completion AsyncLibgit2Complete on the default loop
+NAN_INLINE void AsyncLibgit2QueueWorker (Nan::AsyncWorker* worker) {
+ libgit2ThreadPool.QueueWork(AsyncLibgit2Execute, AsyncLibgit2Complete, worker);
+}
+
+#endif
diff --git a/generate/templates/manual/include/nodegit.h b/generate/templates/manual/include/nodegit.h
new file mode 100644
index 000000000..4408b8ea7
--- /dev/null
+++ b/generate/templates/manual/include/nodegit.h
@@ -0,0 +1,8 @@
+#ifndef NODEGIT_H
+#define NODEGIT_H
+
+#include "thread_pool.h"
+
+extern ThreadPool libgit2ThreadPool;
+
+#endif
diff --git a/generate/templates/manual/include/thread_pool.h b/generate/templates/manual/include/thread_pool.h
new file mode 100644
index 000000000..6d29b3ddf
--- /dev/null
+++ b/generate/templates/manual/include/thread_pool.h
@@ -0,0 +1,45 @@
+#ifndef THREAD_POOL_H
+#define THREAD_POOL_H
+
+#include
+#include
+
+class ThreadPool {
+ typedef void (*Callback) (void *);
+ struct Work {
+ Callback workCallback;
+ Callback loopCallback;
+ void *data;
+
+ Work(Callback workCallback, Callback loopCallback, void *data)
+ : workCallback(workCallback), loopCallback(loopCallback), data(data) {
+ }
+ };
+
+ // work to be performed on the threadpool
+ std::queue workQueue;
+ uv_mutex_t workMutex;
+ uv_sem_t workSemaphore;
+ int workInProgressCount;
+
+ // completion callbacks to be performed on the loop
+ std::queue loopQueue;
+ uv_mutex_t loopMutex;
+ uv_async_t loopAsync;
+
+ static void RunEventQueue(void *threadPool);
+ void RunEventQueue();
+ static void RunLoopCallbacks(uv_async_t* handle);
+ void RunLoopCallbacks();
+public:
+ // Initializes thread pool and spins up the requested number of threads
+ // The provided loop will be used for completion callbacks, whenever
+ // queued work is completed
+ ThreadPool(int numberOfThreads, uv_loop_t *loop);
+ // Queues work on the thread pool, followed by completion call scheduled
+ // on the loop provided in the constructor.
+ // QueueWork should be called on the loop provided in the constructor.
+ void QueueWork(Callback workCallback, Callback loopCallback, void *data);
+};
+
+#endif
diff --git a/generate/templates/manual/revwalk/fast_walk.cc b/generate/templates/manual/revwalk/fast_walk.cc
index 4a2ad7ea5..a7e3c54f3 100644
--- a/generate/templates/manual/revwalk/fast_walk.cc
+++ b/generate/templates/manual/revwalk/fast_walk.cc
@@ -73,9 +73,11 @@ void GitRevwalk::FastWalkWorker::HandleOKCallback()
unsigned int size = baton->out->size();
Local result = Nan::New(size);
for (unsigned int i = 0; i < size; i++) {
- Nan::Set(result, Nan::New(i), GitOid::New(baton->out->at(i), false));
+ Nan::Set(result, Nan::New(i), GitOid::New(baton->out->at(i), true));
}
+ delete baton->out;
+
Local argv[2] = {
Nan::Null(),
result
diff --git a/generate/templates/manual/src/nodegit_wrapper.cc b/generate/templates/manual/src/nodegit_wrapper.cc
index e22468a99..ea6694425 100644
--- a/generate/templates/manual/src/nodegit_wrapper.cc
+++ b/generate/templates/manual/src/nodegit_wrapper.cc
@@ -11,6 +11,7 @@ NodeGitWrapper::NodeGitWrapper(typename Traits::cType *raw, bool selfFre
} else {
this->owner.Reset(owner);
this->raw = raw;
+ selfFreeing = false;
}
} else {
this->raw = raw;
diff --git a/generate/templates/manual/src/thread_pool.cc b/generate/templates/manual/src/thread_pool.cc
new file mode 100644
index 000000000..abf7a29a8
--- /dev/null
+++ b/generate/templates/manual/src/thread_pool.cc
@@ -0,0 +1,85 @@
+#include "../include/thread_pool.h"
+
+ThreadPool::ThreadPool(int numberOfThreads, uv_loop_t *loop) {
+ uv_mutex_init(&workMutex);
+ uv_sem_init(&workSemaphore, 0);
+
+ uv_async_init(loop, &loopAsync, RunLoopCallbacks);
+ loopAsync.data = this;
+ uv_unref((uv_handle_t *)&loopAsync);
+ uv_mutex_init(&loopMutex);
+
+ workInProgressCount = 0;
+
+ for(int i=0; i(threadPool)->RunEventQueue();
+}
+
+void ThreadPool::RunEventQueue() {
+ for ( ; ; ) {
+ // wait until there is work to do
+ uv_sem_wait(&workSemaphore);
+ uv_mutex_lock(&workMutex);
+ // the semaphore should guarantee that queue is not empty
+ Work work = workQueue.front();
+ workQueue.pop();
+ uv_mutex_unlock(&workMutex);
+
+ // perform the queued work
+ (*work.workCallback)(work.data);
+
+ // schedule the callback on the loop
+ uv_mutex_lock(&loopMutex);
+ loopQueue.push(work);
+ uv_mutex_unlock(&loopMutex);
+ uv_async_send(&loopAsync);
+ }
+}
+
+void ThreadPool::RunLoopCallbacks(uv_async_t* handle) {
+ static_cast(handle->data)->RunLoopCallbacks();
+}
+
+void ThreadPool::RunLoopCallbacks() {
+ // uv_async_send can coalesce calls, so we are not guaranteed one
+ // RunLoopCallbacks per uv_async_send call
+ // so we always process the entire loopQueue
+ int callbacksCompleted = 0;
+ uv_mutex_lock(&loopMutex);
+ while(!loopQueue.empty()) {
+ Work work = loopQueue.front();
+ loopQueue.pop();
+ uv_mutex_unlock(&loopMutex);
+ // perform the queued loop callback
+ (*work.loopCallback)(work.data);
+ callbacksCompleted++;
+ uv_mutex_lock(&loopMutex);
+ }
+ uv_mutex_unlock(&loopMutex);
+
+ uv_mutex_lock(&workMutex);
+ // if there is no ongoing work / completion processing, node doesn't need
+ // to be prevented from terminating
+ workInProgressCount -= callbacksCompleted;
+ if(!workInProgressCount) {
+ uv_unref((uv_handle_t *)&loopAsync);
+ }
+ uv_mutex_unlock(&workMutex);
+}
diff --git a/generate/templates/partials/async_function.cc b/generate/templates/partials/async_function.cc
index 7b564adb2..edfae89df 100644
--- a/generate/templates/partials/async_function.cc
+++ b/generate/templates/partials/async_function.cc
@@ -74,7 +74,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) {
{%endif%}
{%endeach%}
- Nan::AsyncQueueWorker(worker);
+ AsyncLibgit2QueueWorker(worker);
return;
}
diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp
index 9a2813579..dbc60874a 100644
--- a/generate/templates/templates/binding.gyp
+++ b/generate/templates/templates/binding.gyp
@@ -22,6 +22,7 @@
"src/convenient_patch.cc",
"src/convenient_hunk.cc",
"src/str_array_converter.cc",
+ "src/thread_pool.cc",
{% each %}
{% if type != "enum" %}
"src/{{ name }}.cc",
diff --git a/generate/templates/templates/class_content.cc b/generate/templates/templates/class_content.cc
index b8084baa6..834361884 100644
--- a/generate/templates/templates/class_content.cc
+++ b/generate/templates/templates/class_content.cc
@@ -12,6 +12,7 @@ extern "C" {
#include "../include/functions/copy.h"
#include "../include/{{ filename }}.h"
#include "nodegit_wrapper.cc"
+#include "../include/async_libgit2_queue_worker.h"
{% each dependencies as dependency %}
#include "{{ dependency }}"
diff --git a/generate/templates/templates/nodegit.cc b/generate/templates/templates/nodegit.cc
index 189a4d622..2cde41c12 100644
--- a/generate/templates/templates/nodegit.cc
+++ b/generate/templates/templates/nodegit.cc
@@ -10,6 +10,7 @@
#include "../include/init_ssh2.h"
#include "../include/lock_master.h"
+#include "../include/nodegit.h"
#include "../include/wrapper.h"
#include "../include/promise_completion.h"
#include "../include/functions/copy.h"
@@ -80,6 +81,8 @@ void OpenSSL_ThreadSetup() {
CRYPTO_set_id_callback(OpenSSL_IDCallback);
}
+ThreadPool libgit2ThreadPool(10, uv_default_loop());
+
extern "C" void init(Local target) {
// Initialize thread safety in openssl and libssh2
OpenSSL_ThreadSetup();
diff --git a/lib/remote.js b/lib/remote.js
index 29b157c1a..93a8461c1 100644
--- a/lib/remote.js
+++ b/lib/remote.js
@@ -26,7 +26,7 @@ Remote.lookup = lookupWrapper(Remote);
* @param {Enums.DIRECTION} direction The direction for the connection
* @param {RemoteCallbacks} callbacks The callback functions for the connection
* @param {ProxyOptions} proxyOpts Proxy settings
- * @param {Array[String]} customHeaders extra HTTP headers to use
+ * @param {Array} customHeaders extra HTTP headers to use
* @param {Function} callback
* @return {Number} error code
*/
diff --git a/lib/repository.js b/lib/repository.js
index 371f4d0b2..e3d66a94e 100644
--- a/lib/repository.js
+++ b/lib/repository.js
@@ -1311,204 +1311,217 @@ Repository.prototype.stageFilemode = function(filePath, stageNew) {
});
};
-/**
- * Stages or unstages line selection of a specified file
- *
- * @async
- * @param {String} filePath The relative path of this file in the repo
- * @param {Array} newLines The array of DiffLine objects
- * selected for staging or unstaging
- * @param {Boolean} isStaged Are the selected lines currently staged
- * @return {Number} 0 or an error code
- */
-Repository.prototype.stageLines =
- function(filePath, selectedLines, isSelectionStaged) {
+function getPathHunks(repo, index, filePath, isStaged) {
+ return Promise.resolve()
+ .then(function() {
+ if (isStaged) {
+ return repo.getHeadCommit()
+ .then(function getTreeFromCommit(commit) {
+ return commit.getTree();
+ })
+ .then(function getDiffFromTree(tree) {
+ return NodeGit.Diff.treeToIndex(repo, tree, index);
+ });
+ }
- function applySelectedLinesToBlob
- (pathHunks, isStaged, newLines, originalBlob) {
- var lineTypes = {
- ADDED: 43, // ascii code for '+'
- DELETED: 45 // ascii code for '-'
- };
- var newContent = "";
- var oldIndex = 0;
- var linesPromises = [];
+ return NodeGit.Diff.indexToWorkdir(repo, index, {
+ flags:
+ NodeGit.Diff.OPTION.SHOW_UNTRACKED_CONTENT |
+ NodeGit.Diff.OPTION.RECURSE_UNTRACKED_DIRS
+ });
+ })
+ .then(function(diff) {
+ if (!(NodeGit.Status.file(repo, filePath) &
+ NodeGit.Status.STATUS.WT_MODIFIED) &&
+ !(NodeGit.Status.file(repo, filePath) &
+ NodeGit.Status.STATUS.INDEX_MODIFIED)) {
+ return Promise.reject
+ ("Selected staging is only available on modified files.");
+ }
- //split the original file into lines
- var oldLines = originalBlob.toString().split("\n");
+ return diff.patches();
+ })
+ .then(function(patches) {
+ var pathPatch = patches.filter(function(patch) {
+ return patch.newFile().path() === filePath;
+ });
- //if no selected lines were sent, return the original content
- if (!newLines || newLines.length === 0) {
- return originalBlob;
- }
+ if (pathPatch.length !== 1) {
+ return Promise.reject("No differences found for this file.");
+ }
- function lineEqualsFirstNewLine(hunkLine) {
- return ((hunkLine.oldLineno() === newLines[0].oldLineno()) &&
- (hunkLine.newLineno() === newLines[0].newLineno()));
- }
+ return pathPatch[0].hunks();
+ });
+}
- function processSelectedLine(hunkLine) {
- //if this hunk line is a selected line find the selected line
- var newLine = newLines.filter(function(nLine) {
- return ((hunkLine.oldLineno() === nLine.oldLineno()) &&
- (hunkLine.newLineno() === nLine.newLineno()));
- });
+function applySelectedLinesToTarget
+ (originalContent, newLines, pathHunks, isStaged, reverse) {
+ // 43: ascii code for '+'
+ // 45: ascii code for '-'
+ var lineTypes = {
+ ADDED: !reverse ? 43 : 45,
+ DELETED: !reverse ? 45 : 43
+ };
+ var newContent = "";
+ var oldIndex = 0;
+ var linesPromises = [];
- if (hunkLine.content()
- .indexOf("\\ No newline at end of file") != -1) {
- return false;
- }
+ // split the original file into lines
+ var oldLines = originalContent.toString().split("\n");
- //determine what to add to the new content
- if ((isStaged && newLine && newLine.length > 0) ||
- (!isStaged && (!newLine || newLine.length === 0))) {
- if (hunkLine.origin() !== lineTypes.ADDED) {
- newContent += hunkLine.content();
- }
- if ((isStaged && hunkLine.origin() !== lineTypes.DELETED) ||
- (!isStaged && hunkLine.origin() !== lineTypes.ADDED)) {
- oldIndex++;
- }
- }
- else {
- switch (hunkLine.origin()) {
- case lineTypes.ADDED:
- newContent += hunkLine.content();
- if (isStaged) {
- oldIndex++;
- }
- break;
- case lineTypes.DELETED:
- if (!isStaged) {
- oldIndex++;
- }
- break;
- default:
- newContent += oldLines[oldIndex++];
- if (oldIndex < oldLines.length) {
- newContent += "\n";
- }
- break;
- }
- }
- }
+ // if no selected lines were sent, return the original content
+ if (!newLines || newLines.length === 0) {
+ return originalContent;
+ }
- //find the affected hunk
- pathHunks.forEach(function(pathHunk) {
- linesPromises.push(pathHunk.lines());
+ function lineEqualsFirstNewLine(hunkLine) {
+ return ((hunkLine.oldLineno() === newLines[0].oldLineno()) &&
+ (hunkLine.newLineno() === newLines[0].newLineno()));
+ }
+
+ function processSelectedLine(hunkLine) {
+ // if this hunk line is a selected line find the selected line
+ var newLine = newLines.filter(function(nLine) {
+ return ((hunkLine.oldLineno() === nLine.oldLineno()) &&
+ (hunkLine.newLineno() === nLine.newLineno()));
});
- return Promise.all(linesPromises).then(function(results) {
- for (var index = 0; index < results.length &&
- newContent.length < 1; index++) {
- var hunkStart = isStaged ? pathHunks[index].newStart()
- : pathHunks[index].oldStart();
- var lines = results[index];
- if (lines.filter(lineEqualsFirstNewLine).length > 0) {
- //add content that is before the hunk
- while (hunkStart > (oldIndex + 1)) {
- newContent += oldLines[oldIndex++] + "\n";
- }
- //modify the lines of the hunk according to the selection
- lines.forEach(processSelectedLine);
+ if (hunkLine.content().indexOf("\\ No newline at end of file") !== -1) {
+ return false;
+ }
- //add the rest of the file
- while (oldLines.length > oldIndex) {
- newContent += oldLines[oldIndex++] +
- (oldLines.length > oldIndex ? "\n" : "");
+ // determine what to add to the new content
+ if ((isStaged && newLine && newLine.length > 0) ||
+ (!isStaged && (!newLine || newLine.length === 0))) {
+ if (hunkLine.origin() !== lineTypes.ADDED) {
+ newContent += hunkLine.content();
+ }
+ if ((isStaged && hunkLine.origin() !== lineTypes.DELETED) ||
+ (!isStaged && hunkLine.origin() !== lineTypes.ADDED)) {
+ oldIndex++;
+ }
+ }
+ else {
+ switch (hunkLine.origin()) {
+ case lineTypes.ADDED:
+ newContent += hunkLine.content();
+ if (isStaged) {
+ oldIndex++;
}
- }
+ break;
+ case lineTypes.DELETED:
+ if (!isStaged) {
+ oldIndex++;
+ }
+ break;
+ default:
+ newContent += oldLines[oldIndex++];
+ if (oldIndex < oldLines.length) {
+ newContent += "\n";
+ }
+ break;
}
- return newContent;
- });
+ }
}
- var repo = this;
- var index;
- var diffPromise = function diffPromise() {
- return isSelectionStaged ?
- repo.getHeadCommit()
- .then(function getTreeFromCommit(commit) {
- return commit.getTree();
- })
- .then(function getDiffFromTree(tree) {
- return NodeGit.Diff.treeToIndex(repo, tree, index);
- })
- :
- NodeGit.Diff.indexToWorkdir(repo, index, {
- flags:
- NodeGit.Diff.OPTION.SHOW_UNTRACKED_CONTENT |
- NodeGit.Diff.OPTION.RECURSE_UNTRACKED_DIRS
- });
- };
+ // find the affected hunk
+ pathHunks.forEach(function(pathHunk) {
+ linesPromises.push(pathHunk.lines());
+ });
- //The following chain checks if there is a patch with no hunks left for the
- //file, and no filemode changes were done on the file. It is then safe to
- //stage the entire file so the file doesn't show as having unstaged changes
- //in `git status`. Also, check if there are no type changes.
- var lastHunkStagedPromise = function lastHunkStagedPromise(result) {
- return NodeGit.Diff.indexToWorkdir(repo, index, {
- flags:
- NodeGit.Diff.OPTION.SHOW_UNTRACKED_CONTENT |
- NodeGit.Diff.OPTION.RECURSE_UNTRACKED_DIRS
- })
- .then(function (diff) {
- return diff.patches();
- })
- .then(function(patches) {
- var pathPatch = patches.filter(function(patch) {
- return patch.newFile().path() === filePath;
- });
- var emptyPatch = false;
- if (pathPatch.length > 0) {
- //No hunks, unchanged file mode, and no type changes.
- emptyPatch = pathPatch[0].size() === 0 &&
- pathPatch[0].oldFile().mode() == pathPatch[0].newFile().mode() &&
- !pathPatch[0].isTypeChange();
+ return Promise.all(linesPromises).then(function(results) {
+ for (var i = 0; i < results.length && newContent.length < 1; i++) {
+ var hunkStart = isStaged || reverse ? pathHunks[i].newStart()
+ : pathHunks[i].oldStart();
+ var lines = results[i];
+ if (lines.filter(lineEqualsFirstNewLine).length > 0) {
+ // add content that is before the hunk
+ while (hunkStart > (oldIndex + 1)) {
+ newContent += oldLines[oldIndex++] + "\n";
}
- if (emptyPatch) {
- return index.addByPath(filePath)
- .then(function() {
- return index.write();
- });
- } else {
- return result;
+
+ // modify the lines of the hunk according to the selection
+ lines.forEach(processSelectedLine);
+
+ // add the rest of the file
+ while (oldLines.length > oldIndex) {
+ newContent += oldLines[oldIndex++] +
+ (oldLines.length > oldIndex ? "\n" : "");
}
- });
- };
+ }
+ }
+ return newContent;
+ });
+}
- return repo.refreshIndex()
- .then(function(indexResult) {
- index = indexResult;
- })
- .then(function() {
- return diffPromise();
+/**
+ * Stages or unstages line selection of a specified file
+ *
+ * @async
+ * @param {String} filePath The relative path of this file in the repo
+ * @param {Array} selectedLines The array of DiffLine objects
+ * selected for staging or unstaging
+ * @param {Boolean} isStaged Are the selected lines currently staged
+ * @return {Number} 0 or an error code
+ */
+Repository.prototype.stageLines =
+ function(filePath, selectedLines, isSelectionStaged) {
+
+ var repo = this;
+ var index;
+ var originalBlob;
+
+ // The following chain checks if there is a patch with no hunks left for the
+ // file, and no filemode changes were done on the file. It is then safe to
+ // stage the entire file so the file doesn't show as having unstaged changes
+ // in `git status`. Also, check if there are no type changes.
+ var lastHunkStagedPromise = function lastHunkStagedPromise(result) {
+ return NodeGit.Diff.indexToWorkdir(repo, index, {
+ flags:
+ NodeGit.Diff.OPTION.SHOW_UNTRACKED_CONTENT |
+ NodeGit.Diff.OPTION.RECURSE_UNTRACKED_DIRS
})
.then(function(diff) {
- if (!(NodeGit.Status.file(repo, filePath) &
- NodeGit.Status.STATUS.WT_MODIFIED) &&
- !(NodeGit.Status.file(repo, filePath) &
- NodeGit.Status.STATUS.INDEX_MODIFIED)) {
- return Promise.reject
- ("Selected staging is only available on modified files.");
- }
return diff.patches();
})
.then(function(patches) {
- var pathOid = index.getByPath(filePath).id;
var pathPatch = patches.filter(function(patch) {
return patch.newFile().path() === filePath;
});
- if (pathPatch.length !== 1) {
- return Promise.reject("No differences found for this file.");
+ var emptyPatch = false;
+ if (pathPatch.length > 0) {
+ // No hunks, unchanged file mode, and no type changes.
+ emptyPatch = pathPatch[0].size() === 0 &&
+ pathPatch[0].oldFile().mode() === pathPatch[0].newFile().mode() &&
+ !pathPatch[0].isTypeChange();
}
- return Promise.all([repo.getBlob(pathOid), pathPatch[0].hunks()]);
+ if (emptyPatch) {
+ return index.addByPath(filePath)
+ .then(function() {
+ return index.write();
+ });
+ }
+
+ return result;
+ });
+ };
+
+ return repo.refreshIndex()
+ .then(function(indexResult) {
+ index = indexResult;
+ var pathOid = index.getByPath(filePath).id;
+
+ return repo.getBlob(pathOid);
+ })
+ .then(function(blob) {
+ originalBlob = blob;
+
+ return getPathHunks(repo, index, filePath, isSelectionStaged);
})
- .then(function(results) {
- var originalBlob = results[0];
- var pathHunks = results[1];
- return applySelectedLinesToBlob(
- pathHunks, isSelectionStaged, selectedLines, originalBlob);
+ .then(function(hunks) {
+ return applySelectedLinesToTarget(
+ originalBlob, selectedLines, hunks, isSelectionStaged
+ );
})
.then(function(newContent) {
var newContentBuffer = new Buffer(newContent);
@@ -1530,9 +1543,46 @@ Repository.prototype.stageLines =
.then(function(result) {
if (isSelectionStaged) {
return result;
- } else {
- return lastHunkStagedPromise(result);
}
+
+ return lastHunkStagedPromise(result);
+ });
+};
+
+/**
+ * Discard line selection of a specified file.
+ * Assumes selected lines are unstaged.
+ *
+ * @async
+ * @param {String} filePath The relative path of this file in the repo
+ * @param {Array} selectedLines The array of DiffLine objects
+ * selected for discarding
+ * @return {Number} 0 or an error code
+ */
+Repository.prototype.discardLines = function(filePath, selectedLines) {
+ var repo = this;
+ var fullFilePath = path.join(repo.workdir(), filePath);
+ var index;
+ var originalContent;
+
+ return repo.refreshIndex()
+ .then(function(indexResult) {
+ index = indexResult;
+
+ return fse.readFile(fullFilePath, "utf8");
+ })
+ .then(function(content) {
+ originalContent = content;
+
+ return getPathHunks(repo, index, filePath, false);
+ })
+ .then(function(hunks) {
+ return applySelectedLinesToTarget(
+ originalContent, selectedLines, hunks, false, true
+ );
+ })
+ .then(function(newContent) {
+ return fse.writeFile(fullFilePath, newContent);
});
};
diff --git a/lifecycleScripts/submodules/getStatus.js b/lifecycleScripts/submodules/getStatus.js
index a6b3f801c..53c85c1f3 100644
--- a/lifecycleScripts/submodules/getStatus.js
+++ b/lifecycleScripts/submodules/getStatus.js
@@ -5,6 +5,13 @@ var exec = require(path.join(rootDir, "./utils/execPromise"));
module.exports = function getStatus() {
return exec("git submodule status", { cwd: rootDir})
.then(function(stdout) {
+ if (!stdout) {
+ // In the case where we pull from npm they pre-init the submodules for
+ // us and `git submodule status` returns empty-string. In that case
+ // we'll just assume that we're good.
+ return Promise.resolve([]);
+ }
+
function getStatusPromiseFromLine(line) {
var lineSections = line.trim().split(" ");
var onNewCommit = !!~lineSections[0].indexOf("+");
diff --git a/package.json b/package.json
index 60ad78d7f..1dc406e66 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "nodegit",
"description": "Node.js libgit2 asynchronous native bindings",
- "version": "0.13.0",
+ "version": "0.13.1",
"homepage": "http://nodegit.org",
"keywords": [
"libgit2",
diff --git a/test/tests/stage.js b/test/tests/stage.js
index ac0675492..248c3e0f1 100644
--- a/test/tests/stage.js
+++ b/test/tests/stage.js
@@ -25,7 +25,7 @@ describe("Stage", function() {
return fse.remove(test.repository.workdir());
});
- function stagingTest(staging, newFileContent) {
+ function stagingTest(isUnstaged, newFileContent, discarding) {
var fileContent = newFileContent ||
"One line of text\n" +
"Two lines of text\n"+
@@ -48,13 +48,22 @@ describe("Stage", function() {
"Nineteen lines of text\n"+
"Twenty lines of text\n";
var fileName = "stagedLinesTest.txt";
- var stagedFile;
+ var expectedContent;
var workingDirFile;
var getDiffFunction;
- if (staging) {
- stagedFile = fileContent.replace("Fifteen", "Changed fifteen");
- workingDirFile = stagedFile.replace("Three", "Changed three")
+
+ if (!isUnstaged || discarding) {
+ expectedContent = fileContent.replace("Three", "Changed three")
.replace("Seventeen", "Changed seventeen");
+ workingDirFile = expectedContent.replace("Fifteen", "Changed fifteen");
+ }
+ else {
+ expectedContent = fileContent.replace("Fifteen", "Changed fifteen");
+ workingDirFile = expectedContent.replace("Three", "Changed three")
+ .replace("Seventeen", "Changed seventeen");
+ }
+
+ if (isUnstaged) {
getDiffFunction = function() {
return test.repository.refreshIndex()
.then(function(index) {
@@ -71,10 +80,6 @@ describe("Stage", function() {
};
}
else {
- stagedFile = fileContent.replace("Three", "Changed three")
- .replace("Seventeen", "Changed seventeen");
- workingDirFile = stagedFile.replace("Fifteen", "Changed fifteen");
-
getDiffFunction = function() {
return RepoUtils.addFileToIndex(test.repository, fileName)
.then(function() {
@@ -138,17 +143,28 @@ describe("Stage", function() {
}
});
});
- return test.repository.stageLines(fileName, linesToStage, !staging);
+
+ if (discarding) {
+ return test.repository.discardLines(fileName, linesToStage);
+ }
+
+ return test.repository.stageLines(fileName, linesToStage, !isUnstaged);
})
.then(function() {
- return test.repository.refreshIndex();
- })
- .then(function(reloadedIndex) {
- var pathOid = reloadedIndex.getByPath(fileName).id;
- return test.repository.getBlob(pathOid);
+ if (discarding) {
+ return fse.readFile(
+ path.join(test.repository.workdir(), fileName), "utf8"
+ );
+ }
+
+ return test.repository.refreshIndex()
+ .then(function(reloadedIndex) {
+ var pathOid = reloadedIndex.getByPath(fileName).id;
+ return test.repository.getBlob(pathOid);
+ });
})
.then(function(resultFileContents) {
- assert.equal(resultFileContents.toString(), stagedFile);
+ assert.equal(resultFileContents.toString(), expectedContent);
});
}
@@ -501,4 +517,8 @@ describe("Stage", function() {
return compareFilemodes(false, freshIndex, 0 /* expect nochange */);
});
});
+
+ it("can discard selected lines", function() {
+ return stagingTest(true, null, true);
+ });
});