creationix / tedit

Chrome app for tedit
https://chrome.google.com/webstore/detail/tedit-development-environ/ooekdijbnbbjdfjocaiflnjgoohnblgf
ISC License
188 stars 27 forks source link

Implement basic sync and offline mode for github-mount mode #50

Open creationix opened 10 years ago

creationix commented 10 years ago

This needs to be a new js-git mixin that performs sync between arbitrary js-git instances.

// options.localRef - local ref to sync
// options.remoteRef - remote ref to sync
// options.localDepth - Depth for shallow local clones
local.sync(remote, options, function (err, report) {
  // report.sent - number of hashes sent
  // report.received - number of hashes received
  // report.ahead - number of commits we have ahead of remote
  // report.behind - number of commits we have behind remote
  // if ahead and behind are non-zero, then the repos have diverged
  // if they haven't diverged then one side can fast-forward.
});

The algorithm needs to favor reading from the local repo, even when discovering what the remote has. Assume the remote is always a full (non shallow) repo with no dangling links.

So, for example, if you want to push commit B (who's parent is A) and you know remote has A, you can scan the tree of local A to see what remote A would have.

creationix commented 10 years ago

After we have this basic sync, we need basic merge.

creationix commented 10 years ago

Example of "clone" using js-github for remote and git-node-fs for local. This is actually a full sync and will push changes if the local repo exists.

var local = {};
require('git-node-fs/mixins/fs-db')(local, "path/to/repo.git");
require('js-git/mixins/sync')(local);

var remote = {};
require('js-github/mixins/github-db')(remote, "creationix/js-git", githubToken);

// Assume we're running in a gen-run block with generators
var localRef = "refs/heads/master";
var remoteRef = "refs/heads/master";

var report = yield local.sync(remote, {
  localRef: localRef,
  remoteRef: remoteRef,
  localDepth: 1
});

if (report.ahead) {
  if (report.behind) {
    throw "TODO: Implement merge"
  }
  // Fast-forward the remote master to match local's master
  yield remote.updateRef(remoteRef, yield local.readRef(localRef));
}
else {
  if (report.behind) {
    // Fast-forward the local master to match the remote's master
    yield local.updateRef(localRef, yield remote.readRef(remoteRef));
  }
}