repofs
This module provides a simple and unified API to manipulate Git repositories on GitHub. This module can be use in Node.JS and in the browser.
It allows more complex operations than the Contents API using the Git Data API.
It is powered by an immutable model. Async operations are Promise-based.
Installation
$ npm install repofs
How to use it?
To use repofs
in the browser, include it using browserify/webpack.
var repofs = ;
Initialize a driver instance, a driver represents the communication layer between repofs and the real git repository.
var driver = repofs;
Start with an empty RepositoryState
The first step is to create an instance of RepositoryState
:
var repoState = repofsRepositoryState;
Fetch the list of branches
After creating a RepositoryState
, the next step is to fetch the list of existing branches.
repofsRepoUtils
Checkout a branch
Once the branches are fetched, you can checkout one. This requires to fetch it first using repofs.RepoUtils.fetchTree
. This overrides any existing working tree for this branch. The repofs.RepoUtils.checkout
operation is always sync.
var branch = repoState; repofsRepoUtils
Quick initialization
There is a short way to initialize a RepositoryState
from a driver, that will fetch the list of the branches, then fetch and checkout master or the first available branch.
repofsRepoUtils;
Reading files
Reading a file requires to fetch the content from the remote repository inside the RepositoryState
(See Caching):
repofsWorkingUtil
Then the content can be accessed using sync methods:
// Read as a blobvar blob = repofsFileUtils; // Read as a Stringvar content = repofsFileUtils;
Listing files
repofs keeps the whole trees in the different WorkingStates
, you can access the whole tree as a flat list...
var workingState = repoState;var treeEntries = workingState;
... or as an immutable tree structure (a TreeNode<File>
):
var dir = '.' // rootvar rootTree = repofsTreeUtils;
Working with files
Create a new file:
var newRepoState = repofsFileUtils;
Write/Update the file
var newRepoState = repofsFileUtils;
Remove the file
var newRepoState = repofsFileUtils;
Rename/Move the file
var newRepoState = repofsFileUtils;
Working with directories
List files in the directory
var pathList = repofsDirUtils;
Remove the directory
var newRepoState = repofsDirUtils;
Rename/Move the directory
var newRepoState = repofsDirUtils;
Changes
Until being commited, repofs keeps a record of changes per files.
Revert all non-commited changes using:
var newRepoState = repofsChangeUtils;
Or revert changes for a specific file or directory:
// Revert change on a specific filevar newRepoState = repofsChangeUtils; // Revert change on a directoryvar newRepoState = repofsChangeUtils;
Commiting changes
// Create an author / committervar john = repofsAuthor; // Create a CommitBuilder to define the commitvar commitBuilder = repofsCommitUtils; // Flush commit using the driverrepofsCommitUtils;
Manipulating branches
// Create a branch from current branchrepofsBranchUtils;
// Remove a branchrepofsBranchUtils;
Non fast forward commits
Flushing a commit can fail with an ERRORS.NOT_FAST_FORWARD
code.
// Flush commit using the driverrepofsCommitUtils;
Non fast forward errors contains the created commit (that is currently not linked to any branch). This allows you to attempt to merge this commit back into the current branch:
... { // Catch non fast forward errors iferrcode !== repofsERRORSNOT_FAST_FORWARD throw err; // The created commit var commit = errcommit; // Attempt automatic merge var from = commit; var into = repoState; return repofsBranchUtils ;}
Merging
repofs.BranchUtils.merge
allows to automatically merge a commit or a branch, into another branch.
// from is either a Branch or a commit SHA stringrepofsBranchUtils;
Merge conflicts
But conflicts can happen when the automatic merge failed. For example, after merging two branches, or after merging a non fast forward commit. It is possible then to solve the conflicts manually:
repofsBranchUtils;
The function solveConflicts
would compute the TreeConflict
representing all the conflicts between from
and into
references, solve it in some ways, and make a merge commit. Here is an example of such function:
{return repofsConflictUtils;}
Remotes operations
When using a compatible API, you can also deal with remotes on the repository.
List remotes
repofsRemoteUtils;
Edit remotes
repofsRemoteUtils;
Pulling
You can update a branch to the state of the same branch on a remote, and get an updated RepositoryState
with:
var master = repoState;var remote =name: 'origin';repofsRemoteUtils
Pushing
You can push a branch to a remote:
var master = repoState;var remote = name: 'origin'; repofsRemoteUtils
Contributing
Run tests
You can run all the tests by providing a GITHUB_TOKEN
with permission to create and write to a GitHub repository, and running npm run test
.
You can run tests with GitHub as a backend npm run test-github
, or Uhub as a backend npm run test-uhub
.
Finally, you can run the tests without testing the API through the drivers by running npm run test-no-api
.