How to Keep (Files on) Multiple Computers Synchronized as a Single Developer

This page describes how a single developer (also referred to in this Wiki as a LoneDeveloper or IndividualDeveloper) can use Mercurial to synchronize files on multiple computers.

There are at least three applications of single developer with multiple computers, which can apply in combination:

  1. Synchronization between a laptop and desktop
  2. Synchronizaton between a computer at work and another at home
  3. Replication for backup; to increase safety beyond simple replication:
    • use a RAID mirrored drive (not technically "multiple computers" but follows the same workflow)
    • use a LAN-accessible shared drive that is automatically backed up offsite
    • use a hosted repository service such as bitbucket

A special case of synchronization is worth pointing out: synchronizing settings files such as "rc files" ("dot files"), preferences, application settings, system and application extensions, etc. I am forever fiddling with shell initialization files, Emacs initialization and macro files, utility scripts (shell, AppleScript, Python, etc.), abbreviation expansions, "keystroke macros" (with facilities that have grown to do much more than that label implies), application templates, extensions (downloaded modules and libraries, application add-ons, browser extras, etc.) and so on. I use one desktop at work, another at home, and a laptop, and keeping my "environment" synchronized manually among the three computers was extremely tedious (and therefore a task I generally avoided, leading to divergent behavior on each). Ordinary tools for "folder synchronization" and backup were insufficiently flexible or powerful for this purpose. Mercurial is just what I needed: a simple, lightweight, peer-to-peer, mechanism for tracking and coordinating changes

Background

I think the main difficulty I had when trying to setup synchronization among my computers using Mercurial was that the commands and workflows I needed were those intended for sharing among multiple developers. It took me a while to realize that from the standpoint of the computers involved, I am a different developer on each machine. I needed to think in terms of sharing with multiple virtual selves, rather than following workflows described for a SingleDeveloper (e.g., http://mercurial-scm.org/guide/#lone_developer).

Mercurial is a distributed peer-to-peer version control system -- there is no centralized repository the others draw from. Changes in one clone of a repository can be pushed to or pulled from any other one, including the original. A critical, and not necessarily obvious, aspect of this peer-to-peer sharing is that all copies must start out as clones of the original or one of the other: when a repository is initialized it gets an identification key, and when a repository is cloned its key comes along with it.

Mercurial will refuse to perform operations between repositories that don't share a key. Therefore, even though we are trying to synchronize several pre-existing directories, we have to initialize one first then clone it to the other locations. However, Mercurial won't clone to a non-empty directory, and besides, we wouldn't want it to uncontrollably overwrite existing files that differ from the corresponding file in the repository. The procedure required to link together a set of separate, similar, non-version-controlled directory trees is as follows.

Setting Up the Repositories

Start in the directory you want to act as the "original" copy of the set and follow steps 1 and 3 of QuickStart. [Note that although step 3 is labeled "setting up a new repository", it really means "turning an existing directory into a repository": the cd command example in step 1 refers to a directory containing the files you want in your (initial version of) the original repository.]

Next, on each of the other computers:

  1. Move the target directory to a different location.
  2. Clone the original repository to the location just abandoned by following step 2 of QuickStart. [The example there uses http:, but the primary repository is on the same computer or one accessible on the LAN you can just specify its path as if you were copying one directory to another. You can also use ssh to access a repository, as described below.]

  3. Use system tools and applications to manually copy files from the moved directory to the clone and edit the cloned files to include differences from files in the moved directory.
  4. Commit, push the changes to the original, and update the original.

Access via SSH

A straightforward way to access repositories on a different machine without bothering with http or hg servers is to use ssh. Just use an ssh address when cloning a repository on a different machine, e.g.

hg clone ssh://example.com/path/to/repository

An import thing to note is that "path" is relative to your home directory on the remote machine.

If you need to go in through a different port, simply add ":portnum" after the hostname (e.g., example.com:2201). To specify a username, add username@ before the hostname (e.g., user@example.com ). Once you've cloned a repository using ssh, further interaction will default to using ssh with the same parameters. You'll find this information on the "default = " line of .hg/hgrc in the cloned repository.

Notes

If you screw something up in one of the repositories, removing its .hg directory removes all traces of Mercurial from the directory (except for the .hgignore file you should have put there). Then, you can go through the steps of setting up the repository again.

It is always safe to modify files and directories in clones by hand (i.e., using command-line commands, editors, file comparison software, etc.). All Mercurial keeps track of is modification dates and file size (I think). Changing files and directories in a clone will simply be noted in response to diff commands or when one clone is pushed to or pulled from another. In the extreme, you could clone a repository, delete everything in it except the .hg directory and .hgignore file in the cloned directory and copy back all the files that were there before you moved them out of the way. You would then use Mercurial to combine this version of the directory tree with the one it was cloned from.


CategoryHowTo CategoryTipsAndTricks

SingleDeveloperMultipleComputers (last edited 2010-04-03 04:44:45 by MitchellModel)