Differences between revisions 5 and 6
Revision 5 as of 2015-08-24 23:57:58
Size: 2414
Editor: Rain
Comment:
Revision 6 as of 2015-08-25 00:07:22
Size: 3142
Editor: Rain
Comment:
Deletions are marked like this. Additions are marked like this.
Line 12: Line 12:
* Enable instantaneous one-way sync of a Mercurial working directory from one machine to another.
* Do not require explicit commits or pushes to make the sync happen.
* Assume that network flakiness is a rare event and will not generally happen. (This makes it unsuitable for many laptop-based use cases. This will likely be addressed in future iterations.)
 * Enable instantaneous one-way sync of a Mercurial working directory from one machine to another.
 * Do not require explicit commits or pushes to make the sync happen.
 * Assume that network flakiness is a rare event and will not generally happen. (This makes it unsuitable for many laptop-based use cases. This will likely be addressed in future iterations.)
Line 18: Line 18:
* How to detect whether a working copy has been changed (that will likely be handled by HgwatchmanExtension)  * How to detect whether a working copy has been changed (that will likely be handled by HgwatchmanExtension)
Line 34: Line 34:
=== Why not use rsync/Unison/Dropbox/<insert favorite file sync tool here>? ===

For small repositories, that works great! Not really for larger ones, though. Consider the case where a large update happens from one public commit to another, which changes > 10,000 files. Any of the above tools will try to sync all changed files, even though the only information the remote needs to know is that the public commit you're on has changed -- at that point the server can update to that commit (including possibly fetching those changes over the network, with RemotefilelogExtension).
Line 40: Line 44:
1. Introduce a class called `memrepo` that represents a `localrepository` with in-memory commits. Any commits to it will be stored and serialized in memory. For safety this will be backed by a `readonlyvfs`, preventing writes to disk from any source. === On the client ===

 
1. Introduce a class called `memrepo` that represents a `localrepository` with in-memory commits. Any commits to it will be stored and serialized in memory rather than on-disk. For safety this will be backed by a `readonlyvfs`, preventing writes to disk from any source.
 2. Allow the in-memory commit to be pushed by the same process. This could be done.
 3.

In-Memory Commit Plan

1. The Overall Problem

There should be a lightweight way to transparently sync working copies across repositories in the background. This document covers one part of a proposed implementation.

The initial implementation's goals are:

  • Enable instantaneous one-way sync of a Mercurial working directory from one machine to another.
  • Do not require explicit commits or pushes to make the sync happen.
  • Assume that network flakiness is a rare event and will not generally happen. (This makes it unsuitable for many laptop-based use cases. This will likely be addressed in future iterations.)

Outside this document's scope are:

  • How to detect whether a working copy has been changed (that will likely be handled by HgwatchmanExtension)

1.1. Why would you even want to sync working copies?

Imagine that you're working in a local repository and have local changes. At many organizations, to test your changes you would need to sync the contents over to a remote server to e.g. test by sending a small amount of production traffic.

The usual way to do that is to make an explicit commit and push, then have a hook on the server that updates the test repo to that commit.

hg commit && hg push test-server -r .

This sucks. Making a commit is a heavyweight operation that requires a mental context switch. It adds unnecessary friction to what should be a seamless process -- for a web application, if the server were running locally you would just need to save the file you're editing, run build steps if any, then hit refresh in your browser.

The overall plan allows developers to get the same workflow as with a local server.

1.2. Why not use rsync/Unison/Dropbox/<insert favorite file sync tool here>?

For small repositories, that works great! Not really for larger ones, though. Consider the case where a large update happens from one public commit to another, which changes > 10,000 files. Any of the above tools will try to sync all changed files, even though the only information the remote needs to know is that the public commit you're on has changed -- at that point the server can update to that commit (including possibly fetching those changes over the network, with RemotefilelogExtension).

1.3. Why not just make real commits on disk and strip them when we're done?

That is not atomic -- if hg log is run while a commit is being made and pushed, it's going to result in weird temporary commits being visible. Even if that is taken care of with e.g. a 'pre-secret' phase, the fact that the lock is taken by a background process is still going to be visible.

2. The Plan

2.1. On the client

  1. Introduce a class called memrepo that represents a localrepository with in-memory commits. Any commits to it will be stored and serialized in memory rather than on-disk. For safety this will be backed by a readonlyvfs, preventing writes to disk from any source.

  2. Allow the in-memory commit to be pushed by the same process. This could be done.

WorkingCopySyncPlan (last edited 2015-08-26 17:34:10 by Rain)