RelatedSoftware/Unison

Unison is a file synchronization tool. Think bidirectional interactive rsync.

Unison is useful when you don’t need history and complex merging, and Darcs would be overkill. If you are careful, it can also be used for distributing a darcs repository across multiple computers when the usual push/{{{pull}}} mode of operation of Darcs is not convenient. (Note: using Unison with DarcsTwo is much safer than using it with prior versions of darcs. These instructions were written before DarcsTwo, so you can mostly disregard them if you are using a darcs2 repository)

Unison is available from http://www.cis.upenn.edu/~bcpierce/unison/ .

Below are some ways that you can combine darcs with unison

Option 1: no unison

Do not put any darcs-managed directories in a location that is synchronised by Unison. For example, you can could have a synch directory for unison and a darcs directory for darcs. To keep things local, that is, to avoid writing into any public repositories, you can restrict your pushing and pulling from your laptop to your workstation.

Advantages:

  • safe
  • ability to perform darcs operations on both machines

Disadvantages:

  • have to remember to darcs record (or log back into the other machine)
  • may have to record work in progress, even crappy stuff that doesn’t compile yet

Option 2: limited unison

The safest bet is to only use Unison for propagating unrecorded changes, and use Darcs itself to propagate recorded changes.

In order to prevent Unison from propagating files under _darcs, put something like this in your unison preferences file: ignore = Name _darcs

Advantages:

  • simplicity of just using unison to synchronise between machines
  • safe

Disadvantages:

  • can only do darcs operations on one of the machines
  • a parent folder rename will delete the _darcs folder! From Unison manual: Ignoring Paths:

    Be careful about renaming directories containing ignored files. Because Unison understands the rename as a delete plus a create, any ignored files in the directory will be lost (since they are invisible to Unison and therefore they do not get recreated in the new version of the directory).

Option 3: full unison (RISKY!)

Riskier but acceptable if very very very careful

A riskier behaviour is to allow Unison to propagate _darcs, but make sure you systematically unison every time you switch machines (do you actually remember to do this?). The idea, for example, is that you are never really using both machines at the same time, a workstation in the office and a laptop at home.

This is not usually the discipline unison users have! We are used to sometimes working on both machines and occasionally remembering that we need to run unison to keep things in synch. Realistically, will you always remember to unison BEFORE and AFTER using your laptop?

Advantages

  • simple and convenient; no need to think about darcs stuff

Disadvantages

  • strict discipline required to unison at every “switch”
  • very easy to make mistakes

Things that can go wrong

Renaming a file for case

This can be an issue if you are using a case insensitive filesystem, and you change the case of one of your files, for example:

darcs mv Foo foo

So far the solution seems to be to delete the file in both working and pristine directory on the receiving end, and then use unison to transfer them over.

Just be careful though. Unison will not understand what to do with this, so you must help it along:

Deleted <-?->             Foo
        <---- Created     foo

The idea is that you want to ignore the deletion of the old Foo, but propagate the creation of the new ‘foo’. (I assume here that the ‘receiving’ end is on the left side).

Not unisoning between each record

So this siutation is ok:

machineA: do some stuff; darcs record
unison
machineB; do some stuff; darcs record
unison
# ok

But this situation is very bad:

# BAD! repository corruption possible
machineA: do some stuff; darcs record
machineB: do some stuff; darcs record
unison
# BAD! repository corruption possible

The risk is forgetting to run Unison after each set of darcs records, in which case you might corrupt both repositories. Which is why we recommend to use Darcs to propagate recorded changes.

Deleting and modifying a file

machineA: rm foo; darcs record
unison
# unison gets confused and copies the file from machineB back into machineA
machineA: modify foo; darcs record

Variant:

machineA: modify foo
machineB: rm foo; darcs record
unison
# you or unison get confused and you copy the file from machineA into machine B
machineA (or machineB): darcs record

What went wrong here? You’ve just made a diff on a file which no longer exists! Your repository is now inconsistent because unison just copied a file back into _darcs/current that had previously been deleted

But this (unison copying back files) won’t happen if you use unison -force <machineA/darcs-repo>.