diff --git a/.travis.yml b/.travis.yml
index e4602d8ac..ef6f06fc2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,13 +22,10 @@ matrix:
include:
- os: linux
env: export NODE_VERSION="4" TARGET_ARCH="ia32"
- sudo: required
- os: linux
env: export NODE_VERSION="6.5" TARGET_ARCH="ia32"
- sudo: required
- os: linux
env: export NODE_VERSION="7.4" TARGET_ARCH="ia32"
- sudo: required
git:
depth: 1
@@ -50,10 +47,6 @@ before_install:
- export npm_config_clang=1
- export JOBS=4
- - if [ $TARGET_ARCH == "ia32" ]; then
- sudo ln -s /usr/include/asm-generic /usr/include/asm;
- fi
-
- if [ $TRAVIS_OS_NAME != "linux" ]; then
git clone https://github.com/creationix/nvm.git ./.nvm;
source ./.nvm/nvm.sh;
@@ -87,14 +80,10 @@ before_script:
- git config --global user.email johndoe@example.com
script:
- - if [ $TARGET_ARCH == "x64" ]; then
- if [ -z "$TRAVIS_TAG" ] && [ $TRAVIS_OS_NAME == "linux" ] && [ $NODE_VERSION == "6" ]; then
- npm test && npm run cov && npm run coveralls;
- else
- npm test;
- fi
+ if [ -z "$TRAVIS_TAG" ] && [ $TRAVIS_OS_NAME == "linux" ] && [ $NODE_VERSION == "6" ]; then
+ npm test && npm run cov && npm run coveralls;
else
- echo "Not running tests because the binary is not built for 64-bit systems";
+ npm test;
fi
after_success:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7be1c515b..2435a2c8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,74 @@
# Change Log
+## v0.18.0 [(2017-02-28)](https://github.com/nodegit/nodegit/releases/tag/v0.18.0)
+
+[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.17.0...v0.18.0)
+
+### API Changes
+
+ - All callbacks that go to libgit2 now have an optional `waitForResult` flag that can be `true`/`false`. Defaults to false. When true it will not stop libgit2 from continuing on before the JS code is fully executed and resolved (in cases of a Promise). This is useful for progress callbacks (like fetching) where the bubbling up of the progress to JS doesn't really need the C/C++ code to wait for the JS code to fully handle the event before continuing. This can have serious performance implications for many callbacks that can be fired quite frequently.
+ - `given_opts` in `Revert.revert` are now optional
+ - `checkout_opts` in `Reset.fromAnnotated` and `Reset.reset` are now optional
+ - `Reset.fromAnnotated` is now async
+ - `message` on `Stash.save` is now optional
+ - `options` on `Stash.apply` and `Stash.pop` is now optional
+ - Added `processMergeMessageCallback` on `Repository#mergeBranches` to allow for custom merge messages
+ - Add `beforeFinishFn` to `Repository#rebaseBranches` and `Repository#continueRebase`. This is called before the invocation of `finish()`. If the callback returns a promise, `finish()` will be called when the promise resolves. The `beforeFinishFn` will be called with an object that has on it:
+ - `ontoName` The name of the branch that we rebased onto
+ - `ontoSha` The sha that we rebased onto
+ - `originalHeadName` The name of the branch that we rebased
+ - `originalHeadSha` The sha of the branch that was rebased
+ - `rewitten` which is an array of sha pairs that contain which contain what the commit sha was before the rebase and what the commit sha is after the rebase
+
+### Summary of Changes from bumping libgit2 to 43275f5
+
+[PR #1123](https://github.com/nodegit/nodegit/pull/1223) bumped libgit2 which brought in many changes and bug fixes.
+
+#### Included merged libgit2 PRs:
+
+ - [Use a shared buffer in calls of git_treebuilder_write to avoid heap contention #3892](https://github.com/libgit2/libgit2/pull/3892)
+ - [WinHTTP: set proper error messages when SSL fails #4050](https://github.com/libgit2/libgit2/pull/4050)
+ - [Clang analyzer run #4051](https://github.com/libgit2/libgit2/pull/4051)
+ - [Extend packfile in increments of page_size. #4053](https://github.com/libgit2/libgit2/pull/4053)
+ - [Fix general example memory leaks #4078](https://github.com/libgit2/libgit2/pull/4078)
+ - [WIP: some coverity & compiler warning fixes #4086](https://github.com/libgit2/libgit2/pull/4086)
+ - [Fix a few recent warnings #4087](https://github.com/libgit2/libgit2/pull/4087)
+ - [Fix uninitialized variable warning #4095](https://github.com/libgit2/libgit2/pull/4095)
+ - [Update docs for git_oid_fromstrn and p #4096](https://github.com/libgit2/libgit2/pull/4096)
+ - [Fix digest credentials for proxy in windows #4104](https://github.com/libgit2/libgit2/pull/4104)
+ - [Vector reverse overflow #4105](https://github.com/libgit2/libgit2/pull/4105)
+ - [Flag given_opts in git_revert as optional #4108](https://github.com/libgit2/libgit2/pull/4108)
+ - [Flag checkout_opts in git_reset as optional #4109](https://github.com/libgit2/libgit2/pull/4109)
+ - [dirname with DOS prefixes #4111](https://github.com/libgit2/libgit2/pull/4111)
+ - [Add support for lowercase proxy environment variables #4112](https://github.com/libgit2/libgit2/pull/4112)
+ - [Flag options in git_stash_apply and git_stash_pop as being optional #4117](https://github.com/libgit2/libgit2/pull/4117)
+ - [rename detection: don't try to detect submodule renames #4119](https://github.com/libgit2/libgit2/pull/4119)
+ - [tests: fix permissions on testrepo.git index file #4121](https://github.com/libgit2/libgit2/pull/4121)
+
+#### Included non-merged libgit2 PRs:
+
+ - [negotiate always fails via libcurl #4126](https://github.com/libgit2/libgit2/pull/4126)
+ - [Fix proxy auto detect not utilizing callbacks #4097](https://github.com/libgit2/libgit2/pull/4097)
+
+### Summary of Changes to NodeGit outside of libgit2 bump
+
+ - Don't overwrite C++ files for things that haven't changed [PR #1091](https://github.com/nodegit/nodegit/pull/1091)
+ - Add the option to "fire and forget" callbacks so libgit2 doesn't wait for JS to finish before proceeding [PR #1208](https://github.com/nodegit/nodegit/pull/1208)
+ - Send back the error code from libgit2 when a call fails [PR #1209](https://github.com/nodegit/nodegit/pull/1209)
+ - Initialize pointers to null [PR #1210](https://github.com/nodegit/nodegit/pull/1210)
+ - Replace Gitter with Slack [PR #1212](https://github.com/nodegit/nodegit/pull/1212)
+ - Make `given_opts` in `Revert.revert` optional [PR #1213](https://github.com/nodegit/nodegit/pull/1213)
+ - Make `Reset.fromAnnotated` async and `checkout_opts` optional [PR #1214](https://github.com/nodegit/nodegit/pull/1214)
+ - Make `message` on `Stash.save` optional [PR #1215](https://github.com/nodegit/nodegit/pull/1215)
+ - Add `Remote.ls` to NodeGit [PR #1218](https://github.com/nodegit/nodegit/pull/1218)
+ - Add `processMergeMessageCallback` to `Repository#mergeBranches` to allow for custom merge messages [PR #1219](https://github.com/nodegit/nodegit/pull/1219)
+ - Bump libgit2 to 43275f5 [PR #1223](https://github.com/nodegit/nodegit/pull/1223) from srajko/bump-libgit
+ - Provide rebase details on finish [PR #1224](https://github.com/nodegit/nodegit/pull/1224)
+ - Use wider int to calculate throttle window [PR #1232](https://github.com/nodegit/nodegit/pull/1232)
+ - Update comment to reflect the correct path for generated code output [PR #1236](https://github.com/nodegit/nodegit/pull/1236)
+ - Remove nwjs example from the docs [PR #1238](https://github.com/nodegit/nodegit/pull/1238)
+ - Remove `sudo` requirement from linux 32-bit builds [PR #1241](https://github.com/nodegit/nodegit/pull/1241)
+
## v0.17.0 [(2017-01-06)](https://github.com/nodegit/nodegit/releases/tag/v0.17.0)
[Full Changelog](https://github.com/nodegit/nodegit/compare/v0.16.0...v0.17.0)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 52a55d148..de461b0a3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,7 +6,8 @@ Contribution Guidelines
We try to be available pretty often to help when problems come up. We like to split incoming questions
into two categories: potential bugs/features, and questions. If you want a feature added, or think you've found a bug
in the code (or in the examples), search the [issue tracker](https://github.com/nodegit/nodegit/issues) and if you dont
-find anything, file a new issue. If you just have questions, instead of using issues, contact us in our [Gitter room](https://gitter.im/nodegit/nodegit).
+find anything, file a new issue. If you just have questions, instead of using issues, [sign up](http://slack.libgit2.org/)
+to libgit2's Slack instance and then contact us in the [#nodegit channel](https://libgit2.slack.com/messages/nodegit/).
## How to Help ##
@@ -21,7 +22,7 @@ These are all good easy ways to start getting involved with the project. You can
and see if you can help with any existing issues. Please comment with your intention and any questions before getting
started; duplicating work or doing something that would be rejected always sucks.
-Additionally, [the documentation](http://www.nodegit.org) needs some love. Get in touch with one of us on Gitter if
+Additionally, [the documentation](http://www.nodegit.org) needs some love. Get in touch with one of us on Slack if
you'd like to lend a hand with that.
-For anything else, Gitter is probably the best way to get in touch as well. Happy coding, merge you soon!
+For anything else, Slack is probably the best way to get in touch as well. Happy coding, merge you soon!
diff --git a/README.md b/README.md
index 84eed5ff8..91907f79b 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ NodeGit
-**Stable (libgit2#master): 0.17.0**
+**Stable (libgit2#master): 0.18.0**
**Stable (libgit2@0.24): 0.14.1**
## Have a problem? Come chat with us! ##
diff --git a/generate/input/descriptor.json b/generate/input/descriptor.json
index a9264214a..f1e26f1df 100644
--- a/generate/input/descriptor.json
+++ b/generate/input/descriptor.json
@@ -1805,6 +1805,9 @@
}
},
"remote": {
+ "dependencies": [
+ "../include/remote_head.h"
+ ],
"cType": "git_remote",
"selfFreeing": true,
"functions": {
@@ -1970,7 +1973,11 @@
}
},
"remote_head": {
- "ignore": true
+ "dependencies": [
+ "../include/functions/free.h"
+ ],
+ "freeFunctionName": "git_remote_head_free",
+ "selfFreeing": true
},
"repository": {
"dependencies": [
@@ -2044,6 +2051,11 @@
"functions": {
"git_revert": {
"isAsync": true,
+ "args": {
+ "given_opts": {
+ "isOptional": true
+ }
+ },
"return": {
"isErrorCode": true
}
@@ -2097,6 +2109,17 @@
"return": {
"isErrorCode": true
}
+ },
+ "git_reset_from_annotated": {
+ "args": {
+ "checkout_opts": {
+ "isOptional": true
+ }
+ },
+ "isAsync": true,
+ "return": {
+ "isErrorCode": true
+ }
}
}
},
@@ -2175,6 +2198,11 @@
}
},
"git_stash_save": {
+ "args": {
+ "message": {
+ "isOptional": true
+ }
+ },
"isAsync": true,
"return": {
"isErrorCode": true
@@ -2541,6 +2569,9 @@
}
}
},
+ "git_treebuilder_write_with_buffer": {
+ "ignore": true
+ },
"git_treebuilder_new": {
"args": {
"source": {
diff --git a/generate/input/libgit2-docs.json b/generate/input/libgit2-docs.json
index 34a478605..48099e8b0 100644
--- a/generate/input/libgit2-docs.json
+++ b/generate/input/libgit2-docs.json
@@ -172,7 +172,7 @@
"git_libgit2_opts"
],
"meta": {},
- "lines": 284
+ "lines": 312
},
{
"file": "config.h",
@@ -241,7 +241,7 @@
"git_describe_result_free"
],
"meta": {},
- "lines": 158
+ "lines": 161
},
{
"file": "diff.h",
@@ -423,7 +423,7 @@
"git_merge"
],
"meta": {},
- "lines": 578
+ "lines": 579
},
{
"file": "message.h",
@@ -556,7 +556,7 @@
"git_oid_shorten_free"
],
"meta": {},
- "lines": 265
+ "lines": 264
},
{
"file": "oidarray.h",
@@ -754,7 +754,6 @@
{
"file": "remote.h",
"functions": [
- "git_remote_rename_problem_cb",
"git_remote_create",
"git_remote_create_with_fetchspec",
"git_remote_create_anonymous",
@@ -993,7 +992,7 @@
"git_submodule_location"
],
"meta": {},
- "lines": 641
+ "lines": 632
},
{
"file": "sys/commit.h",
@@ -1123,10 +1122,12 @@
"git_repository_set_odb",
"git_repository_set_refdb",
"git_repository_set_index",
- "git_repository_set_bare"
+ "git_repository_set_bare",
+ "git_repository_submodule_cache_all",
+ "git_repository_submodule_cache_clear"
],
"meta": {},
- "lines": 136
+ "lines": 165
},
{
"file": "sys/stream.h",
@@ -1250,13 +1251,14 @@
"git_treebuilder_filter_cb",
"git_treebuilder_filter",
"git_treebuilder_write",
+ "git_treebuilder_write_with_buffer",
"git_treewalk_cb",
"git_tree_walk",
"git_tree_dup",
"git_tree_create_updated"
],
"meta": {},
- "lines": 465
+ "lines": 478
},
{
"file": "types.h",
@@ -1974,6 +1976,9 @@
"examples": {
"blame.c": [
"ex/HEAD/blame.html#git_blob_free-5"
+ ],
+ "general.c": [
+ "ex/HEAD/general.html#git_blob_free-2"
]
}
},
@@ -2050,7 +2055,7 @@
"ex/HEAD/cat-file.html#git_blob_rawcontent-1"
],
"general.c": [
- "ex/HEAD/general.html#git_blob_rawcontent-2"
+ "ex/HEAD/general.html#git_blob_rawcontent-3"
]
}
},
@@ -2083,8 +2088,8 @@
"ex/HEAD/cat-file.html#git_blob_rawsize-2"
],
"general.c": [
- "ex/HEAD/general.html#git_blob_rawsize-3",
- "ex/HEAD/general.html#git_blob_rawsize-4"
+ "ex/HEAD/general.html#git_blob_rawsize-4",
+ "ex/HEAD/general.html#git_blob_rawsize-5"
]
}
},
@@ -3165,9 +3170,9 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_lookup-5",
"ex/HEAD/general.html#git_commit_lookup-6",
- "ex/HEAD/general.html#git_commit_lookup-7"
+ "ex/HEAD/general.html#git_commit_lookup-7",
+ "ex/HEAD/general.html#git_commit_lookup-8"
],
"log.c": [
"ex/HEAD/log.html#git_commit_lookup-1"
@@ -3234,10 +3239,11 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_free-8",
"ex/HEAD/general.html#git_commit_free-9",
"ex/HEAD/general.html#git_commit_free-10",
- "ex/HEAD/general.html#git_commit_free-11"
+ "ex/HEAD/general.html#git_commit_free-11",
+ "ex/HEAD/general.html#git_commit_free-12",
+ "ex/HEAD/general.html#git_commit_free-13"
],
"log.c": [
"ex/HEAD/log.html#git_commit_free-2",
@@ -3270,7 +3276,7 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_id-12"
+ "ex/HEAD/general.html#git_commit_id-14"
],
"log.c": [
"ex/HEAD/log.html#git_commit_id-6"
@@ -3354,9 +3360,9 @@
"ex/HEAD/cat-file.html#git_commit_message-4"
],
"general.c": [
- "ex/HEAD/general.html#git_commit_message-13",
- "ex/HEAD/general.html#git_commit_message-14",
- "ex/HEAD/general.html#git_commit_message-15"
+ "ex/HEAD/general.html#git_commit_message-15",
+ "ex/HEAD/general.html#git_commit_message-16",
+ "ex/HEAD/general.html#git_commit_message-17"
],
"log.c": [
"ex/HEAD/log.html#git_commit_message-9",
@@ -3456,8 +3462,8 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_time-16",
- "ex/HEAD/general.html#git_commit_time-17"
+ "ex/HEAD/general.html#git_commit_time-18",
+ "ex/HEAD/general.html#git_commit_time-19"
]
}
},
@@ -3509,7 +3515,7 @@
"ex/HEAD/cat-file.html#git_commit_committer-5"
],
"general.c": [
- "ex/HEAD/general.html#git_commit_committer-18"
+ "ex/HEAD/general.html#git_commit_committer-20"
],
"log.c": [
"ex/HEAD/log.html#git_commit_committer-11"
@@ -3542,8 +3548,8 @@
"ex/HEAD/cat-file.html#git_commit_author-6"
],
"general.c": [
- "ex/HEAD/general.html#git_commit_author-19",
- "ex/HEAD/general.html#git_commit_author-20"
+ "ex/HEAD/general.html#git_commit_author-21",
+ "ex/HEAD/general.html#git_commit_author-22"
],
"log.c": [
"ex/HEAD/log.html#git_commit_author-12",
@@ -3662,7 +3668,7 @@
"ex/HEAD/cat-file.html#git_commit_parentcount-8"
],
"general.c": [
- "ex/HEAD/general.html#git_commit_parentcount-21"
+ "ex/HEAD/general.html#git_commit_parentcount-23"
],
"log.c": [
"ex/HEAD/log.html#git_commit_parentcount-19",
@@ -3703,7 +3709,7 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_parent-22"
+ "ex/HEAD/general.html#git_commit_parent-24"
],
"log.c": [
"ex/HEAD/log.html#git_commit_parent-21",
@@ -3982,7 +3988,7 @@
"group": "commit",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_commit_create_v-23"
+ "ex/HEAD/general.html#git_commit_create_v-25"
],
"init.c": [
"ex/HEAD/init.html#git_commit_create_v-1"
@@ -4212,8 +4218,8 @@
"git_libgit2_features": {
"type": "function",
"file": "common.h",
- "line": 136,
- "lineto": 136,
+ "line": 154,
+ "lineto": 154,
"args": [],
"argline": "",
"sig": "",
@@ -4228,8 +4234,8 @@
"git_libgit2_opts": {
"type": "function",
"file": "common.h",
- "line": 284,
- "lineto": 284,
+ "line": 312,
+ "lineto": 312,
"args": [
{
"name": "option",
@@ -4244,7 +4250,7 @@
"comment": " 0 on success, \n<\n0 on failure"
},
"description": "
Set or query a library global option
\n",
- "comments": "Available options:
\n\n* opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):\n\n > Get the maximum mmap window size\n\n* opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):\n\n > Set the maximum mmap window size\n\n* opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):\n\n > Get the maximum memory that will be mapped in total by the library\n\n* opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):\n\n >Set the maximum amount of memory that can be mapped at any time by the library\n\n* opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)\n\n > Get the search path for a given level of config data. "level" must > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, > `GIT_CONFIG_LEVEL_XDG`, or `GIT_CONFIG_LEVEL_PROGRAMDATA`. > The search path is written to the `out` buffer.\n\n* opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)\n\n > Set the search path for a level of config data. The search path > applied to shared attributes and ignore files, too. > > - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR. > Pass NULL to reset to the default (generally based on environment > variables). Use magic path `$PATH` to include the old value > of the path (if you want to prepend or append, for instance). > > - `level` must be `GIT_CONFIG_LEVEL_SYSTEM`, > `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or > `GIT_CONFIG_LEVEL_PROGRAMDATA`.\n\n* opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size)\n\n > Set the maximum data size for the given type of object to be > considered eligible for caching in memory. Setting to value to > zero means that that type of object will not be cached. > Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache blobs) and 4k > for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG.\n\n* opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes)\n\n > Set the maximum total data size that will be cached in memory > across all repositories before libgit2 starts evicting objects > from the cache. This is a soft limit, in that the library might > briefly exceed it, but will start aggressively evicting objects > from cache when that happens. The default cache size is 256MB.\n\n* opts(GIT_OPT_ENABLE_CACHING, int enabled)\n\n > Enable or disable caching completely. > > Because caches are repository-specific, disabling the cache > cannot immediately clear all cached objects, but each cache will > be cleared on the next attempt to update anything in it.\n\n* opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed)\n\n > Get the current bytes in cache and the maximum that would be > allowed in the cache.\n\n* opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)\n\n > Get the default template path. > The path is written to the `out` buffer.\n\n* opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)\n\n > Set the default template path. > > - `path` directory of template.\n\n* opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, const char *file, const char *path)\n\n > Set the SSL certificate-authority locations. > > - `file` is the location of a file containing several > certificates concatenated together. > - `path` is the location of a directory holding several > certificates, one per file. > > Either parameter may be `NULL`, but not both.\n\n* opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)\n\n > Set the value of the User-Agent header. This value will be > appended to "git/1.0", for compatibility with other git clients. > > - `user_agent` is the value that will be delivered as the > User-Agent header on HTTP requests.\n\n* opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled)\n\n > Enable strict input validation when creating new objects > to ensure that all inputs to the new objects are valid. For > example, when this is enabled, the parent(s) and tree inputs > will be validated when creating a new commit. This defaults > to enabled.\n\n* opts(GIT_OPT_SET_SSL_CIPHERS, const char *ciphers)\n\n > Set the SSL ciphers use for HTTPS connections. > > - `ciphers` is the list of ciphers that are eanbled.\n \n",
+ "comments": "Available options:
\n\n* opts(GIT_OPT_GET_MWINDOW_SIZE, size_t *):\n\n > Get the maximum mmap window size\n\n* opts(GIT_OPT_SET_MWINDOW_SIZE, size_t):\n\n > Set the maximum mmap window size\n\n* opts(GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, size_t *):\n\n > Get the maximum memory that will be mapped in total by the library\n\n* opts(GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, size_t):\n\n >Set the maximum amount of memory that can be mapped at any time by the library\n\n* opts(GIT_OPT_GET_SEARCH_PATH, int level, git_buf *buf)\n\n > Get the search path for a given level of config data. "level" must > be one of `GIT_CONFIG_LEVEL_SYSTEM`, `GIT_CONFIG_LEVEL_GLOBAL`, > `GIT_CONFIG_LEVEL_XDG`, or `GIT_CONFIG_LEVEL_PROGRAMDATA`. > The search path is written to the `out` buffer.\n\n* opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)\n\n > Set the search path for a level of config data. The search path > applied to shared attributes and ignore files, too. > > - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR. > Pass NULL to reset to the default (generally based on environment > variables). Use magic path `$PATH` to include the old value > of the path (if you want to prepend or append, for instance). > > - `level` must be `GIT_CONFIG_LEVEL_SYSTEM`, > `GIT_CONFIG_LEVEL_GLOBAL`, `GIT_CONFIG_LEVEL_XDG`, or > `GIT_CONFIG_LEVEL_PROGRAMDATA`.\n\n* opts(GIT_OPT_SET_CACHE_OBJECT_LIMIT, git_otype type, size_t size)\n\n > Set the maximum data size for the given type of object to be > considered eligible for caching in memory. Setting to value to > zero means that that type of object will not be cached. > Defaults to 0 for GIT_OBJ_BLOB (i.e. won't cache blobs) and 4k > for GIT_OBJ_COMMIT, GIT_OBJ_TREE, and GIT_OBJ_TAG.\n\n* opts(GIT_OPT_SET_CACHE_MAX_SIZE, ssize_t max_storage_bytes)\n\n > Set the maximum total data size that will be cached in memory > across all repositories before libgit2 starts evicting objects > from the cache. This is a soft limit, in that the library might > briefly exceed it, but will start aggressively evicting objects > from cache when that happens. The default cache size is 256MB.\n\n* opts(GIT_OPT_ENABLE_CACHING, int enabled)\n\n > Enable or disable caching completely. > > Because caches are repository-specific, disabling the cache > cannot immediately clear all cached objects, but each cache will > be cleared on the next attempt to update anything in it.\n\n* opts(GIT_OPT_GET_CACHED_MEMORY, ssize_t *current, ssize_t *allowed)\n\n > Get the current bytes in cache and the maximum that would be > allowed in the cache.\n\n* opts(GIT_OPT_GET_TEMPLATE_PATH, git_buf *out)\n\n > Get the default template path. > The path is written to the `out` buffer.\n\n* opts(GIT_OPT_SET_TEMPLATE_PATH, const char *path)\n\n > Set the default template path. > > - `path` directory of template.\n\n* opts(GIT_OPT_SET_SSL_CERT_LOCATIONS, const char *file, const char *path)\n\n > Set the SSL certificate-authority locations. > > - `file` is the location of a file containing several > certificates concatenated together. > - `path` is the location of a directory holding several > certificates, one per file. > > Either parameter may be `NULL`, but not both.\n\n* opts(GIT_OPT_SET_USER_AGENT, const char *user_agent)\n\n > Set the value of the User-Agent header. This value will be > appended to "git/1.0", for compatibility with other git clients. > > - `user_agent` is the value that will be delivered as the > User-Agent header on HTTP requests.\n\n* opts(GIT_OPT_ENABLE_STRICT_OBJECT_CREATION, int enabled)\n\n > Enable strict input validation when creating new objects > to ensure that all inputs to the new objects are valid. For > example, when this is enabled, the parent(s) and tree inputs > will be validated when creating a new commit. This defaults > to enabled.\n\n* opts(GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION, int enabled)\n\n > Validate the target of a symbolic ref when creating it. For > example, `foobar` is not a valid ref, therefore `foobar` is > not a valid target for a symbolic ref by default, whereas > `refs/heads/foobar` is. Disabling this bypasses validation > so that an arbitrary strings such as `foobar` can be used > for a symbolic ref target. This defaults to enabled.\n\n* opts(GIT_OPT_SET_SSL_CIPHERS, const char *ciphers)\n\n > Set the SSL ciphers use for HTTPS connections. > > - `ciphers` is the list of ciphers that are eanbled.\n \n",
"group": "libgit2"
},
"git_config_entry_free": {
@@ -4466,7 +4472,7 @@
"group": "config",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_config_open_ondisk-24"
+ "ex/HEAD/general.html#git_config_open_ondisk-26"
]
}
},
@@ -4576,7 +4582,13 @@
},
"description": "Free the configuration and its associated memory and files
\n",
"comments": "",
- "group": "config"
+ "group": "config",
+ "examples": {
+ "general.c": [
+ "ex/HEAD/general.html#git_config_free-27",
+ "ex/HEAD/general.html#git_config_free-28"
+ ]
+ }
},
"git_config_get_entry": {
"type": "function",
@@ -4643,7 +4655,7 @@
"group": "config",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_config_get_int32-25"
+ "ex/HEAD/general.html#git_config_get_int32-29"
]
}
},
@@ -4776,7 +4788,7 @@
"group": "config",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_config_get_string-26"
+ "ex/HEAD/general.html#git_config_get_string-30"
]
}
},
@@ -5588,8 +5600,8 @@
"git_describe_commit": {
"type": "function",
"file": "describe.h",
- "line": 120,
- "lineto": 123,
+ "line": 123,
+ "lineto": 126,
"args": [
{
"name": "result",
@@ -5625,8 +5637,8 @@
"git_describe_workdir": {
"type": "function",
"file": "describe.h",
- "line": 137,
- "lineto": 140,
+ "line": 140,
+ "lineto": 143,
"args": [
{
"name": "out",
@@ -5662,8 +5674,8 @@
"git_describe_format": {
"type": "function",
"file": "describe.h",
- "line": 150,
- "lineto": 153,
+ "line": 153,
+ "lineto": 156,
"args": [
{
"name": "out",
@@ -5699,8 +5711,8 @@
"git_describe_result_free": {
"type": "function",
"file": "describe.h",
- "line": 158,
- "lineto": 158,
+ "line": 161,
+ "lineto": 161,
"args": [
{
"name": "result",
@@ -6920,7 +6932,7 @@
"group": "giterr",
"examples": {
"general.c": [
- "ex/HEAD/general.html#giterr_last-27"
+ "ex/HEAD/general.html#giterr_last-31"
],
"network/clone.c": [
"ex/HEAD/network/clone.html#giterr_last-2"
@@ -7317,7 +7329,7 @@
"ex/HEAD/diff.html#git_libgit2_init-13"
],
"general.c": [
- "ex/HEAD/general.html#git_libgit2_init-28"
+ "ex/HEAD/general.html#git_libgit2_init-32"
],
"init.c": [
"ex/HEAD/init.html#git_libgit2_init-2"
@@ -7620,7 +7632,7 @@
"group": "index",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_index_free-29"
+ "ex/HEAD/general.html#git_index_free-33"
],
"init.c": [
"ex/HEAD/init.html#git_index_free-4"
@@ -7954,7 +7966,7 @@
"group": "index",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_index_entrycount-30"
+ "ex/HEAD/general.html#git_index_entrycount-34"
]
}
},
@@ -8008,7 +8020,7 @@
"group": "index",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_index_get_byindex-31"
+ "ex/HEAD/general.html#git_index_get_byindex-35"
]
}
},
@@ -8923,8 +8935,8 @@
"git_merge_init_options": {
"type": "function",
"file": "merge.h",
- "line": 304,
- "lineto": 306,
+ "line": 305,
+ "lineto": 307,
"args": [
{
"name": "opts",
@@ -8950,8 +8962,8 @@
"git_merge_analysis": {
"type": "function",
"file": "merge.h",
- "line": 375,
- "lineto": 380,
+ "line": 376,
+ "lineto": 381,
"args": [
{
"name": "analysis_out",
@@ -8992,8 +9004,8 @@
"git_merge_base": {
"type": "function",
"file": "merge.h",
- "line": 391,
- "lineto": 395,
+ "line": 392,
+ "lineto": 396,
"args": [
{
"name": "out",
@@ -9037,8 +9049,8 @@
"git_merge_bases": {
"type": "function",
"file": "merge.h",
- "line": 406,
- "lineto": 410,
+ "line": 407,
+ "lineto": 411,
"args": [
{
"name": "out",
@@ -9074,8 +9086,8 @@
"git_merge_base_many": {
"type": "function",
"file": "merge.h",
- "line": 421,
- "lineto": 425,
+ "line": 422,
+ "lineto": 426,
"args": [
{
"name": "out",
@@ -9111,8 +9123,8 @@
"git_merge_bases_many": {
"type": "function",
"file": "merge.h",
- "line": 436,
- "lineto": 440,
+ "line": 437,
+ "lineto": 441,
"args": [
{
"name": "out",
@@ -9148,8 +9160,8 @@
"git_merge_base_octopus": {
"type": "function",
"file": "merge.h",
- "line": 451,
- "lineto": 455,
+ "line": 452,
+ "lineto": 456,
"args": [
{
"name": "out",
@@ -9185,8 +9197,8 @@
"git_merge_file": {
"type": "function",
"file": "merge.h",
- "line": 473,
- "lineto": 478,
+ "line": 474,
+ "lineto": 479,
"args": [
{
"name": "out",
@@ -9227,8 +9239,8 @@
"git_merge_file_from_index": {
"type": "function",
"file": "merge.h",
- "line": 494,
- "lineto": 500,
+ "line": 495,
+ "lineto": 501,
"args": [
{
"name": "out",
@@ -9274,8 +9286,8 @@
"git_merge_file_result_free": {
"type": "function",
"file": "merge.h",
- "line": 507,
- "lineto": 507,
+ "line": 508,
+ "lineto": 508,
"args": [
{
"name": "result",
@@ -9296,8 +9308,8 @@
"git_merge_trees": {
"type": "function",
"file": "merge.h",
- "line": 525,
- "lineto": 531,
+ "line": 526,
+ "lineto": 532,
"args": [
{
"name": "out",
@@ -9343,8 +9355,8 @@
"git_merge_commits": {
"type": "function",
"file": "merge.h",
- "line": 548,
- "lineto": 553,
+ "line": 549,
+ "lineto": 554,
"args": [
{
"name": "out",
@@ -9385,8 +9397,8 @@
"git_merge": {
"type": "function",
"file": "merge.h",
- "line": 573,
- "lineto": 578,
+ "line": 574,
+ "lineto": 579,
"args": [
{
"name": "repo",
@@ -10116,7 +10128,7 @@
"ex/HEAD/cat-file.html#git_object_free-17"
],
"general.c": [
- "ex/HEAD/general.html#git_object_free-32"
+ "ex/HEAD/general.html#git_object_free-36"
],
"log.c": [
"ex/HEAD/log.html#git_object_free-38"
@@ -10163,8 +10175,8 @@
"ex/HEAD/cat-file.html#git_object_type2string-21"
],
"general.c": [
- "ex/HEAD/general.html#git_object_type2string-33",
- "ex/HEAD/general.html#git_object_type2string-34"
+ "ex/HEAD/general.html#git_object_type2string-37",
+ "ex/HEAD/general.html#git_object_type2string-38"
]
}
},
@@ -10393,6 +10405,9 @@
"examples": {
"cat-file.c": [
"ex/HEAD/cat-file.html#git_odb_free-22"
+ ],
+ "general.c": [
+ "ex/HEAD/general.html#git_odb_free-39"
]
}
},
@@ -10432,7 +10447,7 @@
"ex/HEAD/cat-file.html#git_odb_read-23"
],
"general.c": [
- "ex/HEAD/general.html#git_odb_read-35"
+ "ex/HEAD/general.html#git_odb_read-40"
]
}
},
@@ -10703,7 +10718,7 @@
"group": "odb",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_odb_write-36"
+ "ex/HEAD/general.html#git_odb_write-41"
]
}
},
@@ -11048,7 +11063,7 @@
"ex/HEAD/cat-file.html#git_odb_object_free-24"
],
"general.c": [
- "ex/HEAD/general.html#git_odb_object_free-37"
+ "ex/HEAD/general.html#git_odb_object_free-42"
]
}
},
@@ -11097,7 +11112,7 @@
"group": "odb",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_odb_object_data-38"
+ "ex/HEAD/general.html#git_odb_object_data-43"
]
}
},
@@ -11127,7 +11142,7 @@
"ex/HEAD/cat-file.html#git_odb_object_size-25"
],
"general.c": [
- "ex/HEAD/general.html#git_odb_object_size-39"
+ "ex/HEAD/general.html#git_odb_object_size-44"
]
}
},
@@ -11154,7 +11169,7 @@
"group": "odb",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_odb_object_type-40"
+ "ex/HEAD/general.html#git_odb_object_type-45"
]
}
},
@@ -11405,22 +11420,22 @@
"group": "oid",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_oid_fromstr-41",
- "ex/HEAD/general.html#git_oid_fromstr-42",
- "ex/HEAD/general.html#git_oid_fromstr-43",
- "ex/HEAD/general.html#git_oid_fromstr-44",
- "ex/HEAD/general.html#git_oid_fromstr-45",
"ex/HEAD/general.html#git_oid_fromstr-46",
"ex/HEAD/general.html#git_oid_fromstr-47",
- "ex/HEAD/general.html#git_oid_fromstr-48"
+ "ex/HEAD/general.html#git_oid_fromstr-48",
+ "ex/HEAD/general.html#git_oid_fromstr-49",
+ "ex/HEAD/general.html#git_oid_fromstr-50",
+ "ex/HEAD/general.html#git_oid_fromstr-51",
+ "ex/HEAD/general.html#git_oid_fromstr-52",
+ "ex/HEAD/general.html#git_oid_fromstr-53"
]
}
},
"git_oid_fromstrp": {
"type": "function",
"file": "oid.h",
- "line": 57,
- "lineto": 57,
+ "line": 56,
+ "lineto": 56,
"args": [
{
"name": "out",
@@ -11430,7 +11445,7 @@
{
"name": "str",
"type": "const char *",
- "comment": "input hex string; must be at least 4 characters\n long and null-terminated."
+ "comment": "input hex string; must be null-terminated."
}
],
"argline": "git_oid *out, const char *str",
@@ -11446,8 +11461,8 @@
"git_oid_fromstrn": {
"type": "function",
"file": "oid.h",
- "line": 70,
- "lineto": 70,
+ "line": 69,
+ "lineto": 69,
"args": [
{
"name": "out",
@@ -11471,15 +11486,15 @@
"type": "int",
"comment": " 0 or an error code"
},
- "description": "Parse N characters of a hex formatted object id into a git_oid
\n",
- "comments": "If N is odd, N-1 characters will be parsed instead. The remaining space in the git_oid will be set to zero.
\n",
+ "description": "Parse N characters of a hex formatted object id into a git_oid.
\n",
+ "comments": "If N is odd, the last byte's high nibble will be read in and the low nibble set to zero.
\n",
"group": "oid"
},
"git_oid_fromraw": {
"type": "function",
"file": "oid.h",
- "line": 78,
- "lineto": 78,
+ "line": 77,
+ "lineto": 77,
"args": [
{
"name": "out",
@@ -11505,8 +11520,8 @@
"git_oid_fmt": {
"type": "function",
"file": "oid.h",
- "line": 90,
- "lineto": 90,
+ "line": 89,
+ "lineto": 89,
"args": [
{
"name": "out",
@@ -11530,12 +11545,12 @@
"group": "oid",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_oid_fmt-49",
- "ex/HEAD/general.html#git_oid_fmt-50",
- "ex/HEAD/general.html#git_oid_fmt-51",
- "ex/HEAD/general.html#git_oid_fmt-52",
- "ex/HEAD/general.html#git_oid_fmt-53",
- "ex/HEAD/general.html#git_oid_fmt-54"
+ "ex/HEAD/general.html#git_oid_fmt-54",
+ "ex/HEAD/general.html#git_oid_fmt-55",
+ "ex/HEAD/general.html#git_oid_fmt-56",
+ "ex/HEAD/general.html#git_oid_fmt-57",
+ "ex/HEAD/general.html#git_oid_fmt-58",
+ "ex/HEAD/general.html#git_oid_fmt-59"
],
"network/fetch.c": [
"ex/HEAD/network/fetch.html#git_oid_fmt-1",
@@ -11552,8 +11567,8 @@
"git_oid_nfmt": {
"type": "function",
"file": "oid.h",
- "line": 101,
- "lineto": 101,
+ "line": 100,
+ "lineto": 100,
"args": [
{
"name": "out",
@@ -11584,8 +11599,8 @@
"git_oid_pathfmt": {
"type": "function",
"file": "oid.h",
- "line": 116,
- "lineto": 116,
+ "line": 115,
+ "lineto": 115,
"args": [
{
"name": "out",
@@ -11611,8 +11626,8 @@
"git_oid_tostr_s": {
"type": "function",
"file": "oid.h",
- "line": 129,
- "lineto": 129,
+ "line": 128,
+ "lineto": 128,
"args": [
{
"name": "oid",
@@ -11633,8 +11648,8 @@
"git_oid_tostr": {
"type": "function",
"file": "oid.h",
- "line": 148,
- "lineto": 148,
+ "line": 147,
+ "lineto": 147,
"args": [
{
"name": "out",
@@ -11688,8 +11703,8 @@
"git_oid_cpy": {
"type": "function",
"file": "oid.h",
- "line": 156,
- "lineto": 156,
+ "line": 155,
+ "lineto": 155,
"args": [
{
"name": "out",
@@ -11722,8 +11737,8 @@
"git_oid_cmp": {
"type": "function",
"file": "oid.h",
- "line": 165,
- "lineto": 165,
+ "line": 164,
+ "lineto": 164,
"args": [
{
"name": "a",
@@ -11749,8 +11764,8 @@
"git_oid_equal": {
"type": "function",
"file": "oid.h",
- "line": 174,
- "lineto": 174,
+ "line": 173,
+ "lineto": 173,
"args": [
{
"name": "a",
@@ -11776,8 +11791,8 @@
"git_oid_ncmp": {
"type": "function",
"file": "oid.h",
- "line": 185,
- "lineto": 185,
+ "line": 184,
+ "lineto": 184,
"args": [
{
"name": "a",
@@ -11808,8 +11823,8 @@
"git_oid_streq": {
"type": "function",
"file": "oid.h",
- "line": 194,
- "lineto": 194,
+ "line": 193,
+ "lineto": 193,
"args": [
{
"name": "id",
@@ -11835,8 +11850,8 @@
"git_oid_strcmp": {
"type": "function",
"file": "oid.h",
- "line": 204,
- "lineto": 204,
+ "line": 203,
+ "lineto": 203,
"args": [
{
"name": "id",
@@ -11862,8 +11877,8 @@
"git_oid_iszero": {
"type": "function",
"file": "oid.h",
- "line": 211,
- "lineto": 211,
+ "line": 210,
+ "lineto": 210,
"args": [
{
"name": "id",
@@ -11892,8 +11907,8 @@
"git_oid_shorten_new": {
"type": "function",
"file": "oid.h",
- "line": 232,
- "lineto": 232,
+ "line": 231,
+ "lineto": 231,
"args": [
{
"name": "min_length",
@@ -11914,8 +11929,8 @@
"git_oid_shorten_add": {
"type": "function",
"file": "oid.h",
- "line": 258,
- "lineto": 258,
+ "line": 257,
+ "lineto": 257,
"args": [
{
"name": "os",
@@ -11941,8 +11956,8 @@
"git_oid_shorten_free": {
"type": "function",
"file": "oid.h",
- "line": 265,
- "lineto": 265,
+ "line": 264,
+ "lineto": 264,
"args": [
{
"name": "os",
@@ -14102,7 +14117,7 @@
"group": "reference",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_reference_lookup-55"
+ "ex/HEAD/general.html#git_reference_lookup-60"
]
}
},
@@ -14391,7 +14406,7 @@
"group": "reference",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_reference_target-56"
+ "ex/HEAD/general.html#git_reference_target-61"
]
}
},
@@ -14440,7 +14455,7 @@
"group": "reference",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_reference_symbolic_target-57"
+ "ex/HEAD/general.html#git_reference_symbolic_target-62"
]
}
},
@@ -14467,7 +14482,7 @@
"group": "reference",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_reference_type-58"
+ "ex/HEAD/general.html#git_reference_type-63"
]
}
},
@@ -14735,7 +14750,7 @@
"group": "reference",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_reference_list-59"
+ "ex/HEAD/general.html#git_reference_list-64"
]
}
},
@@ -14852,6 +14867,9 @@
"comments": "",
"group": "reference",
"examples": {
+ "general.c": [
+ "ex/HEAD/general.html#git_reference_free-65"
+ ],
"status.c": [
"ex/HEAD/status.html#git_reference_free-3"
]
@@ -15547,8 +15565,8 @@
"git_remote_create": {
"type": "function",
"file": "remote.h",
- "line": 40,
- "lineto": 44,
+ "line": 38,
+ "lineto": 42,
"args": [
{
"name": "out",
@@ -15589,8 +15607,8 @@
"git_remote_create_with_fetchspec": {
"type": "function",
"file": "remote.h",
- "line": 57,
- "lineto": 62,
+ "line": 55,
+ "lineto": 60,
"args": [
{
"name": "out",
@@ -15631,8 +15649,8 @@
"git_remote_create_anonymous": {
"type": "function",
"file": "remote.h",
- "line": 75,
- "lineto": 78,
+ "line": 73,
+ "lineto": 76,
"args": [
{
"name": "out",
@@ -15671,8 +15689,8 @@
"git_remote_lookup": {
"type": "function",
"file": "remote.h",
- "line": 91,
- "lineto": 91,
+ "line": 89,
+ "lineto": 89,
"args": [
{
"name": "out",
@@ -15714,8 +15732,8 @@
"git_remote_dup": {
"type": "function",
"file": "remote.h",
- "line": 103,
- "lineto": 103,
+ "line": 101,
+ "lineto": 101,
"args": [
{
"name": "dest",
@@ -15741,8 +15759,8 @@
"git_remote_owner": {
"type": "function",
"file": "remote.h",
- "line": 111,
- "lineto": 111,
+ "line": 109,
+ "lineto": 109,
"args": [
{
"name": "remote",
@@ -15763,8 +15781,8 @@
"git_remote_name": {
"type": "function",
"file": "remote.h",
- "line": 119,
- "lineto": 119,
+ "line": 117,
+ "lineto": 117,
"args": [
{
"name": "remote",
@@ -15785,8 +15803,8 @@
"git_remote_url": {
"type": "function",
"file": "remote.h",
- "line": 130,
- "lineto": 130,
+ "line": 128,
+ "lineto": 128,
"args": [
{
"name": "remote",
@@ -15812,8 +15830,8 @@
"git_remote_pushurl": {
"type": "function",
"file": "remote.h",
- "line": 141,
- "lineto": 141,
+ "line": 139,
+ "lineto": 139,
"args": [
{
"name": "remote",
@@ -15839,8 +15857,8 @@
"git_remote_set_url": {
"type": "function",
"file": "remote.h",
- "line": 154,
- "lineto": 154,
+ "line": 152,
+ "lineto": 152,
"args": [
{
"name": "repo",
@@ -15876,8 +15894,8 @@
"git_remote_set_pushurl": {
"type": "function",
"file": "remote.h",
- "line": 167,
- "lineto": 167,
+ "line": 165,
+ "lineto": 165,
"args": [
{
"name": "repo",
@@ -15913,8 +15931,8 @@
"git_remote_add_fetch": {
"type": "function",
"file": "remote.h",
- "line": 180,
- "lineto": 180,
+ "line": 178,
+ "lineto": 178,
"args": [
{
"name": "repo",
@@ -15945,8 +15963,8 @@
"git_remote_get_fetch_refspecs": {
"type": "function",
"file": "remote.h",
- "line": 191,
- "lineto": 191,
+ "line": 189,
+ "lineto": 189,
"args": [
{
"name": "array",
@@ -15972,8 +15990,8 @@
"git_remote_add_push": {
"type": "function",
"file": "remote.h",
- "line": 204,
- "lineto": 204,
+ "line": 202,
+ "lineto": 202,
"args": [
{
"name": "repo",
@@ -16004,8 +16022,8 @@
"git_remote_get_push_refspecs": {
"type": "function",
"file": "remote.h",
- "line": 215,
- "lineto": 215,
+ "line": 213,
+ "lineto": 213,
"args": [
{
"name": "array",
@@ -16031,8 +16049,8 @@
"git_remote_refspec_count": {
"type": "function",
"file": "remote.h",
- "line": 223,
- "lineto": 223,
+ "line": 221,
+ "lineto": 221,
"args": [
{
"name": "remote",
@@ -16053,8 +16071,8 @@
"git_remote_get_refspec": {
"type": "function",
"file": "remote.h",
- "line": 232,
- "lineto": 232,
+ "line": 230,
+ "lineto": 230,
"args": [
{
"name": "remote",
@@ -16080,8 +16098,8 @@
"git_remote_connect": {
"type": "function",
"file": "remote.h",
- "line": 249,
- "lineto": 249,
+ "line": 247,
+ "lineto": 247,
"args": [
{
"name": "remote",
@@ -16127,8 +16145,8 @@
"git_remote_ls": {
"type": "function",
"file": "remote.h",
- "line": 271,
- "lineto": 271,
+ "line": 269,
+ "lineto": 269,
"args": [
{
"name": "out",
@@ -16164,8 +16182,8 @@
"git_remote_connected": {
"type": "function",
"file": "remote.h",
- "line": 282,
- "lineto": 282,
+ "line": 280,
+ "lineto": 280,
"args": [
{
"name": "remote",
@@ -16186,8 +16204,8 @@
"git_remote_stop": {
"type": "function",
"file": "remote.h",
- "line": 292,
- "lineto": 292,
+ "line": 290,
+ "lineto": 290,
"args": [
{
"name": "remote",
@@ -16208,8 +16226,8 @@
"git_remote_disconnect": {
"type": "function",
"file": "remote.h",
- "line": 301,
- "lineto": 301,
+ "line": 299,
+ "lineto": 299,
"args": [
{
"name": "remote",
@@ -16230,8 +16248,8 @@
"git_remote_free": {
"type": "function",
"file": "remote.h",
- "line": 311,
- "lineto": 311,
+ "line": 309,
+ "lineto": 309,
"args": [
{
"name": "remote",
@@ -16264,8 +16282,8 @@
"git_remote_list": {
"type": "function",
"file": "remote.h",
- "line": 322,
- "lineto": 322,
+ "line": 320,
+ "lineto": 320,
"args": [
{
"name": "out",
@@ -16329,7 +16347,7 @@
{
"name": "opts",
"type": "git_fetch_options *",
- "comment": "the `git_push_options` instance to initialize."
+ "comment": "the `git_fetch_options` instance to initialize."
},
{
"name": "version",
@@ -16835,7 +16853,7 @@
"group": "repository",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_repository_open-60"
+ "ex/HEAD/general.html#git_repository_open-66"
],
"network/git2.c": [
"ex/HEAD/network/git2.html#git_repository_open-5"
@@ -17040,7 +17058,7 @@
"ex/HEAD/diff.html#git_repository_free-16"
],
"general.c": [
- "ex/HEAD/general.html#git_repository_free-61"
+ "ex/HEAD/general.html#git_repository_free-67"
],
"init.c": [
"ex/HEAD/init.html#git_repository_free-6"
@@ -17432,7 +17450,12 @@
},
"description": "Get a snapshot of the repository's configuration
\n",
"comments": "Convenience function to take a snapshot from the repository's configuration. The contents of this snapshot will not change, even if the underlying config files are modified.
\n\nThe configuration file must be freed once it's no longer being used by the user.
\n",
- "group": "repository"
+ "group": "repository",
+ "examples": {
+ "general.c": [
+ "ex/HEAD/general.html#git_repository_config_snapshot-68"
+ ]
+ }
},
"git_repository_odb": {
"type": "function",
@@ -17465,7 +17488,7 @@
"ex/HEAD/cat-file.html#git_repository_odb-33"
],
"general.c": [
- "ex/HEAD/general.html#git_repository_odb-62"
+ "ex/HEAD/general.html#git_repository_odb-69"
]
}
},
@@ -17524,7 +17547,7 @@
"group": "repository",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_repository_index-63"
+ "ex/HEAD/general.html#git_repository_index-70"
],
"init.c": [
"ex/HEAD/init.html#git_repository_index-11"
@@ -17992,7 +18015,7 @@
{
"name": "checkout_opts",
"type": "const git_checkout_options *",
- "comment": "Checkout options to be used for a HARD reset.\n The checkout_strategy field will be overridden (based on reset_type).\n This parameter can be used to propagate notify and progress callbacks."
+ "comment": "Optional checkout options to be used for a HARD reset.\n The checkout_strategy field will be overridden (based on reset_type).\n This parameter can be used to propagate notify and progress callbacks."
}
],
"argline": "git_repository *repo, git_object *target, git_reset_t reset_type, const git_checkout_options *checkout_opts",
@@ -18167,7 +18190,7 @@
{
"name": "given_opts",
"type": "const git_revert_options *",
- "comment": "merge flags"
+ "comment": "the revert options (or null for defaults)"
}
],
"argline": "git_repository *repo, git_commit *commit, const git_revert_options *given_opts",
@@ -18341,7 +18364,7 @@
"group": "revwalk",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_revwalk_new-64"
+ "ex/HEAD/general.html#git_revwalk_new-71"
],
"log.c": [
"ex/HEAD/log.html#git_revwalk_new-49",
@@ -18399,7 +18422,7 @@
"group": "revwalk",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_revwalk_push-65"
+ "ex/HEAD/general.html#git_revwalk_push-72"
],
"log.c": [
"ex/HEAD/log.html#git_revwalk_push-51"
@@ -18623,7 +18646,7 @@
"group": "revwalk",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_revwalk_next-66"
+ "ex/HEAD/general.html#git_revwalk_next-73"
],
"log.c": [
"ex/HEAD/log.html#git_revwalk_next-54"
@@ -18658,7 +18681,7 @@
"group": "revwalk",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_revwalk_sorting-67"
+ "ex/HEAD/general.html#git_revwalk_sorting-74"
],
"log.c": [
"ex/HEAD/log.html#git_revwalk_sorting-55",
@@ -18738,7 +18761,7 @@
"group": "revwalk",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_revwalk_free-68"
+ "ex/HEAD/general.html#git_revwalk_free-75"
],
"log.c": [
"ex/HEAD/log.html#git_revwalk_free-57"
@@ -18842,8 +18865,8 @@
"group": "signature",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_signature_new-69",
- "ex/HEAD/general.html#git_signature_new-70"
+ "ex/HEAD/general.html#git_signature_new-76",
+ "ex/HEAD/general.html#git_signature_new-77"
]
}
},
@@ -18990,6 +19013,10 @@
"comments": "Because the signature is not an opaque structure, it is legal to free it manually, but be sure to free the "name" and "email" strings in addition to the structure itself.
\n",
"group": "signature",
"examples": {
+ "general.c": [
+ "ex/HEAD/general.html#git_signature_free-78",
+ "ex/HEAD/general.html#git_signature_free-79"
+ ],
"init.c": [
"ex/HEAD/init.html#git_signature_free-13"
],
@@ -19471,7 +19498,7 @@
"group": "strarray",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_strarray_free-71"
+ "ex/HEAD/general.html#git_strarray_free-80"
],
"remote.c": [
"ex/HEAD/remote.html#git_strarray_free-16",
@@ -19512,8 +19539,8 @@
"git_submodule_update_init_options": {
"type": "function",
"file": "submodule.h",
- "line": 179,
- "lineto": 180,
+ "line": 170,
+ "lineto": 171,
"args": [
{
"name": "opts",
@@ -19539,8 +19566,8 @@
"git_submodule_update": {
"type": "function",
"file": "submodule.h",
- "line": 200,
- "lineto": 200,
+ "line": 191,
+ "lineto": 191,
"args": [
{
"name": "submodule",
@@ -19571,8 +19598,8 @@
"git_submodule_lookup": {
"type": "function",
"file": "submodule.h",
- "line": 229,
- "lineto": 232,
+ "line": 220,
+ "lineto": 223,
"args": [
{
"name": "out",
@@ -19603,8 +19630,8 @@
"git_submodule_free": {
"type": "function",
"file": "submodule.h",
- "line": 239,
- "lineto": 239,
+ "line": 230,
+ "lineto": 230,
"args": [
{
"name": "submodule",
@@ -19625,8 +19652,8 @@
"git_submodule_foreach": {
"type": "function",
"file": "submodule.h",
- "line": 259,
- "lineto": 262,
+ "line": 250,
+ "lineto": 253,
"args": [
{
"name": "repo",
@@ -19662,8 +19689,8 @@
"git_submodule_add_setup": {
"type": "function",
"file": "submodule.h",
- "line": 289,
- "lineto": 294,
+ "line": 280,
+ "lineto": 285,
"args": [
{
"name": "out",
@@ -19704,8 +19731,8 @@
"git_submodule_add_finalize": {
"type": "function",
"file": "submodule.h",
- "line": 306,
- "lineto": 306,
+ "line": 297,
+ "lineto": 297,
"args": [
{
"name": "submodule",
@@ -19726,8 +19753,8 @@
"git_submodule_add_to_index": {
"type": "function",
"file": "submodule.h",
- "line": 318,
- "lineto": 320,
+ "line": 309,
+ "lineto": 311,
"args": [
{
"name": "submodule",
@@ -19753,8 +19780,8 @@
"git_submodule_owner": {
"type": "function",
"file": "submodule.h",
- "line": 333,
- "lineto": 333,
+ "line": 324,
+ "lineto": 324,
"args": [
{
"name": "submodule",
@@ -19775,8 +19802,8 @@
"git_submodule_name": {
"type": "function",
"file": "submodule.h",
- "line": 341,
- "lineto": 341,
+ "line": 332,
+ "lineto": 332,
"args": [
{
"name": "submodule",
@@ -19802,8 +19829,8 @@
"git_submodule_path": {
"type": "function",
"file": "submodule.h",
- "line": 352,
- "lineto": 352,
+ "line": 343,
+ "lineto": 343,
"args": [
{
"name": "submodule",
@@ -19829,8 +19856,8 @@
"git_submodule_url": {
"type": "function",
"file": "submodule.h",
- "line": 360,
- "lineto": 360,
+ "line": 351,
+ "lineto": 351,
"args": [
{
"name": "submodule",
@@ -19851,8 +19878,8 @@
"git_submodule_resolve_url": {
"type": "function",
"file": "submodule.h",
- "line": 370,
- "lineto": 370,
+ "line": 361,
+ "lineto": 361,
"args": [
{
"name": "out",
@@ -19883,8 +19910,8 @@
"git_submodule_branch": {
"type": "function",
"file": "submodule.h",
- "line": 378,
- "lineto": 378,
+ "line": 369,
+ "lineto": 369,
"args": [
{
"name": "submodule",
@@ -19905,8 +19932,8 @@
"git_submodule_set_branch": {
"type": "function",
"file": "submodule.h",
- "line": 391,
- "lineto": 391,
+ "line": 382,
+ "lineto": 382,
"args": [
{
"name": "repo",
@@ -19937,8 +19964,8 @@
"git_submodule_set_url": {
"type": "function",
"file": "submodule.h",
- "line": 405,
- "lineto": 405,
+ "line": 396,
+ "lineto": 396,
"args": [
{
"name": "repo",
@@ -19969,8 +19996,8 @@
"git_submodule_index_id": {
"type": "function",
"file": "submodule.h",
- "line": 413,
- "lineto": 413,
+ "line": 404,
+ "lineto": 404,
"args": [
{
"name": "submodule",
@@ -19991,8 +20018,8 @@
"git_submodule_head_id": {
"type": "function",
"file": "submodule.h",
- "line": 421,
- "lineto": 421,
+ "line": 412,
+ "lineto": 412,
"args": [
{
"name": "submodule",
@@ -20013,8 +20040,8 @@
"git_submodule_wd_id": {
"type": "function",
"file": "submodule.h",
- "line": 434,
- "lineto": 434,
+ "line": 425,
+ "lineto": 425,
"args": [
{
"name": "submodule",
@@ -20035,8 +20062,8 @@
"git_submodule_ignore": {
"type": "function",
"file": "submodule.h",
- "line": 459,
- "lineto": 460,
+ "line": 450,
+ "lineto": 451,
"args": [
{
"name": "submodule",
@@ -20057,8 +20084,8 @@
"git_submodule_set_ignore": {
"type": "function",
"file": "submodule.h",
- "line": 472,
- "lineto": 475,
+ "line": 463,
+ "lineto": 466,
"args": [
{
"name": "repo",
@@ -20089,8 +20116,8 @@
"git_submodule_update_strategy": {
"type": "function",
"file": "submodule.h",
- "line": 487,
- "lineto": 488,
+ "line": 478,
+ "lineto": 479,
"args": [
{
"name": "submodule",
@@ -20111,8 +20138,8 @@
"git_submodule_set_update": {
"type": "function",
"file": "submodule.h",
- "line": 500,
- "lineto": 503,
+ "line": 491,
+ "lineto": 494,
"args": [
{
"name": "repo",
@@ -20143,8 +20170,8 @@
"git_submodule_fetch_recurse_submodules": {
"type": "function",
"file": "submodule.h",
- "line": 516,
- "lineto": 517,
+ "line": 507,
+ "lineto": 508,
"args": [
{
"name": "submodule",
@@ -20165,8 +20192,8 @@
"git_submodule_set_fetch_recurse_submodules": {
"type": "function",
"file": "submodule.h",
- "line": 529,
- "lineto": 532,
+ "line": 520,
+ "lineto": 523,
"args": [
{
"name": "repo",
@@ -20197,8 +20224,8 @@
"git_submodule_init": {
"type": "function",
"file": "submodule.h",
- "line": 547,
- "lineto": 547,
+ "line": 538,
+ "lineto": 538,
"args": [
{
"name": "submodule",
@@ -20224,8 +20251,8 @@
"git_submodule_repo_init": {
"type": "function",
"file": "submodule.h",
- "line": 562,
- "lineto": 565,
+ "line": 553,
+ "lineto": 556,
"args": [
{
"name": "out",
@@ -20256,8 +20283,8 @@
"git_submodule_sync": {
"type": "function",
"file": "submodule.h",
- "line": 575,
- "lineto": 575,
+ "line": 566,
+ "lineto": 566,
"args": [
{
"name": "submodule",
@@ -20278,8 +20305,8 @@
"git_submodule_open": {
"type": "function",
"file": "submodule.h",
- "line": 589,
- "lineto": 591,
+ "line": 580,
+ "lineto": 582,
"args": [
{
"name": "repo",
@@ -20305,8 +20332,8 @@
"git_submodule_reload": {
"type": "function",
"file": "submodule.h",
- "line": 603,
- "lineto": 603,
+ "line": 594,
+ "lineto": 594,
"args": [
{
"name": "submodule",
@@ -20332,8 +20359,8 @@
"git_submodule_status": {
"type": "function",
"file": "submodule.h",
- "line": 619,
- "lineto": 623,
+ "line": 610,
+ "lineto": 614,
"args": [
{
"name": "status",
@@ -20374,8 +20401,8 @@
"git_submodule_location": {
"type": "function",
"file": "submodule.h",
- "line": 639,
- "lineto": 641,
+ "line": 630,
+ "lineto": 632,
"args": [
{
"name": "location_status",
@@ -21569,6 +21596,50 @@
"comments": "Clear the working directory and set core.bare to true. You may also want to call git_repository_set_index(repo, NULL) since a bare repo typically does not have an index, but this function will not do that for you.
\n",
"group": "repository"
},
+ "git_repository_submodule_cache_all": {
+ "type": "function",
+ "file": "sys/repository.h",
+ "line": 149,
+ "lineto": 150,
+ "args": [
+ {
+ "name": "repo",
+ "type": "git_repository *",
+ "comment": "the repository whose submodules will be cached."
+ }
+ ],
+ "argline": "git_repository *repo",
+ "sig": "git_repository *",
+ "return": {
+ "type": "int",
+ "comment": null
+ },
+ "description": "Load and cache all submodules.
\n",
+ "comments": "Because the .gitmodules file is unstructured, loading submodules is an O(N) operation. Any operation (such as git_rebase_init) that requires accessing all submodules is O(N^2) in the number of submodules, if it has to look each one up individually. This function loads all submodules and caches them so that subsequent calls to git_submodule_lookup are O(1).
\n",
+ "group": "repository"
+ },
+ "git_repository_submodule_cache_clear": {
+ "type": "function",
+ "file": "sys/repository.h",
+ "line": 164,
+ "lineto": 165,
+ "args": [
+ {
+ "name": "repo",
+ "type": "git_repository *",
+ "comment": "the repository whose submodule cache will be cleared"
+ }
+ ],
+ "argline": "git_repository *repo",
+ "sig": "git_repository *",
+ "return": {
+ "type": "int",
+ "comment": null
+ },
+ "description": "Clear the submodule cache.
\n",
+ "comments": "Clear the submodule cache populated by git_repository_submodule_cache_all. If there is no cache, do nothing.
\n\nThe cache incorporates data from the repository's configuration, as well as the state of the working tree, the index, and HEAD. So any time any of these has changed, the cache might become invalid.
\n",
+ "group": "repository"
+ },
"git_stream_register_tls": {
"type": "function",
"file": "sys/stream.h",
@@ -21982,7 +22053,7 @@
"group": "tag",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_tag_lookup-72"
+ "ex/HEAD/general.html#git_tag_lookup-81"
]
}
},
@@ -22043,7 +22114,12 @@
},
"description": "Close an open tag
\n",
"comments": "You can no longer use the git_tag pointer after this call.
\n\nIMPORTANT: You MUST call this method when you are through with a tag to release memory. Failure to do so will cause a memory leak.
\n",
- "group": "tag"
+ "group": "tag",
+ "examples": {
+ "general.c": [
+ "ex/HEAD/general.html#git_tag_free-82"
+ ]
+ }
},
"git_tag_id": {
"type": "function",
@@ -22117,7 +22193,7 @@
"group": "tag",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_tag_target-73"
+ "ex/HEAD/general.html#git_tag_target-83"
]
}
},
@@ -22174,7 +22250,7 @@
"ex/HEAD/cat-file.html#git_tag_target_type-36"
],
"general.c": [
- "ex/HEAD/general.html#git_tag_target_type-74"
+ "ex/HEAD/general.html#git_tag_target_type-84"
]
}
},
@@ -22204,7 +22280,7 @@
"ex/HEAD/cat-file.html#git_tag_name-37"
],
"general.c": [
- "ex/HEAD/general.html#git_tag_name-75"
+ "ex/HEAD/general.html#git_tag_name-85"
],
"tag.c": [
"ex/HEAD/tag.html#git_tag_name-20"
@@ -22265,7 +22341,7 @@
"ex/HEAD/cat-file.html#git_tag_message-40"
],
"general.c": [
- "ex/HEAD/general.html#git_tag_message-76"
+ "ex/HEAD/general.html#git_tag_message-86"
],
"tag.c": [
"ex/HEAD/tag.html#git_tag_message-21"
@@ -23022,8 +23098,8 @@
"group": "tree",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_tree_lookup-77",
- "ex/HEAD/general.html#git_tree_lookup-78"
+ "ex/HEAD/general.html#git_tree_lookup-87",
+ "ex/HEAD/general.html#git_tree_lookup-88"
],
"init.c": [
"ex/HEAD/init.html#git_tree_lookup-14"
@@ -23093,6 +23169,10 @@
"ex/HEAD/diff.html#git_tree_free-17",
"ex/HEAD/diff.html#git_tree_free-18"
],
+ "general.c": [
+ "ex/HEAD/general.html#git_tree_free-89",
+ "ex/HEAD/general.html#git_tree_free-90"
+ ],
"init.c": [
"ex/HEAD/init.html#git_tree_free-15"
],
@@ -23175,7 +23255,7 @@
"ex/HEAD/cat-file.html#git_tree_entrycount-41"
],
"general.c": [
- "ex/HEAD/general.html#git_tree_entrycount-79"
+ "ex/HEAD/general.html#git_tree_entrycount-91"
]
}
},
@@ -23207,7 +23287,7 @@
"group": "tree",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_tree_entry_byname-80"
+ "ex/HEAD/general.html#git_tree_entry_byname-92"
]
}
},
@@ -23242,7 +23322,7 @@
"ex/HEAD/cat-file.html#git_tree_entry_byindex-42"
],
"general.c": [
- "ex/HEAD/general.html#git_tree_entry_byindex-81"
+ "ex/HEAD/general.html#git_tree_entry_byindex-93"
]
}
},
@@ -23380,8 +23460,8 @@
"ex/HEAD/cat-file.html#git_tree_entry_name-43"
],
"general.c": [
- "ex/HEAD/general.html#git_tree_entry_name-82",
- "ex/HEAD/general.html#git_tree_entry_name-83"
+ "ex/HEAD/general.html#git_tree_entry_name-94",
+ "ex/HEAD/general.html#git_tree_entry_name-95"
]
}
},
@@ -23548,7 +23628,7 @@
"group": "tree",
"examples": {
"general.c": [
- "ex/HEAD/general.html#git_tree_entry_to_object-84"
+ "ex/HEAD/general.html#git_tree_entry_to_object-96"
]
}
},
@@ -23805,11 +23885,43 @@
"comments": "The tree builder will be written to the given repo, and its identifying SHA1 hash will be stored in the id pointer.
\n",
"group": "treebuilder"
},
+ "git_treebuilder_write_with_buffer": {
+ "type": "function",
+ "file": "tree.h",
+ "line": 389,
+ "lineto": 390,
+ "args": [
+ {
+ "name": "oid",
+ "type": "git_oid *",
+ "comment": "Pointer to store the OID of the newly written tree"
+ },
+ {
+ "name": "bld",
+ "type": "git_treebuilder *",
+ "comment": "Tree builder to write"
+ },
+ {
+ "name": "tree",
+ "type": "git_buf *",
+ "comment": "Shared buffer for writing the tree. Will be grown as necessary."
+ }
+ ],
+ "argline": "git_oid *oid, git_treebuilder *bld, git_buf *tree",
+ "sig": "git_oid *::git_treebuilder *::git_buf *",
+ "return": {
+ "type": "int",
+ "comment": " 0 or an error code"
+ },
+ "description": "Write the contents of the tree builder as a tree object\n using a shared git_buf.
\n",
+ "comments": "",
+ "group": "treebuilder"
+ },
"git_tree_walk": {
"type": "function",
"file": "tree.h",
- "line": 406,
- "lineto": 410,
+ "line": 419,
+ "lineto": 423,
"args": [
{
"name": "tree",
@@ -23845,8 +23957,8 @@
"git_tree_dup": {
"type": "function",
"file": "tree.h",
- "line": 419,
- "lineto": 419,
+ "line": 432,
+ "lineto": 432,
"args": [
{
"name": "out",
@@ -23872,8 +23984,8 @@
"git_tree_create_updated": {
"type": "function",
"file": "tree.h",
- "line": 465,
- "lineto": 465,
+ "line": 478,
+ "lineto": 478,
"args": [
{
"name": "out",
@@ -24449,37 +24561,11 @@
"description": "Packbuilder progress notification function
\n",
"comments": ""
},
- "git_remote_rename_problem_cb": {
- "type": "callback",
- "file": "remote.h",
- "line": 29,
- "lineto": 29,
- "args": [
- {
- "name": "problematic_refspec",
- "type": "const char *",
- "comment": null
- },
- {
- "name": "payload",
- "type": "void *",
- "comment": null
- }
- ],
- "argline": "const char *problematic_refspec, void *payload",
- "sig": "const char *::void *",
- "return": {
- "type": "int",
- "comment": null
- },
- "description": "git2/remote.h
\n",
- "comments": "@{
\n"
- },
"git_push_transfer_progress": {
"type": "callback",
"file": "remote.h",
- "line": 335,
- "lineto": 339,
+ "line": 333,
+ "lineto": 337,
"args": [
{
"name": "current",
@@ -24539,7 +24625,7 @@
"type": "int",
"comment": null
},
- "description": "",
+ "description": "Callback used to inform of upcoming updates.
\n",
"comments": ""
},
"git_revwalk_hide_cb": {
@@ -25052,8 +25138,8 @@
"git_treewalk_cb": {
"type": "callback",
"file": "tree.h",
- "line": 380,
- "lineto": 381,
+ "line": 393,
+ "lineto": 394,
"args": [
{
"name": "root",
@@ -25642,7 +25728,8 @@
"git_remote_default_branch",
"git_repository_discover",
"git_repository_message",
- "git_submodule_resolve_url"
+ "git_submodule_resolve_url",
+ "git_treebuilder_write_with_buffer"
]
}
}
@@ -27440,17 +27527,17 @@
{
"type": "unsigned int",
"name": "max_candidates_tags",
- "comments": ""
+ "comments": " default: 10 "
},
{
"type": "unsigned int",
"name": "describe_strategy",
- "comments": " default: 10 "
+ "comments": " default: GIT_DESCRIBE_DEFAULT "
},
{
"type": "const char *",
"name": "pattern",
- "comments": " default: GIT_DESCRIBE_DEFAULT "
+ "comments": ""
},
{
"type": "int",
@@ -27472,6 +27559,29 @@
}
}
],
+ [
+ "git_describe_result",
+ {
+ "decl": "git_describe_result",
+ "type": "struct",
+ "value": "git_describe_result",
+ "file": "describe.h",
+ "line": 111,
+ "lineto": 111,
+ "tdef": "typedef",
+ "description": " A struct that stores the result of a describe operation.",
+ "comments": "",
+ "used": {
+ "returns": [],
+ "needs": [
+ "git_describe_commit",
+ "git_describe_format",
+ "git_describe_result_free",
+ "git_describe_workdir"
+ ]
+ }
+ }
+ ],
[
"git_describe_strategy_t",
{
@@ -29558,7 +29668,7 @@
"type": "enum",
"file": "common.h",
"line": 111,
- "lineto": 116,
+ "lineto": 134,
"block": "GIT_FEATURE_THREADS\nGIT_FEATURE_HTTPS\nGIT_FEATURE_SSH\nGIT_FEATURE_NSEC",
"tdef": "typedef",
"description": " Combinations of these values describe the features with which libgit2\n was compiled",
@@ -29567,25 +29677,25 @@
{
"type": "int",
"name": "GIT_FEATURE_THREADS",
- "comments": "",
+ "comments": "If set, libgit2 was built thread-aware and can be safely used from multiple\n threads.
\n",
"value": 1
},
{
"type": "int",
"name": "GIT_FEATURE_HTTPS",
- "comments": "",
+ "comments": "If set, libgit2 was built with and linked against a TLS implementation.\n Custom TLS streams may still be added by the user to support HTTPS\n regardless of this.
\n",
"value": 2
},
{
"type": "int",
"name": "GIT_FEATURE_SSH",
- "comments": "",
+ "comments": "If set, libgit2 was built with and linked against libssh2. A custom\n transport may still be added by the user to support libssh2 regardless of\n this.
\n",
"value": 4
},
{
"type": "int",
"name": "GIT_FEATURE_NSEC",
- "comments": "",
+ "comments": "If set, libgit2 was built with support for sub-second resolution in file\n modification times.
\n",
"value": 8
}
],
@@ -30564,14 +30674,15 @@
"GIT_OPT_SET_SSL_CERT_LOCATIONS",
"GIT_OPT_SET_USER_AGENT",
"GIT_OPT_ENABLE_STRICT_OBJECT_CREATION",
+ "GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION",
"GIT_OPT_SET_SSL_CIPHERS",
"GIT_OPT_GET_USER_AGENT"
],
"type": "enum",
"file": "common.h",
- "line": 144,
- "lineto": 162,
- "block": "GIT_OPT_GET_MWINDOW_SIZE\nGIT_OPT_SET_MWINDOW_SIZE\nGIT_OPT_GET_MWINDOW_MAPPED_LIMIT\nGIT_OPT_SET_MWINDOW_MAPPED_LIMIT\nGIT_OPT_GET_SEARCH_PATH\nGIT_OPT_SET_SEARCH_PATH\nGIT_OPT_SET_CACHE_OBJECT_LIMIT\nGIT_OPT_SET_CACHE_MAX_SIZE\nGIT_OPT_ENABLE_CACHING\nGIT_OPT_GET_CACHED_MEMORY\nGIT_OPT_GET_TEMPLATE_PATH\nGIT_OPT_SET_TEMPLATE_PATH\nGIT_OPT_SET_SSL_CERT_LOCATIONS\nGIT_OPT_SET_USER_AGENT\nGIT_OPT_ENABLE_STRICT_OBJECT_CREATION\nGIT_OPT_SET_SSL_CIPHERS\nGIT_OPT_GET_USER_AGENT",
+ "line": 162,
+ "lineto": 181,
+ "block": "GIT_OPT_GET_MWINDOW_SIZE\nGIT_OPT_SET_MWINDOW_SIZE\nGIT_OPT_GET_MWINDOW_MAPPED_LIMIT\nGIT_OPT_SET_MWINDOW_MAPPED_LIMIT\nGIT_OPT_GET_SEARCH_PATH\nGIT_OPT_SET_SEARCH_PATH\nGIT_OPT_SET_CACHE_OBJECT_LIMIT\nGIT_OPT_SET_CACHE_MAX_SIZE\nGIT_OPT_ENABLE_CACHING\nGIT_OPT_GET_CACHED_MEMORY\nGIT_OPT_GET_TEMPLATE_PATH\nGIT_OPT_SET_TEMPLATE_PATH\nGIT_OPT_SET_SSL_CERT_LOCATIONS\nGIT_OPT_SET_USER_AGENT\nGIT_OPT_ENABLE_STRICT_OBJECT_CREATION\nGIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION\nGIT_OPT_SET_SSL_CIPHERS\nGIT_OPT_GET_USER_AGENT",
"tdef": "typedef",
"description": " Global library options",
"comments": "These are used to select which global option to set or get and are used in git_libgit2_opts().
\n",
@@ -30668,15 +30779,21 @@
},
{
"type": "int",
- "name": "GIT_OPT_SET_SSL_CIPHERS",
+ "name": "GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION",
"comments": "",
"value": 15
},
{
"type": "int",
- "name": "GIT_OPT_GET_USER_AGENT",
+ "name": "GIT_OPT_SET_SSL_CIPHERS",
"comments": "",
"value": 16
+ },
+ {
+ "type": "int",
+ "name": "GIT_OPT_GET_USER_AGENT",
+ "comments": "",
+ "value": 17
}
],
"used": {
@@ -30697,8 +30814,8 @@
],
"type": "enum",
"file": "merge.h",
- "line": 311,
- "lineto": 340,
+ "line": 312,
+ "lineto": 341,
"block": "GIT_MERGE_ANALYSIS_NONE\nGIT_MERGE_ANALYSIS_NORMAL\nGIT_MERGE_ANALYSIS_UP_TO_DATE\nGIT_MERGE_ANALYSIS_FASTFORWARD\nGIT_MERGE_ANALYSIS_UNBORN",
"tdef": "typedef",
"description": " The results of `git_merge_analysis` indicate the merge opportunities.",
@@ -31259,8 +31376,8 @@
],
"type": "enum",
"file": "merge.h",
- "line": 345,
- "lineto": 363,
+ "line": 346,
+ "lineto": 364,
"block": "GIT_MERGE_PREFERENCE_NONE\nGIT_MERGE_PREFERENCE_NO_FASTFORWARD\nGIT_MERGE_PREFERENCE_FASTFORWARD_ONLY",
"tdef": "typedef",
"description": " The user's stated preference for merges.",
@@ -31937,7 +32054,8 @@
"git_tree_lookup",
"git_tree_lookup_prefix",
"git_treebuilder_insert",
- "git_treebuilder_write"
+ "git_treebuilder_write",
+ "git_treebuilder_write_with_buffer"
]
}
}
@@ -31949,8 +32067,8 @@
"type": "struct",
"value": "git_oid_shorten",
"file": "oid.h",
- "line": 216,
- "lineto": 216,
+ "line": 215,
+ "lineto": 215,
"tdef": "typedef",
"description": " OID Shortener object",
"comments": "",
@@ -32428,7 +32546,7 @@
{
"type": "int",
"name": "GIT_PROXY_NONE",
- "comments": "Do not attempt to connect through a proxy
\n\nIf built against lbicurl, it itself may attempt to connect\n to a proxy if the environment variables specify it.
\n",
+ "comments": "Do not attempt to connect through a proxy
\n\nIf built against libcurl, it itself may attempt to connect\n to a proxy if the environment variables specify it.
\n",
"value": 0
},
{
@@ -32541,8 +32659,8 @@
"type": "struct",
"value": "git_push_update",
"file": "remote.h",
- "line": 343,
- "lineto": 360,
+ "line": 341,
+ "lineto": 358,
"block": "char * src_refname\nchar * dst_refname\ngit_oid src\ngit_oid dst",
"tdef": "typedef",
"description": " Represents an update which will be performed on the remote during push",
@@ -33357,8 +33475,8 @@
],
"type": "enum",
"file": "remote.h",
- "line": 328,
- "lineto": 332,
+ "line": 326,
+ "lineto": 330,
"block": "GIT_REMOTE_COMPLETION_DOWNLOAD\nGIT_REMOTE_COMPLETION_INDEXING\nGIT_REMOTE_COMPLETION_ERROR\nGIT_REMOTE_COMPLETION_DOWNLOAD\nGIT_REMOTE_COMPLETION_INDEXING\nGIT_REMOTE_COMPLETION_ERROR",
"tdef": "typedef",
"description": " Argument to the completion callback which tells it which operation\n finished.",
@@ -33624,6 +33742,8 @@
"git_repository_set_workdir",
"git_repository_state",
"git_repository_state_cleanup",
+ "git_repository_submodule_cache_all",
+ "git_repository_submodule_cache_clear",
"git_repository_workdir",
"git_repository_wrap_odb",
"git_reset",
@@ -35219,15 +35339,14 @@
"unsigned int version",
"git_checkout_options checkout_opts",
"git_fetch_options fetch_opts",
- "unsigned int clone_checkout_strategy",
"int allow_fetch"
],
"type": "struct",
"value": "git_submodule_update_options",
"file": "submodule.h",
"line": 129,
- "lineto": 163,
- "block": "unsigned int version\ngit_checkout_options checkout_opts\ngit_fetch_options fetch_opts\nunsigned int clone_checkout_strategy\nint allow_fetch",
+ "lineto": 154,
+ "block": "unsigned int version\ngit_checkout_options checkout_opts\ngit_fetch_options fetch_opts\nint allow_fetch",
"tdef": "typedef",
"description": " Submodule update options structure",
"comments": "Use the GIT_SUBMODULE_UPDATE_OPTIONS_INIT to get the default settings, like this:
\n\ngit_submodule_update_options opts = GIT_SUBMODULE_UPDATE_OPTIONS_INIT;
\n",
@@ -35240,18 +35359,13 @@
{
"type": "git_checkout_options",
"name": "checkout_opts",
- "comments": " These options are passed to the checkout step. To disable\n checkout, set the `checkout_strategy` to\n `GIT_CHECKOUT_NONE`. Generally you will want the use\n GIT_CHECKOUT_SAFE to update files in the working\n directory. Use the `clone_checkout_strategy` field\n to set the checkout strategy that will be used in\n the case where update needs to clone the repository."
+ "comments": " These options are passed to the checkout step. To disable\n checkout, set the `checkout_strategy` to\n `GIT_CHECKOUT_NONE`. Generally you will want the use\n GIT_CHECKOUT_SAFE to update files in the working\n directory. "
},
{
"type": "git_fetch_options",
"name": "fetch_opts",
"comments": " Options which control the fetch, including callbacks.\n\n The callbacks to use for reporting fetch progress, and for acquiring\n credentials in the event they are needed."
},
- {
- "type": "unsigned int",
- "name": "clone_checkout_strategy",
- "comments": " The checkout strategy to use when the sub repository needs to\n be cloned. Use GIT_CHECKOUT_SAFE to create all files\n in the working directory for the newly cloned repository."
- },
{
"type": "int",
"name": "allow_fetch",
@@ -35686,6 +35800,7 @@
"git_treebuilder_new",
"git_treebuilder_remove",
"git_treebuilder_write",
+ "git_treebuilder_write_with_buffer",
"git_treewalk_cb"
]
}
@@ -35740,8 +35855,8 @@
"type": "struct",
"value": "git_tree_update",
"file": "tree.h",
- "line": 434,
- "lineto": 443,
+ "line": 447,
+ "lineto": 456,
"block": "git_tree_update_t action\ngit_oid id\ngit_filemode_t filemode\nconst char * path",
"tdef": "typedef",
"description": " An action to perform during the update of a tree",
@@ -35785,8 +35900,8 @@
],
"type": "enum",
"file": "tree.h",
- "line": 424,
- "lineto": 429,
+ "line": 437,
+ "lineto": 442,
"block": "GIT_TREE_UPDATE_UPSERT\nGIT_TREE_UPDATE_REMOVE",
"tdef": "typedef",
"description": " The kind of update to perform",
@@ -35834,7 +35949,8 @@
"git_treebuilder_insert",
"git_treebuilder_new",
"git_treebuilder_remove",
- "git_treebuilder_write"
+ "git_treebuilder_write",
+ "git_treebuilder_write_with_buffer"
]
}
}
@@ -35848,8 +35964,8 @@
],
"type": "enum",
"file": "tree.h",
- "line": 384,
- "lineto": 387,
+ "line": 397,
+ "lineto": 400,
"block": "GIT_TREEWALK_PRE\nGIT_TREEWALK_POST",
"tdef": "typedef",
"description": " Tree traversal modes ",
@@ -36703,6 +36819,8 @@
"git_repository_set_workdir",
"git_repository_state",
"git_repository_state_cleanup",
+ "git_repository_submodule_cache_all",
+ "git_repository_submodule_cache_clear",
"git_repository_workdir",
"git_repository_wrap_odb"
]
@@ -36936,7 +37054,8 @@
"git_treebuilder_insert",
"git_treebuilder_new",
"git_treebuilder_remove",
- "git_treebuilder_write"
+ "git_treebuilder_write",
+ "git_treebuilder_write_with_buffer"
]
]
],
@@ -37030,4 +37149,4 @@
"ex/HEAD/tag.html"
]
]
-}
+}
\ No newline at end of file
diff --git a/generate/input/libgit2-supplement.json b/generate/input/libgit2-supplement.json
index b686795c3..52bb45651 100644
--- a/generate/input/libgit2-supplement.json
+++ b/generate/input/libgit2-supplement.json
@@ -126,6 +126,28 @@
},
"group": "rebase"
},
+ "git_remote_reference_list": {
+ "args": [
+ {
+ "name": "out",
+ "type": "std::vector *"
+ },
+ {
+ "name": "remote",
+ "type": "git_remote *"
+ }
+ ],
+ "type": "function",
+ "isManual": true,
+ "cFile": "generate/templates/manual/remote/ls.cc",
+ "isAsync": true,
+ "isPrototypeMethod": true,
+ "group": "remote",
+ "return": {
+ "type": "int",
+ "isErrorCode": true
+ }
+ },
"git_reset": {
"type": "function",
"file": "reset.h",
@@ -277,6 +299,12 @@
"git_reflog_entry_message"
]
],
+ [
+ "remote",
+ [
+ "git_remote_reference_list"
+ ]
+ ],
[
"revwalk",
[
@@ -614,6 +642,39 @@
}
}
],
+ [
+ "git_remote_head",
+ {
+ "types": "struct",
+ "fields": [
+ {
+ "type": "int",
+ "name": "local"
+ },
+ {
+ "type": "git_oid",
+ "name": "oid"
+ },
+ {
+ "type": "git_oid",
+ "name": "loid"
+ },
+ {
+ "type": "char *",
+ "name": "name"
+ },
+ {
+ "type": "char *",
+ "name": "symref_target"
+ }
+ ],
+ "used": {
+ "needs": [
+ "git_remote_reference_list"
+ ]
+ }
+ }
+ ],
[
"git_time_t",
{
diff --git a/generate/scripts/generateJson.js b/generate/scripts/generateJson.js
index f1afeb956..323247e13 100644
--- a/generate/scripts/generateJson.js
+++ b/generate/scripts/generateJson.js
@@ -231,8 +231,7 @@ module.exports = function generateJson() {
}
- utils.writeFile("output/idefs.json", output);
-
+ utils.writeLocalFile("output/idefs.json", output);
};
if (require.main === module) {
diff --git a/generate/scripts/generateMissingTests.js b/generate/scripts/generateMissingTests.js
index 4aef70f4d..29b6474b3 100644
--- a/generate/scripts/generateMissingTests.js
+++ b/generate/scripts/generateMissingTests.js
@@ -12,7 +12,7 @@ module.exports = function generateMissingTests() {
var testFilePath = path.join(testFilesPath, idef.filename + ".js");
var result = {};
- var file = utils.readFile(testFilePath);
+ var file = utils.readLocalFile(testFilePath);
if (file) {
var fieldsResult = [];
var functionsResult = [];
@@ -58,7 +58,7 @@ module.exports = function generateMissingTests() {
Promise.all(promises).then(
function() {
- utils.writeFile("output/missing-tests.json", output);
+ utils.writeLocalFile("/output/missing-tests.json", output);
},
function(fail) {
console.error(fail);
diff --git a/generate/scripts/generateNativeCode.js b/generate/scripts/generateNativeCode.js
index 56d52672c..a82bef4e5 100644
--- a/generate/scripts/generateNativeCode.js
+++ b/generate/scripts/generateNativeCode.js
@@ -1,6 +1,7 @@
const path = require("path");
const promisify = require("promisify-node");
const fse = promisify(require("fs-extra"));
+const os = require('os');
const exec = require('../../utils/execPromise');
const utils = require("./utils");
@@ -24,27 +25,27 @@ module.exports = function generateNativeCode() {
};
var partials = {
- asyncFunction: utils.readFile("templates/partials/async_function.cc"),
- callbackHelpers: utils.readFile("templates/partials/callback_helpers.cc"),
- convertFromV8: utils.readFile("templates/partials/convert_from_v8.cc"),
- convertToV8: utils.readFile("templates/partials/convert_to_v8.cc"),
- doc: utils.readFile("templates/partials/doc.cc"),
- fields: utils.readFile("templates/partials/fields.cc"),
- guardArguments: utils.readFile("templates/partials/guard_arguments.cc"),
- syncFunction: utils.readFile("templates/partials/sync_function.cc"),
- fieldAccessors: utils.readFile("templates/partials/field_accessors.cc"),
- traits: utils.readFile("templates/partials/traits.h")
+ asyncFunction: utils.readLocalFile("templates/partials/async_function.cc"),
+ callbackHelpers: utils.readLocalFile("templates/partials/callback_helpers.cc"),
+ convertFromV8: utils.readLocalFile("templates/partials/convert_from_v8.cc"),
+ convertToV8: utils.readLocalFile("templates/partials/convert_to_v8.cc"),
+ doc: utils.readLocalFile("templates/partials/doc.cc"),
+ fields: utils.readLocalFile("templates/partials/fields.cc"),
+ guardArguments: utils.readLocalFile("templates/partials/guard_arguments.cc"),
+ syncFunction: utils.readLocalFile("templates/partials/sync_function.cc"),
+ fieldAccessors: utils.readLocalFile("templates/partials/field_accessors.cc"),
+ traits: utils.readLocalFile("templates/partials/traits.h")
};
var templates = {
- class_content: utils.readFile("templates/templates/class_content.cc"),
- struct_content: utils.readFile("templates/templates/struct_content.cc"),
- class_header: utils.readFile("templates/templates/class_header.h"),
- struct_header: utils.readFile("templates/templates/struct_header.h"),
- binding: utils.readFile("templates/templates/binding.gyp"),
- nodegitCC: utils.readFile("templates/templates/nodegit.cc"),
- nodegitJS: utils.readFile("templates/templates/nodegit.js"),
- enums: utils.readFile("templates/templates/enums.js")
+ class_content: utils.readLocalFile("templates/templates/class_content.cc"),
+ struct_content: utils.readLocalFile("templates/templates/struct_content.cc"),
+ class_header: utils.readLocalFile("templates/templates/class_header.h"),
+ struct_header: utils.readLocalFile("templates/templates/struct_header.h"),
+ binding: utils.readLocalFile("templates/templates/binding.gyp"),
+ nodegitCC: utils.readLocalFile("templates/templates/nodegit.cc"),
+ nodegitJS: utils.readLocalFile("templates/templates/nodegit.js"),
+ enums: utils.readLocalFile("templates/templates/enums.js")
};
var filters = {
@@ -99,51 +100,63 @@ module.exports = function generateNativeCode() {
return !idef.ignore;
});
+ const tempDirPath = path.join(os.tmpdir(), 'nodegit_build');
+ const tempSrcDirPath = path.join(tempDirPath, "src");
+ const tempIncludeDirPath = path.join(tempDirPath, "include");
- fse.remove(path.resolve(__dirname, "../../src")).then(function() {
- return fse.remove(path.resolve(__dirname, "../../include"));
- }).then(function() {
- return fse.copy(path.resolve(__dirname, "../templates/manual/include"), path.resolve(__dirname, "../../include"));
+ const finalSrcDirPath = path.join(__dirname, '../../src');
+ const finalIncludeDirPath = path.join(__dirname, '../../include');
+
+ fse.remove(tempDirPath).then(function() {
+ return fse.copy(path.resolve(__dirname, "../templates/manual/include"), tempIncludeDirPath);
}).then(function() {
- return fse.copy(path.resolve(__dirname, "../templates/manual/src"), path.resolve(__dirname, "../../src"));
+ return fse.copy(path.resolve(__dirname, "../templates/manual/src"), tempSrcDirPath);
}).then(function() {
// Write out single purpose templates.
- utils.writeFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
- utils.writeFile("../src/nodegit.cc", templates.nodegitCC.render(enabled), "nodegit.cc");
- utils.writeFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
+ utils.writeLocalFile("../binding.gyp", beautify(templates.binding.render(enabled)), "binding.gyp");
+ utils.writeFile(path.join(tempSrcDirPath, "nodegit.cc"), templates.nodegitCC.render(enabled), "nodegit.cc");
+ utils.writeLocalFile("../lib/nodegit.js", beautify(templates.nodegitJS.render(enabled)), "nodegit.js");
// Write out all the classes.
enabled.forEach(function(idef) {
if (idef.type && idef.type != "enum") {
utils.writeFile(
- "../src/" + idef.filename + ".cc",
+ path.join(tempSrcDirPath, idef.filename + ".cc"),
templates[idef.type + "_content"].render(idef),
idef.type + "_content.cc"
);
+
utils.writeFile(
- "../include/" + idef.filename + ".h",
+ path.join(tempIncludeDirPath, idef.filename + ".h"),
templates[idef.type + "_header"].render(idef),
idef.type + "_header.h"
);
}
});
- utils.writeFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
+ utils.writeLocalFile("../lib/enums.js", beautify(templates.enums.render(enabled)), "enums.js");
}).then(function() {
return exec("command -v astyle").then(function(astyle) {
if (astyle) {
return exec(
"astyle --options=\".astylerc\" "
- + path.resolve(__dirname, "../../src") + "/*.cc "
- + path.resolve(__dirname, "../../include") + "/*.h"
+ + tempSrcDirPath + "/*.cc "
+ + tempIncludeDirPath + "/*.h"
).then(function() {
return exec(
"rm "
- + path.resolve(__dirname, "../../src") + "/*.cc.orig "
- + path.resolve(__dirname, "../../include") + "/*.h.orig "
+ + tempSrcDirPath + "/*.cc.orig "
+ + tempIncludeDirPath + "/*.h.orig "
);
});
}
}, function() {})
+ }).then(function() {
+ return Promise.all([
+ utils.syncDirs(tempSrcDirPath, finalSrcDirPath),
+ utils.syncDirs(tempIncludeDirPath, finalIncludeDirPath),
+ ]);
+ }).then(function() {
+ return fse.remove(tempDirPath);
}).catch(console.log);
};
diff --git a/generate/scripts/utils.js b/generate/scripts/utils.js
index 6868bf653..2771c9ced 100644
--- a/generate/scripts/utils.js
+++ b/generate/scripts/utils.js
@@ -1,4 +1,5 @@
const fse = require("fs-extra");
+const walk = require("walk");
const fs = require("fs");
const path = require("path");
@@ -10,18 +11,25 @@ var util = {
pointerRegex: /\s*\*\s*/,
doublePointerRegex: /\s*\*\*\s*/,
- readFile: function(file) {
+ readLocalFile: function(filePath) {
+ return util.readFile(local(filePath));
+ },
+
+ readFile: function(filePath) {
try {
- return fs.readFileSync(local(file)).toString();
+ return fs.readFileSync(filePath).toString();
}
catch (unhandledException) {
return "";
}
},
- writeFile: function(file, content, header) {
+ writeLocalFile: function(filePath, content, header) {
+ return util.writeFile(local(filePath), content, header);
+ },
+
+ writeFile: function(filePath, content, header) {
try {
- var file = local(file);
if (typeof content == "object") {
content = JSON.stringify(content, null, 2)
}
@@ -29,14 +37,14 @@ var util = {
if (header) {
var commentPrefix = ~header.indexOf('.gyp') ? '#' : '//'
content = commentPrefix +
- " This is a generated file, modify: generate/templates/" +
+ " This is a generated file, modify: generate/templates/templates/" +
header +
"\n\n" +
content;
}
- fse.ensureFileSync(file);
- fse.writeFileSync(file, content);
+ fse.ensureFileSync(filePath);
+ fse.writeFileSync(filePath, content);
return true;
}
catch (exception) {
@@ -62,14 +70,84 @@ var util = {
}).join("");
},
+ getFilePathsRelativeToDir: function(dir) {
+ const files = [];
+ const walker = walk.walk(dir, { followLinks: false });
+ if (!util.isDirectory(dir)) {
+ return Promise.resolve([]);
+ }
+
+ return new Promise(function(resolve, reject) {
+ walker.on('file', function(root, stat, next) {
+ files.push(path.relative(dir, path.join(root, stat.name)));
+ next();
+ });
+
+ walker.on('end', function() {
+ resolve(files);
+ });
+
+ walker.on('errors', function() {
+ reject();
+ });
+ });
+ },
+
+ isFile: function(path) {
+ var isFile;
+ try {
+ isFile = fse.statSync(path).isFile();
+ } catch(e) {
+ isFile = false;
+ }
+
+ return isFile;
+ },
+
+ isDirectory: function(path) {
+ var isDirectory;
+ try {
+ isDirectory = fse.statSync(path).isDirectory();
+ } catch(e) {
+ isDirectory = false;
+ }
+
+ return isDirectory;
+ },
+
isPointer: function(type) {
return util.pointerRegex.test(type) || util.doublePointerRegex.test(type);
},
isDoublePointer: function(type) {
return util.doublePointerRegex.test(type);
- }
+ },
+ syncDirs: function(fromDir, toDir) {
+ return Promise.all([
+ util.getFilePathsRelativeToDir(toDir),
+ util.getFilePathsRelativeToDir(fromDir)
+ ]).then(function(filePaths) {
+ const toFilePaths = filePaths[0];
+ const fromFilePaths = filePaths[1];
+
+ // Delete files that aren't in fromDir
+ toFilePaths.forEach(function(filePath) {
+ if (!util.isFile(path.join(fromDir, filePath))) {
+ fse.remove(path.join(toDir, filePath));
+ }
+ });
+
+ // Copy files that don't exist in toDir or have different contents
+ fromFilePaths.forEach(function(filePath) {
+ const toFilePath = path.join(toDir, filePath);
+ const fromFilePath = path.join(fromDir, filePath);
+ if (!util.isFile(toFilePath) || util.readFile(toFilePath) !== util.readFile(fromFilePath)) {
+ fse.copy(fromFilePath, toFilePath);
+ }
+ });
+ });
+ }
};
module.exports = util;
diff --git a/generate/templates/manual/include/async_baton.h b/generate/templates/manual/include/async_baton.h
index cfae13b31..5f6874102 100644
--- a/generate/templates/manual/include/async_baton.h
+++ b/generate/templates/manual/include/async_baton.h
@@ -12,37 +12,48 @@
// or field properties of configuration objects whose values are callbacks)
struct AsyncBaton {
uv_sem_t semaphore;
+
+ virtual ~AsyncBaton() {}
};
+void deleteBaton(AsyncBaton *baton);
+
template
struct AsyncBatonWithResult : public AsyncBaton {
ResultT result;
ResultT defaultResult; // result returned if the callback doesn't return anything valid
+ void (*onCompletion)(AsyncBaton *);
AsyncBatonWithResult(const ResultT &defaultResult)
: defaultResult(defaultResult) {
- uv_sem_init(&semaphore, 0);
- }
-
- ~AsyncBatonWithResult() {
- uv_sem_destroy(&semaphore);
}
void Done() {
- // signal completion
- uv_sem_post(&semaphore);
+ if (onCompletion) {
+ onCompletion(this);
+ } else {
+ // signal completion
+ uv_sem_post(&semaphore);
+ }
}
- ResultT ExecuteAsync(ThreadPool::Callback asyncCallback) {
+ ResultT ExecuteAsync(ThreadPool::Callback asyncCallback, void (*onCompletion)(AsyncBaton *) = NULL) {
result = 0;
+ this->onCompletion = onCompletion;
+ if (!onCompletion) {
+ uv_sem_init(&semaphore, 0);
+ }
{
LockMaster::TemporaryUnlock temporaryUnlock;
libgit2ThreadPool.ExecuteReverseCallback(asyncCallback, this);
- // wait for completion
- uv_sem_wait(&semaphore);
+ if (!onCompletion) {
+ // wait for completion
+ uv_sem_wait(&semaphore);
+ uv_sem_destroy(&semaphore);
+ }
}
return result;
diff --git a/generate/templates/manual/include/callback_wrapper.h b/generate/templates/manual/include/callback_wrapper.h
index b23a7bb36..0f655ed18 100644
--- a/generate/templates/manual/include/callback_wrapper.h
+++ b/generate/templates/manual/include/callback_wrapper.h
@@ -14,6 +14,11 @@ class CallbackWrapper {
int throttle; // in milliseconds - if > 0, calls to the JS callback will be throttled
uint64_t lastCallTime;
+ // false will trigger the callback and not wait for the callback to finish
+ // in this case, the underlying libgit2 function will immediately be given
+ // the default result
+ bool waitForResult;
+
public:
CallbackWrapper() {
jsCallback = NULL;
@@ -33,12 +38,17 @@ class CallbackWrapper {
return jsCallback;
}
- void SetCallback(Nan::Callback* callback, int throttle = 0) {
+ void SetCallback(Nan::Callback* callback, int throttle = 0, bool waitForResult = true) {
if(jsCallback) {
delete jsCallback;
}
jsCallback = callback;
this->throttle = throttle;
+ this->waitForResult = waitForResult;
+ }
+
+ bool ShouldWaitForResult() {
+ return waitForResult;
}
bool WillBeThrottled() {
@@ -47,7 +57,7 @@ class CallbackWrapper {
}
// throttle if needed
uint64_t now = uv_hrtime();
- if(lastCallTime > 0 && now < lastCallTime + throttle * 1000000) {
+ if(lastCallTime > 0 && now < lastCallTime + throttle * (uint64_t)1000000) {
// throttled
return true;
} else {
diff --git a/generate/templates/manual/include/convenient_hunk.h b/generate/templates/manual/include/convenient_hunk.h
index 63d77d900..37e9ab111 100644
--- a/generate/templates/manual/include/convenient_hunk.h
+++ b/generate/templates/manual/include/convenient_hunk.h
@@ -27,9 +27,9 @@ using namespace v8;
class ConvenientHunk : public Nan::ObjectWrap {
public:
static Nan::Persistent constructor_template;
- static void InitializeComponent (Local target);
+ static void InitializeComponent (v8::Local target);
- static Local New(void *raw);
+ static v8::Local New(void *raw);
HunkData *GetValue();
char *GetHeader();
diff --git a/generate/templates/manual/include/convenient_patch.h b/generate/templates/manual/include/convenient_patch.h
index d6f6c69a1..9d6921ef8 100644
--- a/generate/templates/manual/include/convenient_patch.h
+++ b/generate/templates/manual/include/convenient_patch.h
@@ -38,9 +38,9 @@ using namespace v8;
class ConvenientPatch : public Nan::ObjectWrap {
public:
static Nan::Persistent constructor_template;
- static void InitializeComponent (Local target);
+ static void InitializeComponent (v8::Local target);
- static Local New(void *raw);
+ static v8::Local New(void *raw);
ConvenientLineStats GetLineStats();
git_delta_t GetStatus();
diff --git a/generate/templates/manual/include/functions/copy.h b/generate/templates/manual/include/functions/copy.h
index f7f942475..9983e575a 100644
--- a/generate/templates/manual/include/functions/copy.h
+++ b/generate/templates/manual/include/functions/copy.h
@@ -14,6 +14,8 @@ const git_index_time *git_index_time_dup(const git_index_time *arg);
const git_time *git_time_dup(const git_time *arg);
const git_diff_delta *git_diff_delta_dup(const git_diff_delta *arg);
const git_diff_file *git_diff_file_dup(const git_diff_file *arg);
+git_remote_head *git_remote_head_dup(const git_remote_head *src);
+
void git_time_dup(git_time **out, const git_time *arg);
void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_progress *arg);
diff --git a/generate/templates/manual/include/functions/free.h b/generate/templates/manual/include/functions/free.h
new file mode 100644
index 000000000..873417b98
--- /dev/null
+++ b/generate/templates/manual/include/functions/free.h
@@ -0,0 +1,12 @@
+#include
+
+#include
+
+#include "git2.h"
+
+#ifndef NODEGIT_FREE_FUNCTIONS
+#define NODEGIT_FREE_FUNCTIONS
+
+void git_remote_head_free(git_remote_head *remote_head);
+
+#endif
diff --git a/generate/templates/manual/include/git_buf_converter.h b/generate/templates/manual/include/git_buf_converter.h
index e2ea08bba..fcbd1eaba 100644
--- a/generate/templates/manual/include/git_buf_converter.h
+++ b/generate/templates/manual/include/git_buf_converter.h
@@ -10,7 +10,7 @@ using namespace v8;
class StrArrayConverter {
public:
- static git_strarray *Convert (Local val);
+ static git_strarray *Convert (v8::Local val);
};
#endif
diff --git a/generate/templates/manual/include/str_array_converter.h b/generate/templates/manual/include/str_array_converter.h
index c3509f128..37f1bcc1d 100644
--- a/generate/templates/manual/include/str_array_converter.h
+++ b/generate/templates/manual/include/str_array_converter.h
@@ -11,11 +11,11 @@ using namespace v8;
class StrArrayConverter {
public:
- static git_strarray *Convert (Local val);
+ static git_strarray *Convert (v8::Local val);
private:
static git_strarray *ConvertArray(Array *val);
- static git_strarray *ConvertString(Local val);
+ static git_strarray *ConvertString(v8::Local val);
static git_strarray *AllocStrArray(const size_t count);
static git_strarray *ConstructStrArray(int argc, char** argv);
};
diff --git a/generate/templates/manual/include/thread_pool.h b/generate/templates/manual/include/thread_pool.h
index a1eeabbfd..8a346028d 100644
--- a/generate/templates/manual/include/thread_pool.h
+++ b/generate/templates/manual/include/thread_pool.h
@@ -19,12 +19,13 @@ class ThreadPool {
}
};
- struct ReverseCall {
- Callback reverseCallback;
+ struct LoopCallback {
+ Callback callback;
void *data;
+ bool isWork;
- ReverseCall(Callback reverseCallback, void *data)
- : reverseCallback(reverseCallback), data(data) {
+ LoopCallback(Callback callback, void *data, bool isWork)
+ : callback(callback), data(data), isWork(isWork) {
}
};
@@ -34,22 +35,17 @@ class ThreadPool {
uv_sem_t workSemaphore;
int workInProgressCount;
- // completion callbacks to be performed on the loop
- std::queue completionQueue;
- uv_mutex_t completionMutex;
- uv_async_t completionAsync;
-
- // async callback made from the threadpool, executed in the loop
- std::queue reverseQueue;
- uv_mutex_t reverseMutex;
- uv_async_t reverseAsync;
+ // completion and async 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 RunCompletionCallbacks(uv_async_t* handle);
- void RunCompletionCallbacks();
- static void RunReverseCallbacks(uv_async_t *handle);
- void RunReverseCallbacks();
+ static void RunLoopCallbacks(uv_async_t* handle);
+ void RunLoopCallbacks();
+
+ void QueueLoopCallback(Callback callback, void *data, bool isWork);
public:
// Initializes thread pool and spins up the requested number of threads
@@ -61,7 +57,6 @@ class ThreadPool {
// QueueWork should be called on the loop provided in the constructor.
void QueueWork(Callback workCallback, Callback completionCallback, void *data);
// Queues a callback on the loop provided in the constructor
- // these block the calling thread's execution until the callback completes
void ExecuteReverseCallback(Callback reverseCallback, void *data);
};
diff --git a/generate/templates/manual/include/wrapper.h b/generate/templates/manual/include/wrapper.h
index c040ea64d..9dcbe3186 100644
--- a/generate/templates/manual/include/wrapper.h
+++ b/generate/templates/manual/include/wrapper.h
@@ -17,10 +17,10 @@ class Wrapper : public Nan::ObjectWrap {
public:
static Nan::Persistent constructor_template;
- static void InitializeComponent (Local target);
+ static void InitializeComponent (v8::Local target);
void *GetValue();
- static Local New(const void *raw);
+ static v8::Local New(const void *raw);
private:
Wrapper(void *raw);
diff --git a/generate/templates/manual/patches/convenient_patches.cc b/generate/templates/manual/patches/convenient_patches.cc
index 79823e37a..27de54fcf 100644
--- a/generate/templates/manual/patches/convenient_patches.cc
+++ b/generate/templates/manual/patches/convenient_patches.cc
@@ -95,8 +95,15 @@ void GitPatch::ConvenientFromDiffWorker::HandleOKCallback() {
}
if (baton->error) {
+ Local err;
+ if (baton->error->message) {
+ err = Nan::Error(baton->error->message)->ToObject();
+ } else {
+ err = Nan::Error("Method convenientFromDiff has thrown an error.")->ToObject();
+ }
+ err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Local argv[1] = {
- Nan::Error(baton->error->message)
+ err
};
callback->Call(1, argv);
if (baton->error->message)
diff --git a/generate/templates/manual/remote/ls.cc b/generate/templates/manual/remote/ls.cc
new file mode 100644
index 000000000..d426d6f79
--- /dev/null
+++ b/generate/templates/manual/remote/ls.cc
@@ -0,0 +1,99 @@
+NAN_METHOD(GitRemote::ReferenceList)
+{
+ if (info.Length() == 0 || !info[0]->IsFunction()) {
+ return Nan::ThrowError("Callback is required and must be a Function.");
+ }
+
+ ReferenceListBaton* baton = new ReferenceListBaton;
+
+ baton->error_code = GIT_OK;
+ baton->error = NULL;
+ baton->out = new std::vector;
+ baton->remote = Nan::ObjectWrap::Unwrap(info.This())->GetValue();
+
+ Nan::Callback *callback = new Nan::Callback(Local::Cast(info[0]));
+ ReferenceListWorker *worker = new ReferenceListWorker(baton, callback);
+ worker->SaveToPersistent("remote", info.This());
+ Nan::AsyncQueueWorker(worker);
+ return;
+}
+
+void GitRemote::ReferenceListWorker::Execute()
+{
+ giterr_clear();
+
+ {
+ LockMaster lockMaster(
+ /*asyncAction: */true,
+ baton->remote
+ );
+
+ const git_remote_head **remote_heads;
+ size_t num_remote_heads;
+ baton->error_code = git_remote_ls(
+ &remote_heads,
+ &num_remote_heads,
+ baton->remote
+ );
+
+ if (baton->error_code != GIT_OK) {
+ baton->error = git_error_dup(giterr_last());
+ delete baton->out;
+ baton->out = NULL;
+ return;
+ }
+
+ baton->out->reserve(num_remote_heads);
+
+ for (size_t head_index = 0; head_index < num_remote_heads; ++head_index) {
+ git_remote_head *remote_head = git_remote_head_dup(remote_heads[head_index]);
+ baton->out->push_back(remote_head);
+ }
+ }
+}
+
+void GitRemote::ReferenceListWorker::HandleOKCallback()
+{
+ if (baton->out != NULL)
+ {
+ 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), GitRemoteHead::New(baton->out->at(i), true));
+ }
+
+ delete baton->out;
+
+ Local argv[2] = {
+ Nan::Null(),
+ result
+ };
+ callback->Call(2, argv);
+ }
+ else if (baton->error)
+ {
+ Local argv[1] = {
+ Nan::Error(baton->error->message)
+ };
+ callback->Call(1, argv);
+ if (baton->error->message)
+ {
+ free((void *)baton->error->message);
+ }
+
+ free((void *)baton->error);
+ }
+ else if (baton->error_code < 0)
+ {
+ Local err = Nan::Error("Reference List has thrown an error.")->ToObject();
+ err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
+ Local argv[1] = {
+ err
+ };
+ callback->Call(1, argv);
+ }
+ else
+ {
+ callback->Call(0, NULL);
+ }
+}
diff --git a/generate/templates/manual/revwalk/fast_walk.cc b/generate/templates/manual/revwalk/fast_walk.cc
index 2f263f83f..ec3a10cd7 100644
--- a/generate/templates/manual/revwalk/fast_walk.cc
+++ b/generate/templates/manual/revwalk/fast_walk.cc
@@ -88,8 +88,15 @@ void GitRevwalk::FastWalkWorker::HandleOKCallback()
{
if (baton->error)
{
+ Local err;
+ if (baton->error->message) {
+ err = Nan::Error(baton->error->message)->ToObject();
+ } else {
+ err = Nan::Error("Method fastWalk has thrown an error.")->ToObject();
+ }
+ err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Local argv[1] = {
- Nan::Error(baton->error->message)
+ err
};
callback->Call(1, argv);
if (baton->error->message)
diff --git a/generate/templates/manual/revwalk/file_history_walk.cc b/generate/templates/manual/revwalk/file_history_walk.cc
index 0f511969f..220482679 100644
--- a/generate/templates/manual/revwalk/file_history_walk.cc
+++ b/generate/templates/manual/revwalk/file_history_walk.cc
@@ -289,8 +289,15 @@ void GitRevwalk::FileHistoryWalkWorker::HandleOKCallback()
}
if (baton->error) {
+ Local err;
+ if (baton->error->message) {
+ err = Nan::Error(baton->error->message)->ToObject();
+ } else {
+ err = Nan::Error("Method fileHistoryWalk has thrown an error.")->ToObject();
+ }
+ err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
Local argv[1] = {
- Nan::Error(baton->error->message)
+ err
};
callback->Call(1, argv);
if (baton->error->message)
diff --git a/generate/templates/manual/src/async_baton.cc b/generate/templates/manual/src/async_baton.cc
new file mode 100644
index 000000000..590a19c62
--- /dev/null
+++ b/generate/templates/manual/src/async_baton.cc
@@ -0,0 +1,5 @@
+#include "../include/async_baton.h"
+
+void deleteBaton(AsyncBaton *baton) {
+ delete baton;
+}
diff --git a/generate/templates/manual/src/functions/copy.cc b/generate/templates/manual/src/functions/copy.cc
index f09f2cbaa..90327650b 100644
--- a/generate/templates/manual/src/functions/copy.cc
+++ b/generate/templates/manual/src/functions/copy.cc
@@ -20,3 +20,18 @@ void git_transfer_progress_dup(git_transfer_progress **out, const git_transfer_p
*out = (git_transfer_progress *)malloc(sizeof(git_transfer_progress));
memcpy(*out, arg, sizeof(git_transfer_progress));
}
+
+git_remote_head *git_remote_head_dup(const git_remote_head *src) {
+ git_remote_head *dest = (git_remote_head *)malloc(sizeof(git_remote_head));
+ dest->local = src->local;
+ git_oid_cpy(&dest->oid, &src->oid);
+ git_oid_cpy(&dest->loid, &src->loid);
+
+ dest->name = src->name
+ ? strdup(src->name)
+ : NULL;
+ dest->symref_target = src->symref_target
+ ? strdup(src->symref_target)
+ : NULL;
+ return dest;
+}
diff --git a/generate/templates/manual/src/functions/free.cc b/generate/templates/manual/src/functions/free.cc
new file mode 100644
index 000000000..a52a7016f
--- /dev/null
+++ b/generate/templates/manual/src/functions/free.cc
@@ -0,0 +1,9 @@
+#include
+
+#include "git2.h"
+
+void git_remote_head_free(git_remote_head *remote_head) {
+ free(remote_head->name);
+ free(remote_head->symref_target);
+ free(remote_head);
+}
diff --git a/generate/templates/manual/src/thread_pool.cc b/generate/templates/manual/src/thread_pool.cc
index d8bedc96e..7eadf0421 100644
--- a/generate/templates/manual/src/thread_pool.cc
+++ b/generate/templates/manual/src/thread_pool.cc
@@ -4,15 +4,10 @@ ThreadPool::ThreadPool(int numberOfThreads, uv_loop_t *loop) {
uv_mutex_init(&workMutex);
uv_sem_init(&workSemaphore, 0);
- uv_async_init(loop, &completionAsync, RunCompletionCallbacks);
- completionAsync.data = this;
- uv_unref((uv_handle_t *)&completionAsync);
- uv_mutex_init(&completionMutex);
-
- uv_async_init(loop, &reverseAsync, RunReverseCallbacks);
- reverseAsync.data = this;
- uv_unref((uv_handle_t *)&reverseAsync);
- uv_mutex_init(&reverseMutex);
+ uv_async_init(loop, &loopAsync, RunLoopCallbacks);
+ loopAsync.data = this;
+ uv_unref((uv_handle_t *)&loopAsync);
+ uv_mutex_init(&loopMutex);
workInProgressCount = 0;
@@ -26,25 +21,29 @@ void ThreadPool::QueueWork(Callback workCallback, Callback completionCallback, v
uv_mutex_lock(&workMutex);
// there is work on the thread pool - reference the handle so
// node doesn't terminate
- uv_ref((uv_handle_t *)&completionAsync);
+ uv_ref((uv_handle_t *)&loopAsync);
workQueue.push(Work(workCallback, completionCallback, data));
workInProgressCount++;
uv_mutex_unlock(&workMutex);
uv_sem_post(&workSemaphore);
}
-void ThreadPool::ExecuteReverseCallback(Callback reverseCallback, void *data) {
+void ThreadPool::QueueLoopCallback(Callback callback, void *data, bool isWork) {
// push the callback into the queue
- uv_mutex_lock(&reverseMutex);
- ReverseCall reverseCall(reverseCallback, data);
- bool queueWasEmpty = reverseQueue.empty();
- reverseQueue.push(reverseCall);
- // we only trigger RunReverseCallbacks via the reverseAsync handle if the queue
- // was empty. Otherwise, we depend on RunReverseCallbacks to re-trigger itself
+ uv_mutex_lock(&loopMutex);
+ LoopCallback loopCallback(callback, data, isWork);
+ bool queueWasEmpty = loopQueue.empty();
+ loopQueue.push(loopCallback);
+ // we only trigger RunLoopCallbacks via the loopAsync handle if the queue
+ // was empty. Otherwise, we depend on RunLoopCallbacks to re-trigger itself
if (queueWasEmpty) {
- uv_async_send(&reverseAsync);
+ uv_async_send(&loopAsync);
}
- uv_mutex_unlock(&reverseMutex);
+ uv_mutex_unlock(&loopMutex);
+}
+
+void ThreadPool::ExecuteReverseCallback(Callback reverseCallback, void *data) {
+ QueueLoopCallback(reverseCallback, data, false);
}
void ThreadPool::RunEventQueue(void *threadPool) {
@@ -64,63 +63,40 @@ void ThreadPool::RunEventQueue() {
// perform the queued work
(*work.workCallback)(work.data);
- // schedule the callback on the loop
- uv_mutex_lock(&completionMutex);
- completionQueue.push(work);
- uv_mutex_unlock(&completionMutex);
- uv_async_send(&completionAsync);
+ // schedule the completion callback on the loop
+ QueueLoopCallback(work.completionCallback, work.data, true);
}
}
-void ThreadPool::RunCompletionCallbacks(uv_async_t* handle) {
- static_cast(handle->data)->RunCompletionCallbacks();
+void ThreadPool::RunLoopCallbacks(uv_async_t* handle) {
+ static_cast(handle->data)->RunLoopCallbacks();
}
-void ThreadPool::RunCompletionCallbacks() {
- // uv_async_send can coalesce calls, so we are not guaranteed one
- // RunCompletionCallbacks per uv_async_send call
- // so we always process the entire completionQueue
- int callbacksCompleted = 0;
- uv_mutex_lock(&completionMutex);
- while(!completionQueue.empty()) {
- Work work = completionQueue.front();
- completionQueue.pop();
- uv_mutex_unlock(&completionMutex);
- // perform the queued loop callback
- (*work.completionCallback)(work.data);
- callbacksCompleted++;
- uv_mutex_lock(&completionMutex);
+void ThreadPool::RunLoopCallbacks() {
+ // get the next callback to run
+ uv_mutex_lock(&loopMutex);
+ LoopCallback loopCallback = loopQueue.front();
+ uv_mutex_unlock(&loopMutex);
+
+ // perform the queued loop callback
+ (*loopCallback.callback)(loopCallback.data);
+
+ // pop the queue, and if necessary, re-trigger RunLoopCallbacks
+ uv_mutex_lock(&loopMutex);
+ loopQueue.pop();
+ if (!loopQueue.empty()) {
+ uv_async_send(&loopAsync);
}
- uv_mutex_unlock(&completionMutex);
+ 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 *)&completionAsync);
- }
- uv_mutex_unlock(&workMutex);
-}
-
-void ThreadPool::RunReverseCallbacks(uv_async_t* handle) {
- static_cast(handle->data)->RunReverseCallbacks();
-}
-
-void ThreadPool::RunReverseCallbacks() {
- // get the next callback to run
- uv_mutex_lock(&reverseMutex);
- ReverseCall reverseCall = reverseQueue.front();
- uv_mutex_unlock(&reverseMutex);
-
- // execute callback
- (*reverseCall.reverseCallback)(reverseCall.data);
-
- // pop the queue, and if necessary, re-trigger RunReverseCallbacks
- uv_mutex_lock(&reverseMutex);
- reverseQueue.pop();
- if (!reverseQueue.empty()) {
- uv_async_send(&reverseAsync);
+ if (loopCallback.isWork) {
+ uv_mutex_lock(&workMutex);
+ workInProgressCount --;
+ if(!workInProgressCount) {
+ uv_unref((uv_handle_t *)&loopAsync);
+ }
+ uv_mutex_unlock(&workMutex);
}
- uv_mutex_unlock(&reverseMutex);
}
diff --git a/generate/templates/partials/async_function.cc b/generate/templates/partials/async_function.cc
index 3d3227d4a..b8e19ddb0 100644
--- a/generate/templates/partials/async_function.cc
+++ b/generate/templates/partials/async_function.cc
@@ -61,7 +61,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) {
{%endif%}
{%endeach%}
- Nan::Callback *callback = new Nan::Callback(Local::Cast(info[{{args|jsArgsCount}}]));
+ Nan::Callback *callback = new Nan::Callback(v8::Local::Cast(info[{{args|jsArgsCount}}]));
{{ cppFunctionName }}Worker *worker = new {{ cppFunctionName }}Worker(baton, callback);
{%each args|argsInfo as arg %}
{%if not arg.isReturn %}
@@ -129,14 +129,14 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
if (baton->error_code == GIT_OK) {
{%endif%}
{%if return.isResultOrError %}
- Local result = Nan::New(baton->error_code);
+ v8::Local result = Nan::New(baton->error_code);
{%elsif not .|returnsCount %}
- Local result = Nan::Undefined();
+ v8::Local result = Nan::Undefined();
{%else%}
- Local to;
+ v8::Local to;
{%if .|returnsCount > 1 %}
- Local result = Nan::New();
+ v8::Local result = Nan::New();
{%endif%}
{%each .|returnsInfo 0 1 as _return %}
{%partial convertToV8 _return %}
@@ -145,25 +145,32 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
{%endif%}
{%endeach%}
{%if .|returnsCount == 1 %}
- Local result = to;
+ v8::Local result = to;
{%endif%}
{%endif%}
- Local argv[2] = {
+ v8::Local argv[2] = {
Nan::Null(),
result
};
callback->Call(2, argv);
} else {
if (baton->error) {
- Local argv[1] = {
- Nan::Error(baton->error->message)
+ v8::Local err;
+ if (baton->error->message) {
+ err = Nan::Error(baton->error->message)->ToObject();
+ } else {
+ err = Nan::Error("Method {{ jsFunctionName }} has thrown an error.")->ToObject();
+ }
+ err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
+ v8::Local argv[1] = {
+ err
};
callback->Call(1, argv);
if (baton->error->message)
free((void *)baton->error->message);
free((void *)baton->error);
} else if (baton->error_code < 0) {
- std::queue< Local > workerArguments;
+ std::queue< v8::Local > workerArguments;
{%each args|argsInfo as arg %}
{%if not arg.isReturn %}
{%if not arg.isSelf %}
@@ -175,7 +182,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
{%endeach%}
bool callbackFired = false;
while(!workerArguments.empty()) {
- Local node = workerArguments.front();
+ v8::Local node = workerArguments.front();
workerArguments.pop();
if (
@@ -191,11 +198,11 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
continue;
}
- Local nodeObj = node->ToObject();
- Local checkValue = GetPrivate(nodeObj, Nan::New("NodeGitPromiseError").ToLocalChecked());
+ v8::Local nodeObj = node->ToObject();
+ v8::Local checkValue = GetPrivate(nodeObj, Nan::New("NodeGitPromiseError").ToLocalChecked());
if (!checkValue.IsEmpty() && !checkValue->IsNull() && !checkValue->IsUndefined()) {
- Local argv[1] = {
+ v8::Local argv[1] = {
checkValue->ToObject()
};
callback->Call(1, argv);
@@ -203,10 +210,10 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
break;
}
- Local properties = nodeObj->GetPropertyNames();
+ v8::Local properties = nodeObj->GetPropertyNames();
for (unsigned int propIndex = 0; propIndex < properties->Length(); ++propIndex) {
- Local propName = properties->Get(propIndex)->ToString();
- Local nodeToQueue = nodeObj->Get(propName);
+ v8::Local propName = properties->Get(propIndex)->ToString();
+ v8::Local nodeToQueue = nodeObj->Get(propName);
if (!nodeToQueue->IsUndefined()) {
workerArguments.push(nodeToQueue);
}
@@ -214,9 +221,9 @@ void {{ cppClassName }}::{{ cppFunctionName }}Worker::HandleOKCallback() {
}
if (!callbackFired) {
- Local err = Nan::Error("Method {{ jsFunctionName }} has thrown an error.")->ToObject();
+ v8::Local err = Nan::Error("Method {{ jsFunctionName }} has thrown an error.")->ToObject();
err->Set(Nan::New("errno").ToLocalChecked(), Nan::New(baton->error_code));
- Local argv[1] = {
+ v8::Local argv[1] = {
err
};
callback->Call(1, argv);
diff --git a/generate/templates/partials/callback_helpers.cc b/generate/templates/partials/callback_helpers.cc
index acd44f424..c1d0ab74a 100644
--- a/generate/templates/partials/callback_helpers.cc
+++ b/generate/templates/partials/callback_helpers.cc
@@ -30,7 +30,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_async(void
{% endif %}
{% endeach %}
- Local argv[{{ cbFunction.args|jsArgsCount }}] = {
+ v8::Local argv[{{ cbFunction.args|jsArgsCount }}] = {
{% each cbFunction.args|argsInfo as arg %}
{% if arg | isPayload %}
{%-- payload is always the last arg --%}
@@ -54,7 +54,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_async(void
};
Nan::TryCatch tryCatch;
- Local result = callback->Call({{ cbFunction.args|jsArgsCount }}, argv);
+ v8::Local result = callback->Call({{ cbFunction.args|jsArgsCount }}, argv);
if(PromiseCompletion::ForwardIfPromise(result, baton, {{ cppFunctionName }}_{{ cbFunction.name }}_promiseCompleted)) {
return;
@@ -124,7 +124,7 @@ void {{ cppClassName }}::{{ cppFunctionName }}_{{ cbFunction.name }}_promiseComp
{{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each cbFunction.args|argsInfo as arg %}
{% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %}
{% endeach %});
- Local parent = instance->handle();
+ v8::Local parent = instance->handle();
SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result);
baton->result = {{ cbFunction.return.error }};
diff --git a/generate/templates/partials/convert_from_v8.cc b/generate/templates/partials/convert_from_v8.cc
index 425e691f4..f7c4da469 100644
--- a/generate/templates/partials/convert_from_v8.cc
+++ b/generate/templates/partials/convert_from_v8.cc
@@ -1,6 +1,12 @@
{%if not isPayload %}
// start convert_from_v8 block
+ {%if cType|isPointer %}
+ {{ cType }} from_{{ name }} = NULL;
+ {%elsif cType|isDoublePointer %}
+ {{ cType }} from_{{ name }} = NULL;
+ {%else%}
{{ cType }} from_{{ name }};
+ {%endif%}
{%if isOptional | or isBoolean %}
{%if cppClassName == 'GitStrarray'%}
diff --git a/generate/templates/partials/convert_to_v8.cc b/generate/templates/partials/convert_to_v8.cc
index d9b1d8830..bfe268f3e 100644
--- a/generate/templates/partials/convert_to_v8.cc
+++ b/generate/templates/partials/convert_to_v8.cc
@@ -33,12 +33,12 @@
{%-- // FIXME this is not general purpose enough. --%}
{% if size %}
- Local tmpArray = Nan::New({{= parsedName =}}->{{ size }});
+ v8::Local tmpArray = Nan::New({{= parsedName =}}->{{ size }});
for (unsigned int i = 0; i < {{= parsedName =}}->{{ size }}; i++) {
Nan::Set(tmpArray, Nan::New(i), Nan::New({{= parsedName =}}->{{ key }}[i]).ToLocalChecked());
}
{% else %}
- Local tmpArray = Nan::New({{= parsedName =}});
+ v8::Local tmpArray = Nan::New({{= parsedName =}});
{% endif %}
to = tmpArray;
diff --git a/generate/templates/partials/field_accessors.cc b/generate/templates/partials/field_accessors.cc
index f9f9065a0..ea5bb5db1 100644
--- a/generate/templates/partials/field_accessors.cc
+++ b/generate/templates/partials/field_accessors.cc
@@ -39,7 +39,7 @@
}
{% elsif field.isLibgitType %}
- Local {{ field.name }}(value->ToObject());
+ v8::Local {{ field.name }}(value->ToObject());
wrapper->{{ field.name }}.Reset({{ field.name }});
@@ -48,24 +48,32 @@
{% elsif field.isCallbackFunction %}
Nan::Callback *callback = NULL;
int throttle = {%if field.return.throttle %}{{ field.return.throttle }}{%else%}0{%endif%};
+ bool waitForResult = true;
if (value->IsFunction()) {
callback = new Nan::Callback(value.As());
} else if (value->IsObject()) {
- Local object = value.As();
- Local callbackKey;
+ v8::Local object = value.As();
+ v8::Local callbackKey;
Nan::MaybeLocal maybeObjectCallback = Nan::Get(object, Nan::New("callback").ToLocalChecked());
if (!maybeObjectCallback.IsEmpty()) {
- Local objectCallback = maybeObjectCallback.ToLocalChecked();
+ v8::Local objectCallback = maybeObjectCallback.ToLocalChecked();
if (objectCallback->IsFunction()) {
callback = new Nan::Callback(objectCallback.As());
+
Nan::MaybeLocal maybeObjectThrottle = Nan::Get(object, Nan::New("throttle").ToLocalChecked());
if(!maybeObjectThrottle.IsEmpty()) {
- Local objectThrottle = maybeObjectThrottle.ToLocalChecked();
+ v8::Local objectThrottle = maybeObjectThrottle.ToLocalChecked();
if (objectThrottle->IsNumber()) {
throttle = (int)objectThrottle.As()->Value();
}
}
+
+ Nan::MaybeLocal maybeObjectWaitForResult = Nan::Get(object, Nan::New("waitForResult").ToLocalChecked());
+ if(!maybeObjectWaitForResult.IsEmpty()) {
+ Local objectWaitForResult = maybeObjectWaitForResult.ToLocalChecked();
+ waitForResult = (bool)objectWaitForResult->BooleanValue();
+ }
}
}
}
@@ -74,7 +82,7 @@
wrapper->raw->{{ field.name }} = ({{ field.cType }}){{ field.name }}_cppCallback;
}
- wrapper->{{ field.name }}.SetCallback(callback, throttle);
+ wrapper->{{ field.name }}.SetCallback(callback, throttle, waitForResult);
}
{% elsif field.payloadFor %}
@@ -111,19 +119,28 @@
{{ arg.cType }} {{ arg.name}}{% if not arg.lastArg %},{% endif %}
{% endeach %}
) {
- {{ field.name|titleCase }}Baton baton({{ field.return.noResults }});
+ {{ field.name|titleCase }}Baton *baton =
+ new {{ field.name|titleCase }}Baton({{ field.return.noResults }});
{% each field.args|argsInfo as arg %}
- baton.{{ arg.name }} = {{ arg.name }};
+ baton->{{ arg.name }} = {{ arg.name }};
{% endeach %}
- {{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(&baton);
+ {{ cppClassName }}* instance = {{ field.name }}_getInstanceFromBaton(baton);
+
+ {{ field.return.type }} result;
if (instance->{{ field.name }}.WillBeThrottled()) {
- return baton.defaultResult;
+ result = baton->defaultResult;
+ delete baton;
+ } else if (instance->{{ field.name }}.ShouldWaitForResult()) {
+ result = baton->ExecuteAsync({{ field.name }}_async);
+ delete baton;
+ } else {
+ result = baton->defaultResult;
+ baton->ExecuteAsync({{ field.name }}_async, deleteBaton);
}
-
- return baton.ExecuteAsync({{ field.name }}_async);
+ return result;
}
void {{ cppClassName }}::{{ field.name }}_async(void *untypedBaton) {
@@ -153,7 +170,7 @@
{% endif %}
{% endeach %}
- Local argv[{{ field.args|jsArgsCount }}] = {
+ v8::Local argv[{{ field.args|jsArgsCount }}] = {
{% each field.args|argsInfo as arg %}
{% if arg.name == "payload" %}
{%-- payload is always the last arg --%}
@@ -176,7 +193,7 @@
};
Nan::TryCatch tryCatch;
- Local result = instance->{{ field.name }}.GetCallback()->Call({{ field.args|jsArgsCount }}, argv);
+ v8::Local result = instance->{{ field.name }}.GetCallback()->Call({{ field.args|jsArgsCount }}, argv);
if(PromiseCompletion::ForwardIfPromise(result, baton, {{ cppClassName }}::{{ field.name }}_promiseCompleted)) {
return;
@@ -245,7 +262,7 @@
{{ cppClassName }}* instance = static_cast<{{ cppClassName }}*>(baton->{% each field.args|argsInfo as arg %}
{% if arg.payload == true %}{{arg.name}}{% elsif arg.lastArg %}{{arg.name}}{% endif %}
{% endeach %});
- Local parent = instance->handle();
+ v8::Local parent = instance->handle();
SetPrivate(parent, Nan::New("NodeGitPromiseError").ToLocalChecked(), result);
baton->result = {{ field.return.error }};
diff --git a/generate/templates/partials/fields.cc b/generate/templates/partials/fields.cc
index ae3aeae44..9d6e6e39d 100644
--- a/generate/templates/partials/fields.cc
+++ b/generate/templates/partials/fields.cc
@@ -1,7 +1,7 @@
{% each fields|fieldsInfo as field %}
{% if not field.ignore %}
NAN_METHOD({{ cppClassName }}::{{ field.cppFunctionName }}) {
- Local to;
+ v8::Local to;
{% if field | isFixedLengthString %}
char* {{ field.name }} = (char *)Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This())->GetValue()->{{ field.name }};
diff --git a/generate/templates/partials/sync_function.cc b/generate/templates/partials/sync_function.cc
index d53a5c2d0..c07c77b51 100644
--- a/generate/templates/partials/sync_function.cc
+++ b/generate/templates/partials/sync_function.cc
@@ -17,7 +17,7 @@ NAN_METHOD({{ cppClassName }}::{{ cppFunctionName }}) {
{%if not arg.isReturn %}
{%partial convertFromV8 arg %}
{%if arg.saveArg %}
- Local {{ arg.name }}(info[{{ arg.jsArg }}]->ToObject());
+ v8::Local {{ arg.name }}(info[{{ arg.jsArg }}]->ToObject());
{{ cppClassName }} *thisObj = Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This());
thisObj->{{ cppFunctionName }}_{{ arg.name }}.Reset({{ arg.name }});
@@ -108,9 +108,9 @@ if (Nan::ObjectWrap::Unwrap<{{ cppClassName }}>(info.This())->GetValue() != NULL
}
{%endif%}
- Local to;
+ v8::Local to;
{%if .|returnsCount > 1 %}
- Local toReturn = Nan::New();
+ v8::Local toReturn = Nan::New();
{%endif%}
{%each .|returnsInfo as _return %}
{%partial convertToV8 _return %}
diff --git a/generate/templates/templates/binding.gyp b/generate/templates/templates/binding.gyp
index ece88cd15..69e2042ad 100644
--- a/generate/templates/templates/binding.gyp
+++ b/generate/templates/templates/binding.gyp
@@ -12,12 +12,14 @@
},
"sources": [
+ "src/async_baton.cc",
"src/lock_master.cc",
"src/nodegit.cc",
"src/init_ssh2.cc",
"src/promise_completion.cc",
"src/wrapper.cc",
"src/functions/copy.cc",
+ "src/functions/free.cc",
"src/convenient_patch.cc",
"src/convenient_hunk.cc",
"src/str_array_converter.cc",
diff --git a/generate/templates/templates/class_content.cc b/generate/templates/templates/class_content.cc
index a6f2a180e..48e67b0eb 100644
--- a/generate/templates/templates/class_content.cc
+++ b/generate/templates/templates/class_content.cc
@@ -43,10 +43,10 @@ using namespace node;
{% endeach %}
}
- void {{ cppClassName }}::InitializeComponent(Local target) {
+ void {{ cppClassName }}::InitializeComponent(v8::Local target) {
Nan::HandleScope scope;
- Local tpl = Nan::New(JSNewFunction);
+ v8::Local tpl = Nan::New(JSNewFunction);
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->SetClassName(Nan::New("{{ jsClassName }}").ToLocalChecked());
@@ -69,17 +69,17 @@ using namespace node;
InitializeTemplate(tpl);
- Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked();
+ v8::Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked();
constructor_template.Reset(_constructor_template);
Nan::Set(target, Nan::New("{{ jsClassName }}").ToLocalChecked(), _constructor_template);
}
{% else %}
- void {{ cppClassName }}::InitializeComponent(Local target) {
+ void {{ cppClassName }}::InitializeComponent(v8::Local target) {
Nan::HandleScope scope;
- Local object = Nan::New();
+ v8::Local object = Nan::New();
{% each functions as function %}
{% if not function.ignore %}
diff --git a/generate/templates/templates/class_header.h b/generate/templates/templates/class_header.h
index 6f19f517f..ea04c120f 100644
--- a/generate/templates/templates/class_header.h
+++ b/generate/templates/templates/class_header.h
@@ -52,7 +52,7 @@ class {{ cppClassName }} : public
friend class NodeGitWrapper<{{ cppClassName }}Traits>;
{%endif %}
public:
- static void InitializeComponent (Local target);
+ static void InitializeComponent (v8::Local target);
{% each functions as function %}
{% if not function.ignore %}
@@ -95,7 +95,7 @@ class {{ cppClassName }} : public
{% endif %}
)
{}
- {{ cppClassName }}({{ cType }} *raw, bool selfFreeing, Local owner = Local())
+ {{ cppClassName }}({{ cType }} *raw, bool selfFreeing, v8::Local owner = v8::Local())
: NodeGitWrapper<{{ cppClassName }}Traits>(raw, selfFreeing, owner)
{}
~{{ cppClassName }}();
diff --git a/generate/templates/templates/nodegit.cc b/generate/templates/templates/nodegit.cc
index 23adae3b5..9f392cabc 100644
--- a/generate/templates/templates/nodegit.cc
+++ b/generate/templates/templates/nodegit.cc
@@ -121,7 +121,7 @@ void OpenSSL_ThreadSetup() {
ThreadPool libgit2ThreadPool(10, uv_default_loop());
-extern "C" void init(Local target) {
+extern "C" void init(v8::Local target) {
// Initialize thread safety in openssl and libssh2
OpenSSL_ThreadSetup();
init_ssh2();
@@ -146,7 +146,7 @@ extern "C" void init(Local target) {
NODE_SET_METHOD(target, "getThreadSafetyStatus", LockMasterGetStatus);
NODE_SET_METHOD(target, "getThreadSafetyDiagnostics", LockMasterGetDiagnostics);
- Local threadSafety = Nan::New();
+ v8::Local threadSafety = Nan::New();
threadSafety->Set(Nan::New("DISABLED").ToLocalChecked(), Nan::New((int)LockMaster::Disabled));
threadSafety->Set(Nan::New("ENABLED_FOR_ASYNC_ONLY").ToLocalChecked(), Nan::New((int)LockMaster::EnabledForAsyncOnly));
threadSafety->Set(Nan::New("ENABLED").ToLocalChecked(), Nan::New((int)LockMaster::Enabled));
diff --git a/generate/templates/templates/struct_content.cc b/generate/templates/templates/struct_content.cc
index 14b3db242..c6f9e5b91 100644
--- a/generate/templates/templates/struct_content.cc
+++ b/generate/templates/templates/struct_content.cc
@@ -68,7 +68,7 @@ void {{ cppClassName }}::ConstructFields() {
{% if not field.ignore %}
{% if not field.isEnum %}
{% if field.hasConstructor |or field.isLibgitType %}
- Local {{ field.name }}Temp = {{ field.cppClassName }}::New(
+ v8::Local {{ field.name }}Temp = {{ field.cppClassName }}::New(
{%if not field.cType|isPointer %}&{%endif%}this->raw->{{ field.name }},
false
)->ToObject();
@@ -82,7 +82,7 @@ void {{ cppClassName }}::ConstructFields() {
this->raw->{{ fields|payloadFor field.name }} = (void *)this;
{% elsif field.payloadFor %}
- Local {{ field.name }} = Nan::Undefined();
+ v8::Local {{ field.name }} = Nan::Undefined();
this->{{ field.name }}.Reset({{ field.name }});
{% endif %}
{% endif %}
@@ -90,10 +90,10 @@ void {{ cppClassName }}::ConstructFields() {
{% endeach %}
}
-void {{ cppClassName }}::InitializeComponent(Local target) {
+void {{ cppClassName }}::InitializeComponent(v8::Local target) {
Nan::HandleScope scope;
- Local tpl = Nan::New(JSNewFunction);
+ v8::Local tpl = Nan::New(JSNewFunction);
tpl->InstanceTemplate()->SetInternalFieldCount(1);
tpl->SetClassName(Nan::New("{{ jsClassName }}").ToLocalChecked());
@@ -108,7 +108,7 @@ void {{ cppClassName }}::InitializeComponent(Local target) {
InitializeTemplate(tpl);
- Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked();
+ v8::Local _constructor_template = Nan::GetFunction(tpl).ToLocalChecked();
constructor_template.Reset(_constructor_template);
Nan::Set(target, Nan::New("{{ jsClassName }}").ToLocalChecked(), _constructor_template);
}
diff --git a/generate/templates/templates/struct_header.h b/generate/templates/templates/struct_header.h
index dd8f8570e..94fd3bc0f 100644
--- a/generate/templates/templates/struct_header.h
+++ b/generate/templates/templates/struct_header.h
@@ -29,8 +29,8 @@ class {{ cppClassName }} : public NodeGitWrapper<{{ cppClassName }}Traits> {
// grant full access to base class
friend class NodeGitWrapper<{{ cppClassName }}Traits>;
public:
- {{ cppClassName }}({{ cType }}* raw, bool selfFreeing, v8::Local owner = Local());
- static void InitializeComponent (Local target);
+ {{ cppClassName }}({{ cType }}* raw, bool selfFreeing, v8::Local owner = v8::Local());
+ static void InitializeComponent (v8::Local target);
{% each fields as field %}
{% if not field.ignore %}
diff --git a/guides/README.md b/guides/README.md
index e4a2bdf14..3fda23c7b 100644
--- a/guides/README.md
+++ b/guides/README.md
@@ -12,7 +12,6 @@ description: Learning NodeGit
- [Basics](install/)
- [From source](install/from-source)
- [Electron](install/electron/)
-- [NW.js](install/nw.js/)
***
diff --git a/guides/install/nw.js/README.md b/guides/install/nw.js/README.md
deleted file mode 100644
index 05b020b42..000000000
--- a/guides/install/nw.js/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-layout: full
-menu_item: guides
-title: NW.js
-description: How to install NodeGit with NW.js
----
-
-[Return to all guides](../../)
-
-* * *
-
-Install for nwjs
-----------------
-
-Please see the official nw.js docs [here](http://docs.nwjs.io/en/latest/For%20Users/Advanced/Use%20Native%20Node%20Modules/#node-pre-gyp)
-
-For a slightly simpler version of the third method, use an `.npmrc` file. For example if you have an NW.js app that's targeting version 0.13.0, your `.npmrc` file would look something like:
-```
-runtime = node-webkit
-target = 0.13.0
-target_arch = x64
-disturl = http://node-webkit.s3.amazonaws.com
-```
-
-*NOTE: NW.js support is not thoroughly tested. Additionally, there are no pre-built binaries for NW.js, you must compile NodeGit. Visit our [building guides](../from-source) for help*
diff --git a/lib/remote.js b/lib/remote.js
index 47fac857e..b7c897957 100644
--- a/lib/remote.js
+++ b/lib/remote.js
@@ -38,7 +38,7 @@ Remote.prototype.connect = function(
proxyOpts,
customHeaders
) {
- callbacks = normalizeOptions(callbacks, NodeGit.RemoteCallbacks);
+ callbacks = normalizeOptions(callbacks || {}, NodeGit.RemoteCallbacks);
proxyOpts = normalizeOptions(proxyOpts || {}, NodeGit.ProxyOptions);
customHeaders = customHeaders || [];
@@ -112,6 +112,18 @@ Remote.prototype.push = function(refSpecs, opts) {
return _push.call(this, refSpecs, opts);
};
+/**
+ * Lists advertised references from a remote. You must connect to the remote
+ * before using referenceList.
+ *
+ * @async
+ * @return {Promise>} a list of the remote heads the remote
+ * had available at the last established
+ * connection.
+ *
+ */
+Remote.prototype.referenceList = Remote.prototype.referenceList;
+
/**
* Connects to a remote
*
diff --git a/lib/repository.js b/lib/repository.js
index 1a4e6eaa8..f2ba369da 100644
--- a/lib/repository.js
+++ b/lib/repository.js
@@ -1,5 +1,6 @@
var promisify = require("promisify-node");
var fse = promisify(require("fs-extra"));
+var fp = require("lodash/fp");
var NodeGit = require("../");
var Blob = NodeGit.Blob;
var Checkout = NodeGit.Checkout;
@@ -184,12 +185,35 @@ function getPathHunks(repo, index, filePath, isStaged, additionalDiffOptions) {
* invocation of next(). If the callback
* returns a promise, the next() will be
* called when the promise resolves.
+ * @param {Function} beforeFinishFn Callback called before the invocation
+ * of finish(). If the callback returns a
+ * promise, finish() will be called when the
+ * promise resolves. This callback will be
+ * provided a detailed overview of the rebase
* @return {Int|Index} An error code for an unsuccesful rebase or an index for
* a rebase with conflicts
*/
-function performRebase(repository, rebase, signature, beforeNextFn) {
+function performRebase(
+ repository,
+ rebase,
+ signature,
+ beforeNextFn,
+ beforeFinishFn
+) {
var beforeNextFnResult;
+ function readRebaseMetadataFile(fileName) {
+ return fse.readFile(
+ path.join(repository.path(), "rebase-merge", fileName),
+ { encoding: "utf8" }
+ )
+ .then(fp.trim);
+ }
+
+ function calcHeadName(input) {
+ return input.replace(/refs\/heads\/(.*)/, "$1");
+ }
+
function getPromise() {
return rebase.next()
.then(function() {
@@ -201,11 +225,51 @@ function performRebase(repository, rebase, signature, beforeNextFn) {
rebase.commit(null, signature);
- return performRebase(repository, rebase, signature, beforeNextFn);
+ return performRebase(
+ repository,
+ rebase,
+ signature,
+ beforeNextFn,
+ beforeFinishFn
+ );
});
}, function(error) {
if (error && error.errno === NodeGit.Error.CODE.ITEROVER) {
- return rebase.finish(signature);
+ const calcRewritten = fp.flow([
+ fp.split("\n"),
+ fp.map(fp.split(" "))
+ ]);
+
+ const beforeFinishFnPromise = !beforeFinishFn ?
+ Promise.resolve() :
+ Promise.all([
+ readRebaseMetadataFile("onto_name"),
+ readRebaseMetadataFile("onto"),
+ readRebaseMetadataFile("head-name").then(calcHeadName),
+ readRebaseMetadataFile("orig-head"),
+ readRebaseMetadataFile("rewritten").then(calcRewritten)
+ ])
+ .then(function([
+ ontoName,
+ ontoSha,
+ originalHeadName,
+ originalHeadSha,
+ rewritten
+ ]) {
+ return beforeFinishFn({
+ ontoName,
+ ontoSha,
+ originalHeadName,
+ originalHeadSha,
+ rebase,
+ rewritten
+ });
+ });
+
+ return beforeFinishFnPromise
+ .then(function() {
+ return rebase.finish(signature);
+ });
} else {
throw error;
}
@@ -354,10 +418,19 @@ Repository.prototype.checkoutRef = function(reference, opts) {
* promise, the rebase will resume when the
* promise resolves. The rebase object is
* is passed to the callback.
+ * @param {Function} beforeFinishFn Callback called before the invocation
+ * of finish(). If the callback returns a
+ * promise, finish() will be called when the
+ * promise resolves. This callback will be
+ * provided a detailed overview of the rebase
* @return {Oid|Index} A commit id for a succesful merge or an index for a
* rebase with conflicts
*/
-Repository.prototype.continueRebase = function(signature, beforeNextFn) {
+Repository.prototype.continueRebase = function(
+ signature,
+ beforeNextFn,
+ beforeFinishFn
+) {
var repo = this;
signature = signature || repo.defaultSignature();
@@ -373,7 +446,13 @@ Repository.prototype.continueRebase = function(signature, beforeNextFn) {
.then(function(rebase) {
rebase.commit(null, signature);
- return performRebase(repo, rebase, signature, beforeNextFn);
+ return performRebase(
+ repo,
+ rebase,
+ signature,
+ beforeNextFn,
+ beforeFinishFn
+ );
})
.then(function(error) {
if (error) {
@@ -1218,6 +1297,11 @@ Repository.prototype.isReverting = function() {
* promise, the rebase will resume when the
* promise resolves. The rebase object is
* is passed to the callback.
+ * @param {Function} beforeFinishFn Callback called before the invocation
+ * of finish(). If the callback returns a
+ * promise, finish() will be called when the
+ * promise resolves. This callback will be
+ * provided a detailed overview of the rebase
* @return {Oid|Index} A commit id for a succesful merge or an index for a
* rebase with conflicts
*/
@@ -1227,6 +1311,7 @@ Repository.prototype.rebaseBranches = function(
onto,
signature,
beforeNextFn,
+ beforeFinishFn,
rebaseOptions
)
{
@@ -1278,7 +1363,13 @@ Repository.prototype.rebaseBranches = function(
rebaseOptions
)
.then(function(rebase) {
- return performRebase(repo, rebase, signature, beforeNextFn);
+ return performRebase(
+ repo,
+ rebase,
+ signature,
+ beforeNextFn,
+ beforeFinishFn
+ );
})
.then(function(error) {
if (error) {
@@ -1325,11 +1416,19 @@ Repository.prototype.refreshIndex = function(callback) {
* @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, mergeOptions) {
+Repository.prototype.mergeBranches = function(
+ to,
+ from,
+ signature,
+ mergePreference,
+ mergeOptions,
+ processMergeMessageCallback
+) {
var repo = this;
var fromBranch;
var toBranch;
+ processMergeMessageCallback = processMergeMessageCallback ||
+ function (message) { return message; };
mergePreference = mergePreference || NodeGit.Merge.PREFERENCE.NONE;
mergeOptions = normalizeOptions(mergeOptions, NodeGit.MergeOptions);
@@ -1414,19 +1513,38 @@ Repository.prototype.mergeBranches =
return index.writeTreeTo(repo);
})
.then(function(oid) {
+ var mergeDecorator;
+ if (fromBranch.isTag()) {
+ mergeDecorator = "tag";
+ } else if (fromBranch.isRemote()) {
+ mergeDecorator = "remote-tracking branch";
+ } else {
+ mergeDecorator = "branch";
+ }
+
var message =
- "Merged " +
+ "Merge " +
+ mergeDecorator +
+ " '" +
fromBranch.shorthand() +
- " into " +
- toBranch.shorthand();
+ "'";
+
+ // https://github.com/git/git/blob/master/builtin/fmt-merge-msg.c#L456-L459
+ if (toBranch.shorthand() !== "master") {
+ message += " into " + toBranch.shorthand();
+ }
+ return Promise.all([oid, processMergeMessageCallback(message)]);
+ })
+ .then(function([oid, message]) {
return repo.createCommit(
toBranch.name(),
signature,
signature,
message,
oid,
- [toCommitOid, fromCommitOid]);
+ [toCommitOid, fromCommitOid]
+ );
})
.then(function(commit) {
// we've updated the checked out branch, so make sure we update
diff --git a/lib/reset.js b/lib/reset.js
index 0f304d6be..df770304a 100644
--- a/lib/reset.js
+++ b/lib/reset.js
@@ -4,6 +4,7 @@ var normalizeOptions = NodeGit.Utils.normalizeOptions;
var Reset = NodeGit.Reset;
var _default = Reset.default;
var _reset = Reset.reset;
+var _fromAnnotated = Reset.fromAnnotated;
/**
* Look up a refs's commit.
@@ -50,3 +51,25 @@ Reset.reset = function(repo, target, resetType, opts) {
return _reset.call(this, repo, target, resetType, opts);
};
+
+/**
+ * Sets the current head to the specified commit oid and optionally
+ * resets the index and working tree to match.
+ *
+ * This behaves like reset but takes an annotated commit, which lets
+ * you specify which extended sha syntax string was specified by a
+ * user, allowing for more exact reflog messages.
+ *
+ * See the documentation for reset.
+ *
+ * @async
+ * @param {Repository} repo
+ * @param {AnnotatedCommit} target
+ * @param {Number} resetType
+ * @param {CheckoutOptions} opts
+ */
+Reset.fromAnnotated = function(repo, target, resetType, opts) {
+ opts = normalizeOptions(opts, NodeGit.CheckoutOptions);
+
+ return _fromAnnotated.call(this, repo, target, resetType, opts);
+};
diff --git a/package.json b/package.json
index 9b04d878d..ff52b8d84 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "nodegit",
"description": "Node.js libgit2 asynchronous native bindings",
- "version": "0.17.0",
+ "version": "0.18.0",
"homepage": "http://nodegit.org",
"keywords": [
"libgit2",
@@ -52,7 +52,8 @@
"js-beautify": "~1.5.10",
"jshint": "~2.8.0",
"lcov-result-merger": "~1.0.2",
- "mocha": "~2.3.4"
+ "mocha": "~2.3.4",
+ "walk": "^2.3.9"
},
"vendorDependencies": {
"libssh2": "1.7.0",
diff --git a/test/tests/clone.js b/test/tests/clone.js
index c7645357d..48205d03d 100644
--- a/test/tests/clone.js
+++ b/test/tests/clone.js
@@ -166,6 +166,37 @@ describe("Clone", function() {
});
});
+ it("can clone without waiting for callback results", function() {
+ var test = this;
+ var url = "https://github.com/nodegit/test.git";
+ var lastReceivedObjects = 0;
+ var cloneFinished = false;
+ var opts = {
+ fetchOpts: {
+ callbacks: {
+ transferProgress: {
+ waitForResult: false,
+ callback: function(progress) {
+ var receivedObjects = progress.receivedObjects();
+ assert.false(
+ cloneFinished,
+ "callback running after clone completion"
+ );
+ assert.gt(receivedObjects, lastReceivedObjects);
+ lastReceivedObjects = receivedObjects;
+ }
+ }
+ }
+ }
+ };
+
+ return Clone(url, clonePath, opts).then(function(repo) {
+ assert.ok(repo instanceof Repository);
+ cloneFinished = true;
+ test.repository = repo;
+ });
+ });
+
it("can clone using nested function", function() {
var test = this;
var url = "https://github.com/nodegit/test.git";
diff --git a/test/tests/commit.js b/test/tests/commit.js
index be066093e..097b45ed7 100644
--- a/test/tests/commit.js
+++ b/test/tests/commit.js
@@ -586,6 +586,24 @@ describe("Commit", function() {
});
});
+ it("can get header fields", function() {
+ var commit = this.commit;
+ return commit.headerField("parent").then(function(field) {
+ assert.equal(field,
+ "ecfd36c80a3e9081f200dfda2391acadb56dac27");
+ return commit.headerField("author");
+ })
+ .then(function(field) {
+ assert.equal(field,
+ "Michael Robinson 1362012884 +1300");
+ return commit.headerField("committer");
+ })
+ .then(function(field) {
+ assert.equal(field,
+ "Michael Robinson 1362012884 +1300");
+ });
+ });
+
describe("Commit's Author", function() {
before(function() {
this.author = this.commit.author();
@@ -622,6 +640,28 @@ describe("Commit", function() {
});
});
+ describe("Commit's Body", function() {
+
+ it("null if only summary", function() {
+ var test = this;
+ return NodeGit.Commit.lookup(test.repository,
+ "15315cf41ad76400d9189c85a5827b77b8c392f1")
+ .then(function(commit) {
+ assert.equal(commit.body(), null);
+ });
+ });
+
+ it("non-null when body exists", function() {
+ var test = this;
+ return NodeGit.Commit.lookup(test.repository,
+ "c82fb078a192ea221c9f1093c64321c60d64aa0d")
+ .then(function(commit) {
+ assert.equal(commit.body(),
+ "Added new methods in checkout and repository");
+ });
+ });
+ });
+
it("does not leak", function() {
var test = this;
diff --git a/test/tests/merge.js b/test/tests/merge.js
index 3a63b0ced..66728bdb9 100644
--- a/test/tests/merge.js
+++ b/test/tests/merge.js
@@ -348,7 +348,7 @@ describe("Merge", function() {
})
.then(function(oid) {
assert.equal(oid.toString(),
- "6806d22d2b6c0095b29dc5ec51829caeb67861f1");
+ "65516eb7b20f51d275096cd28f132ff606a09e07");
return repository.getBranchCommit(ourBranchName)
.then(function(branchCommit) {
@@ -501,7 +501,7 @@ describe("Merge", function() {
})
.then(function(commitId) {
assert.equal(commitId.toString(),
- "5384feb481d9c29081b3a0c1478fcc24a3953efa");
+ "96d6f1d0704eb3ef9121a13348d17c1d672c28aa");
})
.then(function() {
return repository.getStatus();
@@ -512,6 +512,320 @@ describe("Merge", function() {
});
});
+ it(
+ "can merge --no-ff a non-fast-forward using the convenience method " +
+ "with custom merge message via sync callback",
+ function() {
+ var initialFileName = "initialFile.txt";
+ var ourFileName = "ourNewFile.txt";
+ var theirFileName = "theirNewFile.txt";
+
+ var initialFileContent = "I'd like to drive somewhere";
+ var ourFileContent = "I like Toll Roads. I have an EZ-Pass!";
+ var theirFileContent = "I'm skeptical about Toll Roads";
+
+ var ourSignature = NodeGit.Signature.create
+ ("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60);
+ var theirSignature = NodeGit.Signature.create
+ ("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60);
+
+ var repository = this.repository;
+ var initialCommit;
+ var ourCommit;
+ var theirCommit;
+ var ourBranch;
+ var theirBranch;
+
+ return fse.writeFile(
+ path.join(repository.workdir(), initialFileName),
+ initialFileContent)
+ // Load up the repository index and make our initial commit to HEAD
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(initialFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "21a553813e2f670815b649eef51eeadb253a5d0c");
+
+ return repository.createCommit("HEAD", ourSignature,
+ ourSignature, "initial commit", oid, []);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "af66a9c799a10a23319ee4318c8bb2021521f539");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ initialCommit = commit;
+ }).then(function() {
+ return repository.createBranch(ourBranchName, commitOid)
+ .then(function(branch) {
+ ourBranch = branch;
+ return repository.createBranch(theirBranchName, commitOid);
+ });
+ });
+ })
+ .then(function(branch) {
+ theirBranch = branch;
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), ourFileName),
+ ourFileContent);
+ })
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(ourFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "af60aa06b3537f75b427f6268a130c842c84a137");
+
+ return repository.createCommit(ourBranch.name(), ourSignature,
+ ourSignature, "we made a commit", oid, [initialCommit]);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "7ce31c05427659986d50abfb90c8f7db88ef4fa1");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ ourCommit = commit;
+ });
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), theirFileName),
+ theirFileContent);
+ })
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(theirFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "f007361737a2ca00a0e80fc2daf55064463173b4");
+
+ return repository.createCommit(theirBranch.name(), theirSignature,
+ theirSignature, "they made a commit", oid, [initialCommit]);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "b588f0eef1809226f8f7db542940749da15ae1de");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ theirCommit = commit;
+ });
+ })
+ .then(function() {
+ var opts = {checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE};
+ return repository.checkoutBranch(ourBranchName, opts);
+ })
+ .then(function() {
+ return repository.mergeBranches(
+ ourBranchName,
+ theirBranchName,
+ ourSignature,
+ NodeGit.Merge.PREFERENCE.NO_FASTFORWARD,
+ null,
+ function(message) {
+ assert(message === "Merge branch 'theirs' into ours");
+ return "We manipulated the message, HAH.";
+ }
+ );
+ })
+ .then(function(commitId) {
+ assert.equal(commitId.toString(),
+ "5b49a43be0ba95e7767dd9a2880bab4795c6db70");
+ })
+ .then(function() {
+ return repository.getStatus();
+ })
+ .then(function(statuses) {
+ // make sure we didn't change the index
+ assert.equal(statuses.length, 0);
+ });
+ }
+ );
+
+ it(
+ "can merge --no-ff a non-fast-forward using the convenience method " +
+ "with custom merge message via async callback",
+ function() {
+ var initialFileName = "initialFile.txt";
+ var ourFileName = "ourNewFile.txt";
+ var theirFileName = "theirNewFile.txt";
+
+ var initialFileContent = "I'd like to drive somewhere";
+ var ourFileContent = "I like Toll Roads. I have an EZ-Pass!";
+ var theirFileContent = "I'm skeptical about Toll Roads";
+
+ var ourSignature = NodeGit.Signature.create
+ ("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60);
+ var theirSignature = NodeGit.Signature.create
+ ("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60);
+
+ var repository = this.repository;
+ var initialCommit;
+ var ourCommit;
+ var theirCommit;
+ var ourBranch;
+ var theirBranch;
+
+ return fse.writeFile(
+ path.join(repository.workdir(), initialFileName),
+ initialFileContent)
+ // Load up the repository index and make our initial commit to HEAD
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(initialFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "21a553813e2f670815b649eef51eeadb253a5d0c");
+
+ return repository.createCommit("HEAD", ourSignature,
+ ourSignature, "initial commit", oid, []);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "af66a9c799a10a23319ee4318c8bb2021521f539");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ initialCommit = commit;
+ }).then(function() {
+ return repository.createBranch(ourBranchName, commitOid)
+ .then(function(branch) {
+ ourBranch = branch;
+ return repository.createBranch(theirBranchName, commitOid);
+ });
+ });
+ })
+ .then(function(branch) {
+ theirBranch = branch;
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), ourFileName),
+ ourFileContent);
+ })
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(ourFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "af60aa06b3537f75b427f6268a130c842c84a137");
+
+ return repository.createCommit(ourBranch.name(), ourSignature,
+ ourSignature, "we made a commit", oid, [initialCommit]);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "7ce31c05427659986d50abfb90c8f7db88ef4fa1");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ ourCommit = commit;
+ });
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), theirFileName),
+ theirFileContent);
+ })
+ .then(function() {
+ return repository.refreshIndex();
+ })
+ .then(function(index) {
+ return index.addByPath(theirFileName)
+ .then(function() {
+ return index.write();
+ })
+ .then(function() {
+ return index.writeTree();
+ });
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "f007361737a2ca00a0e80fc2daf55064463173b4");
+
+ return repository.createCommit(theirBranch.name(), theirSignature,
+ theirSignature, "they made a commit", oid, [initialCommit]);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "b588f0eef1809226f8f7db542940749da15ae1de");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ theirCommit = commit;
+ });
+ })
+ .then(function() {
+ var opts = {checkoutStrategy: NodeGit.Checkout.STRATEGY.FORCE};
+ return repository.checkoutBranch(ourBranchName, opts);
+ })
+ .then(function() {
+ return repository.mergeBranches(
+ ourBranchName,
+ theirBranchName,
+ ourSignature,
+ NodeGit.Merge.PREFERENCE.NO_FASTFORWARD,
+ null,
+ function(message) {
+ assert(message === "Merge branch 'theirs' into ours");
+ return Promise.resolve("We manipulated the message, HAH.");
+ }
+ );
+ })
+ .then(function(commitId) {
+ assert.equal(commitId.toString(),
+ "5b49a43be0ba95e7767dd9a2880bab4795c6db70");
+ })
+ .then(function() {
+ return repository.getStatus();
+ })
+ .then(function(statuses) {
+ // make sure we didn't change the index
+ assert.equal(statuses.length, 0);
+ });
+ }
+ );
+
it("can merge --ff-only a fast-forward using the convenience method",
function() {
var ourFileName = "ourNewFile.txt";
@@ -906,7 +1220,7 @@ describe("Merge", function() {
})
.then(function(commitId) {
assert.equal(commitId.toString(),
- "5384feb481d9c29081b3a0c1478fcc24a3953efa");
+ "96d6f1d0704eb3ef9121a13348d17c1d672c28aa");
});
});
@@ -1298,4 +1612,26 @@ describe("Merge", function() {
assert.ok(repository.isDefaultState());
});
});
+
+ it("can retrieve error code on if common merge base not found", function() {
+ var repo;
+ return NodeGit.Repository.open(local("../repos/workdir"))
+ .then(function(r) {
+ repo = r;
+ return repo.getCommit("4bd806114ce26503c103c85dcc985021951bbc18");
+ })
+ .then(function(commit) {
+ return commit.getParents(commit.parentcount());
+ })
+ .then(function(parents) {
+ return NodeGit.Merge.base(repo, parents[0], parents[1])
+ .then(function() {
+ return Promise.reject(new Error(
+ "should not be able to retrieve common merge base"));
+ }, function(err) {
+ assert.equal("no merge base found", err.message);
+ assert.equal(NodeGit.Error.CODE.ENOTFOUND, err.errno);
+ });
+ });
+ });
});
diff --git a/test/tests/rebase.js b/test/tests/rebase.js
index 70c8e8ee6..731884f82 100644
--- a/test/tests/rebase.js
+++ b/test/tests/rebase.js
@@ -915,6 +915,304 @@ describe("Rebase", function() {
});
});
+ it("beforeFinishFn sync callback receives correct rebase data", function() {
+ var baseFileName = "baseNewFile.txt";
+ var ourFileName = "ourNewFile.txt";
+ var theirFileName = "theirNewFile.txt";
+
+ var baseFileContent = "How do you feel about Toll Roads?";
+ var ourFileContent = "I like Toll Roads. I have an EZ-Pass!";
+ var theirFileContent = "I'm skeptical about Toll Roads";
+
+ var ourSignature = NodeGit.Signature.create
+ ("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60);
+ var theirSignature = NodeGit.Signature.create
+ ("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60);
+
+ var repository = this.repository;
+ var ourCommit;
+ var ourBranch;
+ var theirBranch;
+ var ourBranchShaPreRebase;
+ var ourBranchShaPostRebase = "b937100ee0ea17ef20525306763505a7fe2be29e";
+ var theirBranchSha;
+
+ var nextCalls = 0;
+
+ var calledBeforeFinishFn = false;
+
+ return fse.writeFile(path.join(repository.workdir(), baseFileName),
+ baseFileContent)
+ // Load up the repository index and make our initial commit to HEAD
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, baseFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "b5cdc109d437c4541a13fb7509116b5f03d5039a");
+
+ return repository.createCommit("HEAD", ourSignature,
+ ourSignature, "initial commit", oid, []);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "be03abdf0353d05924c53bebeb0e5bb129cda44a");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ ourCommit = commit;
+ }).then(function() {
+ return repository.createBranch(ourBranchName, commitOid)
+ .then(function(branch) {
+ ourBranch = branch;
+ return repository.createBranch(theirBranchName, commitOid);
+ });
+ });
+ })
+ .then(function(branch) {
+ theirBranch = branch;
+ return fse.writeFile(path.join(repository.workdir(), theirFileName),
+ theirFileContent);
+ })
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, theirFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "be5f0fd38a39a67135ad68921c93cd5c17fefb3d");
+
+ return repository.createCommit(theirBranch.name(), theirSignature,
+ theirSignature, "they made a commit", oid, [ourCommit]);
+ })
+ .then(function(commitOid) {
+ theirBranchSha = commitOid.toString();
+ assert.equal(theirBranchSha,
+ "e9ebd92f2f4778baf6fa8e92f0c68642f931a554");
+
+ return removeFileFromIndex(repository, theirFileName);
+ })
+ .then(function() {
+ return fse.remove(path.join(repository.workdir(), theirFileName));
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), ourFileName),
+ ourFileContent);
+ })
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, ourFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "77867fc0bfeb3f80ab18a78c8d53aa3a06207047");
+
+ return repository.createCommit(ourBranch.name(), ourSignature,
+ ourSignature, "we made a commit", oid, [ourCommit]);
+ })
+ .then(function(commitOid) {
+ ourBranchShaPreRebase = commitOid.toString();
+ assert.equal(ourBranchShaPreRebase,
+ "e7f37ee070837052937e24ad8ba66f6d83ae7941");
+
+ return removeFileFromIndex(repository, ourFileName);
+ })
+ .then(function() {
+ return fse.remove(path.join(repository.workdir(), ourFileName));
+ })
+ .then(function() {
+ return repository.checkoutBranch(ourBranchName);
+ })
+ .then(function() {
+ return repository.rebaseBranches(ourBranchName, theirBranchName,
+ null, ourSignature, function(rebase) {
+ assert.ok(rebase instanceof NodeGit.Rebase);
+
+ nextCalls++;
+
+ return Promise.resolve();
+ }, function(rebaseMetadata) {
+ calledBeforeFinishFn = true;
+
+ assert.equal(rebaseMetadata.ontoName, theirBranchName);
+ assert.equal(rebaseMetadata.ontoSha, theirBranchSha);
+ assert.equal(rebaseMetadata.originalHeadName, ourBranchName);
+ assert.equal(
+ rebaseMetadata.originalHeadSha,
+ ourBranchShaPreRebase
+ );
+ assert.deepEqual(
+ rebaseMetadata.rewritten,
+ [[ourBranchShaPreRebase, ourBranchShaPostRebase]]
+ );
+ });
+ })
+ .then(function(commit) {
+ // verify that the beforeNextFn callback was called
+ assert.equal(nextCalls, 2);
+
+ // verify that the beforeFinishFn callback was called
+ assert(calledBeforeFinishFn, "beforeFinishFn was not called");
+
+ // verify that the "ours" branch has moved to the correct place
+ assert.equal(commit.id().toString(), ourBranchShaPostRebase);
+
+ return commit.parent(0);
+ })
+ .then(function(commit) {
+ // verify that we are on top of "their commit"
+ assert.equal(commit.id().toString(),
+ "e9ebd92f2f4778baf6fa8e92f0c68642f931a554");
+ });
+ });
+
+ it("beforeFinishFn async callback receives correct rebase data", function() {
+ var baseFileName = "baseNewFile.txt";
+ var ourFileName = "ourNewFile.txt";
+ var theirFileName = "theirNewFile.txt";
+
+ var baseFileContent = "How do you feel about Toll Roads?";
+ var ourFileContent = "I like Toll Roads. I have an EZ-Pass!";
+ var theirFileContent = "I'm skeptical about Toll Roads";
+
+ var ourSignature = NodeGit.Signature.create
+ ("Ron Paul", "RonPaul@TollRoadsRBest.info", 123456789, 60);
+ var theirSignature = NodeGit.Signature.create
+ ("Greg Abbott", "Gregggg@IllTollYourFace.us", 123456789, 60);
+
+ var repository = this.repository;
+ var ourCommit;
+ var ourBranch;
+ var theirBranch;
+ var ourBranchShaPreRebase;
+ var ourBranchShaPostRebase = "b937100ee0ea17ef20525306763505a7fe2be29e";
+ var theirBranchSha;
+
+ var nextCalls = 0;
+
+ var calledBeforeFinishFn = false;
+
+ return fse.writeFile(path.join(repository.workdir(), baseFileName),
+ baseFileContent)
+ // Load up the repository index and make our initial commit to HEAD
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, baseFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "b5cdc109d437c4541a13fb7509116b5f03d5039a");
+
+ return repository.createCommit("HEAD", ourSignature,
+ ourSignature, "initial commit", oid, []);
+ })
+ .then(function(commitOid) {
+ assert.equal(commitOid.toString(),
+ "be03abdf0353d05924c53bebeb0e5bb129cda44a");
+
+ return repository.getCommit(commitOid).then(function(commit) {
+ ourCommit = commit;
+ }).then(function() {
+ return repository.createBranch(ourBranchName, commitOid)
+ .then(function(branch) {
+ ourBranch = branch;
+ return repository.createBranch(theirBranchName, commitOid);
+ });
+ });
+ })
+ .then(function(branch) {
+ theirBranch = branch;
+ return fse.writeFile(path.join(repository.workdir(), theirFileName),
+ theirFileContent);
+ })
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, theirFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "be5f0fd38a39a67135ad68921c93cd5c17fefb3d");
+
+ return repository.createCommit(theirBranch.name(), theirSignature,
+ theirSignature, "they made a commit", oid, [ourCommit]);
+ })
+ .then(function(commitOid) {
+ theirBranchSha = commitOid.toString();
+ assert.equal(theirBranchSha,
+ "e9ebd92f2f4778baf6fa8e92f0c68642f931a554");
+
+ return removeFileFromIndex(repository, theirFileName);
+ })
+ .then(function() {
+ return fse.remove(path.join(repository.workdir(), theirFileName));
+ })
+ .then(function() {
+ return fse.writeFile(path.join(repository.workdir(), ourFileName),
+ ourFileContent);
+ })
+ .then(function() {
+ return RepoUtils.addFileToIndex(repository, ourFileName);
+ })
+ .then(function(oid) {
+ assert.equal(oid.toString(),
+ "77867fc0bfeb3f80ab18a78c8d53aa3a06207047");
+
+ return repository.createCommit(ourBranch.name(), ourSignature,
+ ourSignature, "we made a commit", oid, [ourCommit]);
+ })
+ .then(function(commitOid) {
+ ourBranchShaPreRebase = commitOid.toString();
+ assert.equal(ourBranchShaPreRebase,
+ "e7f37ee070837052937e24ad8ba66f6d83ae7941");
+
+ return removeFileFromIndex(repository, ourFileName);
+ })
+ .then(function() {
+ return fse.remove(path.join(repository.workdir(), ourFileName));
+ })
+ .then(function() {
+ return repository.checkoutBranch(ourBranchName);
+ })
+ .then(function() {
+ return repository.rebaseBranches(ourBranchName, theirBranchName,
+ null, ourSignature, function(rebase) {
+ assert.ok(rebase instanceof NodeGit.Rebase);
+
+ nextCalls++;
+
+ return Promise.resolve();
+ }, function(rebaseMetadata) {
+ calledBeforeFinishFn = true;
+
+ assert.equal(rebaseMetadata.ontoName, theirBranchName);
+ assert.equal(rebaseMetadata.ontoSha, theirBranchSha);
+ assert.equal(rebaseMetadata.originalHeadName, ourBranchName);
+ assert.equal(
+ rebaseMetadata.originalHeadSha,
+ ourBranchShaPreRebase
+ );
+ assert.deepEqual(
+ rebaseMetadata.rewritten,
+ [[ourBranchShaPreRebase, ourBranchShaPostRebase]]
+ );
+
+ return Promise.resolve();
+ });
+ })
+ .then(function(commit) {
+ // verify that the beforeNextFn callback was called
+ assert.equal(nextCalls, 2);
+
+ // verify that the beforeFinishFn callback was called
+ assert(calledBeforeFinishFn, "beforeFinishFn was not called");
+
+ // verify that the "ours" branch has moved to the correct place
+ assert.equal(commit.id().toString(), ourBranchShaPostRebase);
+
+ return commit.parent(0);
+ })
+ .then(function(commit) {
+ // verify that we are on top of "their commit"
+ assert.equal(commit.id().toString(),
+ "e9ebd92f2f4778baf6fa8e92f0c68642f931a554");
+ });
+ });
+
it("can rebase with conflicts using the convenience methods", function() {
var fileName = "everyonesFile.txt";
diff --git a/test/tests/remote.js b/test/tests/remote.js
index dfe3fb318..57d77517d 100644
--- a/test/tests/remote.js
+++ b/test/tests/remote.js
@@ -2,6 +2,7 @@ var assert = require("assert");
var path = require("path");
var local = path.join.bind(path, __dirname);
var _ = require("lodash");
+var fp = require("lodash/fp");
var garbageCollect = require("../utils/garbage_collect.js");
@@ -444,4 +445,111 @@ describe("Remote", function() {
Remote.getSelfFreeingInstanceCount());
});
});
+
+ it("can retrieve the list of references advertised by a remote", function() {
+ var expectedRemoteHeads = {
+ HEAD: {
+ local: 0,
+ oid: "32789a79e71fbc9e04d3eff7425e1771eb595150",
+ loid: "0000000000000000000000000000000000000000",
+ name: "HEAD",
+ symrefTarget: "refs/heads/master"
+ },
+ "refs/heads/checkout-test": {
+ local: 0,
+ oid: "1729c73906bb8467f4095c2f4044083016b4dfde",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/heads/checkout-test",
+ symrefTarget: null
+ },
+ "refs/heads/master": {
+ local: 0,
+ oid: "32789a79e71fbc9e04d3eff7425e1771eb595150",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/heads/master",
+ symrefTarget: null
+ },
+ "refs/heads/rev-walk": {
+ local: 0,
+ oid: "32789a79e71fbc9e04d3eff7425e1771eb595150",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/heads/rev-walk",
+ symrefTarget: null
+ },
+ "refs/tags/annotated-tag": {
+ local: 0,
+ oid: "dc800017566123ff3c746b37284a24a66546667e",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/tags/annotated-tag",
+ symrefTarget: null
+ },
+ "refs/tags/annotated-tag^{}": {
+ local: 0,
+ oid: "32789a79e71fbc9e04d3eff7425e1771eb595150",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/tags/annotated-tag^{}",
+ symrefTarget: null
+ },
+ "refs/tags/light-weight-tag": {
+ local: 0,
+ oid: "32789a79e71fbc9e04d3eff7425e1771eb595150",
+ loid: "0000000000000000000000000000000000000000",
+ name: "refs/tags/light-weight-tag",
+ symrefTarget: null
+ }
+ };
+
+ return this.repository.getRemote("origin")
+ .then(function(remote) {
+ return Promise.all([
+ remote,
+ remote.connect(NodeGit.Enums.DIRECTION.FETCH)
+ ]);
+ })
+ .then(function(results) {
+ var remote = results[0];
+ return Promise.all([remote, remote.referenceList()]);
+ })
+ .then(function(results) {
+ var remote = results[0];
+ var remoteHeads = results[1];
+ var remoteHeadsBySha = fp.flow([
+ fp.map(function(remoteHead) {
+ return {
+ local: remoteHead.local(),
+ oid: remoteHead.oid().toString(),
+ loid: remoteHead.loid().toString(),
+ name: remoteHead.name(),
+ symrefTarget: remoteHead.symrefTarget()
+ };
+ }),
+ fp.keyBy("name")
+ ])(remoteHeads);
+
+ fp.flow([
+ fp.keys,
+ fp.forEach(function(remoteHeadName) {
+ assert(fp.isEqual(
+ expectedRemoteHeads[remoteHeadName],
+ remoteHeadsBySha[remoteHeadName]
+ ), "Expectations for head " + remoteHeadName + " were not met.");
+ })
+ ])(expectedRemoteHeads);
+
+ return remote.disconnect();
+ });
+ });
+
+ it("will error when retrieving reference list if not connected", function() {
+ return this.repository.getRemote("origin")
+ .then(function(remote) {
+ return remote.referenceList();
+ })
+ .then(function() {
+ assert.fail("Unconnected remote should have no reference list.");
+ })
+ .catch(function(notConnectedError) {
+ assert(notConnectedError.message === "this remote has never connected");
+ });
+ });
});
diff --git a/test/tests/reset.js b/test/tests/reset.js
index 7cfea3dd3..9bc38fd2b 100644
--- a/test/tests/reset.js
+++ b/test/tests/reset.js
@@ -8,6 +8,7 @@ describe("Reset", function() {
var NodeGit = require("../../");
var Repository = NodeGit.Repository;
var Reset = NodeGit.Reset;
+ var AnnotatedCommit = NodeGit.AnnotatedCommit;
var reposPath = local("../repos/workdir");
var currentCommitOid = "32789a79e71fbc9e04d3eff7425e1771eb595150";
@@ -104,25 +105,57 @@ describe("Reset", function() {
});
});
- it("can perform a soft reset", function() {
- var test = this;
-
- return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.SOFT)
+ function resetFrom(repo, commit, resetType, annotated) {
+ var promise = null;
+ if (annotated) {
+ promise = AnnotatedCommit.lookup(repo, commit.id())
+ .then(function(annotatedCommit) {
+ return Reset.fromAnnotated(repo, annotatedCommit, resetType);
+ });
+ } else {
+ promise = Reset.reset(repo, commit, resetType);
+ }
+ return promise
.then(function() {
- return test.repo.refreshIndex();
+ return repo.refreshIndex();
})
.then(function(index) {
return index.writeTree();
})
.then(function(oid) {
- return test.repo.getTree(oid);
+ return repo.getTree(oid);
})
.then(function(tree) {
return tree.getEntry(filePath);
})
.then(function(entry) {
return entry.getBlob();
- })
+ });
+ }
+
+ it("can perform a soft reset", function() {
+ var test = this;
+
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.SOFT, false)
+ .then(function(blob) {
+ var currentCommitContents = test.currentCommitBlob.toString();
+ var previousCommitContents = test.previousCommitBlob.toString();
+ var resetContents = blob.toString();
+
+ // With a soft reset all of the changes should be in the index
+ // still so the index should still == what we had at the current
+ // commit and not the one nwe reset to
+ assert(resetContents == currentCommitContents);
+ assert(resetContents != previousCommitContents);
+
+ return Reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
+ });
+ });
+
+ it("can perform an annotated soft reset", function() {
+ var test = this;
+
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.SOFT, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
@@ -130,7 +163,7 @@ describe("Reset", function() {
// With a soft reset all of the changes should be in the index
// still so the index should still == what we had at the current
- // commit and not the one we reset to
+ // commit and not the one nwe reset to
assert(resetContents == currentCommitContents);
assert(resetContents != previousCommitContents);
@@ -141,22 +174,32 @@ describe("Reset", function() {
it("can perform a mixed reset", function() {
var test = this;
- return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.MIXED)
- .then(function() {
- return test.repo.refreshIndex();
- })
- .then(function(index) {
- return index.writeTree();
- })
- .then(function(oid) {
- return test.repo.getTree(oid);
- })
- .then(function(tree) {
- return tree.getEntry(filePath);
- })
- .then(function(entry) {
- return entry.getBlob();
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.MIXED, false)
+ .then(function(blob) {
+ var currentCommitContents = test.currentCommitBlob.toString();
+ var previousCommitContents = test.previousCommitBlob.toString();
+ var resetContents = blob.toString();
+
+ // With a mixed reset all of the changes should removed from the index
+ // but still in the working directory. (i.e. unstaged)
+ assert(resetContents != currentCommitContents);
+ assert(resetContents == previousCommitContents);
+
+ return fse.readFile(path.join(test.repo.workdir(), filePath));
})
+ .then(function(fileContents) {
+ var currentCommitContents = test.currentCommitBlob.toString();
+
+ assert(fileContents == currentCommitContents);
+
+ return Reset.reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
+ });
+ });
+
+ it("can perform an annotated mixed reset", function() {
+ var test = this;
+
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.MIXED, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
@@ -181,22 +224,32 @@ describe("Reset", function() {
it("can perform a hard reset", function() {
var test = this;
- return Reset.reset(test.repo, test.previousCommit, Reset.TYPE.HARD)
- .then(function() {
- return test.repo.refreshIndex();
- })
- .then(function(index) {
- return index.writeTree();
- })
- .then(function(oid) {
- return test.repo.getTree(oid);
- })
- .then(function(tree) {
- return tree.getEntry(filePath);
- })
- .then(function(entry) {
- return entry.getBlob();
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.HARD, false)
+ .then(function(blob) {
+ var currentCommitContents = test.currentCommitBlob.toString();
+ var previousCommitContents = test.previousCommitBlob.toString();
+ var resetContents = blob.toString();
+
+ // With a hard reset all of the changes should removed from the index
+ // and also removed from the working directory
+ assert(resetContents != currentCommitContents);
+ assert(resetContents == previousCommitContents);
+
+ return fse.readFile(path.join(test.repo.workdir(), filePath));
})
+ .then(function(fileContents) {
+ var previousCommitContents = test.previousCommitBlob.toString();
+
+ assert(fileContents == previousCommitContents);
+
+ return Reset.reset(test.repo, test.currentCommit, Reset.TYPE.HARD);
+ });
+ });
+
+ it("can perform an annotated hard reset", function() {
+ var test = this;
+
+ return resetFrom(test.repo, test.previousCommit, Reset.TYPE.HARD, true)
.then(function(blob) {
var currentCommitContents = test.currentCommitBlob.toString();
var previousCommitContents = test.previousCommitBlob.toString();
diff --git a/test/tests/revert.js b/test/tests/revert.js
index b3f151831..a16d8c126 100644
--- a/test/tests/revert.js
+++ b/test/tests/revert.js
@@ -60,4 +60,11 @@ describe("Revert", function() {
assert.ok(_.endsWith(fileName, entries[0].path));
});
});
+
+ it("RevertOptions is optional", function() {
+ return Revert.revert(test.repository, test.firstCommit, null)
+ .catch(function(error) {
+ throw error;
+ });
+ });
});
diff --git a/test/tests/stash.js b/test/tests/stash.js
index 1e0a1d395..637ae00c9 100644
--- a/test/tests/stash.js
+++ b/test/tests/stash.js
@@ -31,15 +31,13 @@ describe("Stash", function() {
});
});
- it("can save and drop a stash", function() {
+ function saveDropStash(repo, stashMessage) {
var fileName = "README.md";
var fileContent = "Cha-cha-cha-chaaaaaangessssss";
- var repo = this.repository;
var filePath = path.join(repo.workdir(), fileName);
var oldContent;
var stashes = [];
var stashOid;
- var stashMessage = "stash test";
return fse.readFile(filePath)
.then(function(content) {
@@ -82,6 +80,14 @@ describe("Stash", function() {
return Promise.reject(e);
});
});
+ }
+
+ it("can save and drop a stash", function() {
+ saveDropStash(this.repository, "stash test");
+ });
+
+ it("can save a stash with no message and drop it", function() {
+ saveDropStash(this.repository, null);
});
it("can save and pop a stash", function() {
diff --git a/vendor/libgit2 b/vendor/libgit2
index 0bf052600..12f0b704d 160000
--- a/vendor/libgit2
+++ b/vendor/libgit2
@@ -1 +1 @@
-Subproject commit 0bf05260089002b8101a0be1f79261b3211b10db
+Subproject commit 12f0b704d2d3269db5bc6d95f098aea3eb645f63