Today marks the release of isomorphic-git version 1.0! 🎉 There are a lot of big improvements to celebrate.
- Better IDE Integration
- Better TypeScript Integration
- More Good Defaults, Fewer Bad Defaults
- Embrace Callbacks
- Future-proof API
- 1.0 Breaking Changes
Better IDE Integration
No longer must we maintain the
index.d.ts file by hand!
Thanks to improvements in TS 3.7, we can auto-generate the declaration file using
tsc --declaration --allowJs.
This has the added benefit that the JSDoc is also included in the
index.d.ts which leads to a much richer IDE integration. Sadly, parameter descriptions still aren't shown, but the main description body and the example code are!
Here's what the Visual Studio Code tooltip for
git.log looked like before:
And here's what it looks like in version 1.0:
The functions themselves have been tweaked so that the core object interfaces (
TagObject, etc) are reused wherever possible,
so that all the functions feel consistent and there are no surprises.
The result is a cleaner API where the documentation comes to you, right where you are.
Better TypeScript Integration
The return types gel with TS better now. For example,
readObject returns a "discriminated union" type, so you can take advantage of powerful type inference, like this:
Exceptions are also well-typed now, so you can access their
.data property with confidence:
More Good Defaults, Fewer Bad Defaults
A number of helpful behaviors that had to be opt-in before to preserve backwards compatibility are now the defaults.
initfunction doesn't overwrite your config file if it already exists.
checkoutfunction now warns about conflicts instead of blindly overwriting files.
commitfunction doesn't silently remove submodules.
:shudder: You live, you learn, amirite?
A number of "helpful" default behaviors have been removed, because no default is better than a bad default:
A big one was assuming if you if you used the ESM build you were in the browser and had access to
fetch and if you used the CommonJS build you were in node.
That simply isn't true in today's environment.
In version 1.0, you are always in control of whether to use
Another one was automatically appending
.git to the end of URLs when you clone them. That can be helpful, but it can also completely break cloning for some servers, which led to the awkward addition of the
noGitSuffix parameter (cringe).
In version 1.0, the URL you give is the URL we GET.
Something I tried to do early-ish in the development of 0.x was to move towards this idea that all function arguments need to be serializable. My reasoning was this:
- isomorphic-git can be pretty slow and block the main thread.
- I should encourage everyone to use isomorphic-git in a Worker.
- Therefore, I should make it easy to wrap isomorphic-git in a postMessage / RPC interface.
This led to the creation of
magic-portal and publishing the WebWorker Guide.
It also was the main constraint driving the design of the plugin system.
The idea was all the callbacks could be setup in one place.
However, since that time I have grown a tad wiser. In building real-world applications with isomorphic-git, I've realized:
- All code can be pretty slow and block the main thread.
- Therefore all the code that uses isomorphic-git should be in that Worker too.
- In that case, isomorphic-git doesn't need serializable arguments at all.
Therefore the plugin system and its awkward global state and funky namespace "cores" are gone, replaced by a vastly simpler collection of callback arguments. The new code is safer, has better locality when you're reading it, and enables some cool new behaviors like canceling running functions and infinite retry for interactive authentication.
A number of other changes, such as returning
Uint8Array instead of
Buffer, were done to pave the way for future refactoring.
The size of the library can be shrunk significantly if we drop the
Buffer polyfill dependency.
Plus, Webpack 5 reportedly won't provide node polyfills automatically.
As always, all the functions are
async and take named arguments, which makes adding new features without breaking old ones easy! I'm a huge fan of this pattern, and I think it's been very successful.
It is safe to say that the API for isomorphic-git will remain backwards compatible and have no breaking changes for at least a year, possibly two or three.
Because I want you to always be able to upgrade to the latest and greatest version of
isomorphic-git without having to change any of your code.
Except for today. Today, we are making breaking changes because it is a major release.
A HUGE THANK YOU to everyone who used isomorphic-git 0.x. You've been tremendously helpful, and you early adopters have helped make this project of mine fun and fulfilling!
And an even bigger thanks to everyone who contributed directly! Seeing other people help improve the codebase has warmed my heart. And seeing your bug reports at least lets me know it is getting lots of use!
Lastly, I'd like to thank Stoplight, Inc for hiring me and letting me work on isomorphic-git occasionally as part of my regular day job! Everyone has benefitted from the bugfixes, perf, and usability enhancements that have resulted from our using isomorphic-git in our world-class API designer, Stoplight Studio.
1.0 Breaking Changes
- The supported node & browser versions have been bumped. (See beautiful table above.)
- The plugin system has been eliminated and we're back to plain old dependency injection via function arguments! The plugin cores created a mysterious "global state" that makes it easy to trip up (I myself sometimes forgot to unset plugins after running tests). The old style of passing
fsas a function argument was less aesthetic and more verbose, but it is a much simpler model than the plugin core model, and much safer because it makes it impossible for dependencies to accidentally share the default plugin core.
emitterplugin has been replaced with
credentialManagerplugin has been replaced with
fsplugin has been replaced with an
httpplugin has been replaced with an
pgpplugin has been replaced with an
- There is an additional setup step to choose which
httpclient to use, and functions that make HTTP requests have a new required
httpparameter. Previously I used a mix of bundler and runtime magic to try and pick between a build that used
fetchand one that used
require('http')but that didn't always work. For instance, if you were bundling a node application using Webpack, it would pick the wrong build (#938). Another example: in an Electron renderer thread, both options could work (if the window is launched with
nodeIntegration: true) but in a Web Worker thread only the fetch option should work (unless you have
nodeIntegrationInWorker: trueset). See "Getting Started" below to see the extra line of code you need.
- The files in the package have been renamed so the import paths are short and sweet:
index.js(the future has arrived)
Some functions have been renamed or removed:
walkBeta2function was renamed to
walkBeta1function was removed.
fastCheckoutfunction has been renamed
checkoutand the old
checkouthas been removed.
- The (previously deprecated)
signfunction was removed.
- The (previously deprecated)
utils.authfunction was removed.
- The (previously deprecated)
configfunction has been removed and replaced by
verifyfunction has been removed, but
readTagall return the
payloadnow. This actually makes verification simpler and more efficient, because it can be done in batch on
git.logoutput and the
gpgsigitself can be parsed and used to lookup the public key. See onSign for complete code examples.
Some function parameters have been removed or replaced:
- The undocumented parameter aliases
emitterparameter was removed and replaced with the
onProgresscallbacks. (Note that
onMessageemits un-trimmed strings, so you get those
oauth2formatparameters were removed and replaced with the
pullwas removed, since there is no "slow" implementation anymore.
logwas removed, since
logwill always return a payload.
patternparameter was removed from
statusMatrixand replaced with a new
filterfunction. (This is so we can drop the dependencies on
newSubmoduleBehaviorparameter was removed and is now the default and only behavior, because it makes much more sense to have non-destructive defaults!
noSubmodulesparameter was removed because with the new submodule behavior it is no longer necessary to print console warnings about how submodules aren't supported. (When submodule support IS added to isomorphic-git, it will be opt-in using
recurseSubmodules: trueor something like that.)
autoTranslateSSHfeature was removed, since it is trivial to implement your own version using just the
writeObjectfunction when used to write a tree now expects a plain array rather than an object with a property called
entrieswhich is the array. (This is so that argument to
writeObjecthas the same shape as the arguments to
noOverwriteparameter was removed from
initand is the new behavior.
tagger.dateparameters were removed in favor of
tagger.timestampin order to be clear about what is actually written and share the same shape as the return types in
The return types of some functions have changed:
- Functions that used to return
Bufferobjects now return
Uint8Arrayobjects. (This is so we can eventually remove all internal dependencies on the Buffer browser polyfill, which is quite heavy!)
logfunction now returns an array of the same kind of objects that
readCommitreturns. (This change simplifies the type signature of
logso we don't need function overloading; that function overloading was the one thing preventing me from auto-generating
readObjectfunction returns a proper discriminated union so TypeScript can infer the type of
.objectonce you establish the value of
.objecthas the same shape as as the return value of
readTree. (Meaning trees are now plain arrays rather than objects with a
.entriesproperty that is the array.)
Some function behaviors have changed
pushfunction now pushes to the remote tracking branch (rather than a branch with the same name) by default.
Docs and DX improvements
docs/alphabetic.mdand function list in
README.mdare auto-generated from the filenames in
- Nearly the entire docs website is auto-generated from the JSDoc actually so keeping the docs website and source code in sync is easier.
- All the example code in JSDoc is now type-checked during CI tests.
- The live code examples on the website are displayed in a full-blown mobile-friendly code editor (CodeMirror 6).
- Each page with live code examples includes a code snippet at the bottom to reset the browser file system.
- The Getting Started guide has been updated.
- All the example code in JSDoc has been updated.
- Update the README to recommend LightningFS rather than BrowserFS.
internal-apisbundle is no longer included in the published package. That was only being built to run the unit tests.