What is isomorphic-git?
isomorphic-git is a pure JavaScript implementation of Git that works in both Node.js and browser environments. It provides a wide range of Git functionalities, allowing developers to perform Git operations without relying on native Git installations.
What are isomorphic-git's main functionalities?
Clone a Repository
This feature allows you to clone a Git repository. The code sample demonstrates how to clone the isomorphic-git repository into a local directory named '/tutorial'.
const git = require('isomorphic-git');
const fs = require('fs');
(async () => {
await git.clone({
fs,
dir: '/tutorial',
url: 'https://github.com/isomorphic-git/isomorphic-git',
singleBranch: true,
depth: 1
});
console.log('Cloned the repository!');
})();
Commit Changes
This feature allows you to commit changes to a repository. The code sample demonstrates how to commit changes in the '/tutorial' directory with a commit message 'Initial commit'.
const git = require('isomorphic-git');
const fs = require('fs');
(async () => {
await git.commit({
fs,
dir: '/tutorial',
author: {
name: 'Your Name',
email: 'you@example.com'
},
message: 'Initial commit'
});
console.log('Committed changes!');
})();
Push to Remote
This feature allows you to push changes to a remote repository. The code sample demonstrates how to push changes from the '/tutorial' directory to the 'main' branch of the remote repository 'origin'.
const git = require('isomorphic-git');
const fs = require('fs');
(async () => {
await git.push({
fs,
dir: '/tutorial',
remote: 'origin',
ref: 'main',
token: 'your-github-token'
});
console.log('Pushed to remote!');
})();
Fetch from Remote
This feature allows you to fetch changes from a remote repository. The code sample demonstrates how to fetch changes from the 'origin' remote repository into the '/tutorial' directory.
const git = require('isomorphic-git');
const fs = require('fs');
(async () => {
await git.fetch({
fs,
dir: '/tutorial',
remote: 'origin'
});
console.log('Fetched from remote!');
})();
List Files in a Commit
This feature allows you to list files in a specific commit. The code sample demonstrates how to read the commit object for the 'HEAD' commit and log the tree of files.
const git = require('isomorphic-git');
const fs = require('fs');
(async () => {
const commit = await git.readCommit({
fs,
dir: '/tutorial',
oid: 'HEAD'
});
console.log(commit.commit.tree);
})();
Other packages similar to isomorphic-git
nodegit
NodeGit is a native Node.js binding to the libgit2 library, providing a comprehensive set of Git functionalities. Unlike isomorphic-git, NodeGit relies on native bindings and is not designed to work in browser environments.
simple-git
Simple-git is a lightweight wrapper around the Git command line interface, providing a simple API for common Git operations. It requires Git to be installed on the system and is not designed to work in browser environments, unlike isomorphic-git.
dugite
Dugite provides a simplified interface for using Git in Node.js applications. It bundles a specific version of Git with the package, ensuring consistent behavior across different environments. However, it does not support browser environments like isomorphic-git.
isomorphic-git
A pure JavaScript implementation of git for node and browsers!
isomorphic-git
is a pure JavaScript implementation of git that works in node and browser environments (including WebWorkers and ServiceWorkers). This means it can be used to read and write to to git repositories, as well as fetch from and push to git remotes like Github.
Isomorphic-git aims for 100% interoperability with the canonical git implementation. This means it does all its operations by modifying files in a ".git" directory just like the git you are used to. The included isogit
CLI can operate on git repositories on your desktop or server.
isomorphic-git
aims to be a complete solution with no assembly required.
I've tried carefully to design the API so it is easy to use all the features, without paying a penalty in bundle size.
By providing functionality as separate functions instead of an object oriented API, code bundlers like Webpack will only include the functionality your application actually uses. (Or at least that's the goal.)
I am working on adding type definitions so you can enjoy static type-checking and intelligent code completion in editors like CodeSandbox.
Table of Contents generated with DocToc
Getting Started
The "isomorphic" in isomorphic-git
means it works equally well on the server or the browser.
That's tricky to do since git uses the file system, and browsers don't have an 'fs' module.
So rather than relying on the 'fs' module, isomorphic-git
is BYOFS (Bring Your Own File System).
When creating a new Git object, you pass it the fs module to use.
If you're only using isomorphic-git
in Node, you can just use the native fs
module.
const git = require('isomorphic-git');
const fs = require('fs');
git.listFiles({fs, dir: __dirname});
If you're writing code for the browser though, you'll need something that emulates the fs
API.
At the time of writing, the most complete option is BrowserFS.
It has a few more steps involved to set up than in Node, as seen below:
<script src="https://unpkg.com/browserfs"></script>
<script src="https://unpkg.com/isomorphic-git"></script>
<script>
BrowserFS.configure({ fs: "IndexedDB", options: {} }, function (err) {
if (err) return console.log(err);
window.fs = BrowserFS.BFSRequire("fs");
git.listFiles({fs: window.fs, dir: '/'});
});
</script>
Besides IndexedDB, BrowserFS supports many different backends with different performance characteristics, as well as advanced configurations such as: multiple mounting points, and overlaying a writeable filesystems on top of a read-only filesystem. You don't need to know about all these features, but familiarizing yourself with the different options may be necessary if you hit a storage limit or performance bottleneck in the IndexedDB backend I suggested above.
Using as an npm module
You can install it from npm.
npm install --save isomorphic-git
In the package.json you'll see there are actually 4 different versions:
"main": "dist/for-node/",
"browser": "dist/for-browserify/",
"module": "dist/for-future/",
"unpkg": "dist/bundle.umd.min.js",
This probably deserves a brief explanation.
- the "main" version is for node.
- the "browser" version is for browserify.
- the "module" version is for native ES6 module loaders when they arrive.
- the "unpkg" version is the UMD build.
For more details about each build see ./dist/README.md
isogit
CLI
Isomorphic-git comes with a simple CLI tool, named isogit
because isomorphic-git
is a lot to type. It is really just a thin shell that translates command line arguments into the equivalent JS API commands. So you should be able to run any current or future isomorphic-git commands using the CLI.
It always starts with an the assumption that the current working directory is a git root.
E.g. repo = new Git({fs, dir: '.'})
.
It uses minimisted
to parse command line options.
TODO: Document this more. Also write some tests? IDK the CLI is more of a lark for testing really.
Supported Git commands
I may continue to make changes to the API until the 1.0 release, after which I promise not to make any breaking changes.
NEW DOCS WEBSITE
commands
utils
dir vs gitdir
I looked hard and wide for a good explanation of the "working tree" and the "git directory" and the best I found was this one from Stack Overflow:
If you have a non-bare git repository, there are two parts to it: the git directory and the working tree:
- The working tree has your checked out source code, with any changes you might have made.
- The git directory is normally named
.git
, and is in the top level of your working tree - this contains all the history of your project, configuration settings, pointers to branches, the index (staging area) and so on.
While this is the default layout of a git repository, you can actually set any directories in the filesystem to be your git directory and working tree. You can change these directories from their defaults either with the --work-tree and --git-dir options to git or by using the GIT_DIR and GIT_WORK_TREE environment variables. Usually, however, you shouldn't need to set these.
In isomorphic-git the equivalent of --work-tree
is the dir
argument.
In isomorphic-git the equivalent of --git-dir
is the gitdir
argument.
This is really only important when working with bare repositories.
Internal code architecture
I have written this library as a series of layers that build upon one another and should tree-shake very well:
Commands
Each command is available as its own file, so you are able to import individual commands
if you only need a few in order to optimize your bundle size.
Managers
Managers are a level above models. They take care of implementation performance details like
- batching reads to and from the file system
- in-process concurrency locks
- lockfiles
- caching files and invalidating cached results
- reusing objects
- object memory pools
Models and Utils
Models and utils are the lowest level building blocks.
Models generally have very few or no dependencies except for 'buffer'
.
This makes them portable to many different environments so they can be a useful lowest common denominator.
Utils are basically miscellaneous functions.
Some are convenience wrappers for common filesystem operations.
Who is using isomorphic-git?
- nde - a futuristic next-generation web IDE
- git-app-manager - install "unhosted" websites locally by git cloning them
Similar projects
Acknowledgments
Isomorphic-git would not have been possible without the pioneering work by
@creationix and @chrisdickinson. Git is a tricky binary mess, and without
their examples (and their modules!) I would not have been able to come even
close to finishing this. They are geniuses ahead of their time.
License
This work is released under The Unlicense