Git Implemented in JavaScript.
This project is very modular and configurable by gluing different components together.
This repo, js-git
, is the core implementation of git and consumes various instances of interfaces. This means that your network and persistance stack is completely pluggable.
If you're looking for a more pre-packaged system, consider packages like creationix/git-node
that implement all the abstract interfaces using node.js native APIs. The creationix/jsgit
package is an example of a CLI tool that consumes this.
The main end-user API as exported by this module for working with local repositories is:
First you create an instance of the library by injecting the platform dependencies.
var platform = require('git-node-platform');
var jsGit = require('js-git')(platform);
Then you implement the database interface (or more likely use a library to create it for you).
var fsDb = require('git-fs-db')(platform);
var db = fsDb("/path/to/repo.git");
The database interface is documented later on.
In all public async functions you can either pass in a node-style callback last or omit the callback and it will return you a continuable.
This means you can consume the js-git library using normal ES3 code or if you prefer use gen-run and consume the continuables.
If the callback is omitted, a continuable is returned. You must pass a callback into this continuable to actually start the action.
// Callback mode
jsgit.someAction(arg1, arg2, function (err, result) {
...
});
// Continuable mode
var cont = jsgit.someAction(arg1, arg2);
cont(function (err, result) {
...
});
// Continuable mode with gen-run
var result = yield jsgit.someAction(arg1, arg2);
Load a ref or object from the database.
The database should assume that keys that are 40-character long hex strings are sha1 hashes. The value for these will always be binary (Buffer
in node, Uint8Array
in browser)
All other keys are paths like refs/heads/master
or HEAD
and the value is a string.
Save a value to the database. Same rules apply about hash keys being binary values and other keys being string values.
Check if a key is in the database
Remove an object or ref from the database.
Given a path prefix, give all the keys. This is like a readdir if you treat the keys as paths.
For example, given the keys refs/heads/master
, refs/headers/experimental
, refs/tags/0.1.3
and the prefix refs/heads/
, the output would be master
and experimental
.
A null prefix returns all non hash keys.
Initialize a database. This is where you db implementation can setup stuff.
This is for when the user wants to delete or otherwise reclaim your database's resources.
Now that you have a database instance, you can use the jsGit library created above.
var repo = jsGit(db);
Load a git object from the database. You can pass in either a hash or a symbolic name like HEAD
or refs/tags/v3.1.4
.
The object will be of the form:
{
type: "commit", // Or "tag", "tree", or "blob"
body: { ... } // Or an array for tree and a binary value for blob.
}
Save an object to the database. This will give you back the hash of the cotent by which you can retrieve the value back.
This convenience wrapper will call repo.save
for you and then check if the type is what you expected. If it is, it will return the body directly. If it's not, it will error.
var commit = yield repo.loadAs("commit", "HEAD");
var tree = yield repo.loadAs("tree", commit.tree);
I'm using yield syntax because it's simpler, you can use callbacks instead if you prefer.
Another convenience wrapper, this time to save objects as a specefic type. The body must be in the right format.
var blobHash = yield repo.saveAs("blob", binaryData);
var treeHash = yield repo.saveAs("tree", [
{ mode: 0100644, name: "file.dat", hash: blobHash }
]);
var commitHash = yield repo.saveAs("commit", {
tree: treeHash,
author: { name: "Tim Caswell", email: "[email protected]", date: new Date },
message: "Save the blob"
});
Remove an object.
Import a packfile stream (simple-stream format) into the current database. This is used mostly for clone and fetch operations where the stream comes from a remote repo.
opts
is a hash of optional configs.
opts.onProgress(progress)
- listen to the git progress channel by passing in a event listener.opts.onError(error)
- same thing, but for the error channel.opts.deline
- If this is truthy, the progress and error messages will be rechunked to be whole lines. They usually come jumbled in the internal sidechannel.
This convenience wrapper creates a readable stream of the history sorted by author date.
If you want full history, pass in HEAD
for the hash.
This helper will return a stream of files suitable for traversing a file tree as a linear stream. The hash can be a ref to a commit, a commit hash or a tree hash directly.
This is the generic helper that logWalk
and treeWalk
use. See js-git.js
source for usage.
Resolve a ref, branch, or tag to a real hash.
Update whatever branch HEAD
is pointing to so that it points to hash
.
You'll usually want to do this after creating a new commint in the HEAD branch.
Read the current active branch.
Set the current active branch.
Convenience wrapper that fetches from a remote instance and calls repo.unpack
with the resulting packfile stream for you.
Being that js-git is so modular, here is a list of the most relevent modules that work with js-git:
- https://github.com/creationix/git-net - A generic remote protocol implementation that wraps the platform interfaces and consumes urls.
- Example Applications
- https://github.com/creationix/git-browser - A multi-platform GUI program that clones and browses git repos.
- https://github.com/creationix/jsgit - An example of using js-git in node. This is a CLI tool.
- https://github.com/creationix/git-node - A packaged version of js-git made for node.js
- Platform Helpers
- https://github.com/creationix/git-http - A git-http platform interface adapter that wraps git-tcp platform instances.
- https://github.com/creationix/git-node-platform - Just the platform interface for using js-git on node.js.
- https://github.com/creationix/git-sha1 - A pure-js implementation of the sha1 part of the platform interface.
- https://github.com/creationix/git-web-platform - An implementation of js-git platform for browsers.
- https://github.com/creationix/websocket-tcp-client - An implementation of the git-tcp interface that consumes a websocket to tcp proxy server.
- https://github.com/creationix/git-zlib - A pure-js implementation of the zlib parts of the platform interface.
- Storage Backends
- https://github.com/creationix/git-fs-db - A database interface adapter that wraps a fs interface.
- https://github.com/creationix/git-localdb - A git-db implementation based on
localStorage
. - https://github.com/creationix/git-memdb - A git-db implementation that stores data in ram for quick testing.
- https://github.com/aaronpowell/git-indexeddb - A git-db implementation cased on
indexedDB
.