Share Extension

(Other Languages : Fran├žais)

This extension is distributed with Mercurial 1.3 and later

Author: Olivia Mackall

1. Overview

This extension allows for sharing the 'store' (ie history) portion of a repository with one or more other locally-accessible repositories while maintaining an independent working directory state. This can make creating a working directory for a branch faster and less expensive. It can also be used for a simple collaboration mode as all commits immediately appear in the history of sharing repositories without the need for push or pull.

$ hg share project project-branch
updating working directory
1040 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg share /path/to/network/project  # creates 'project'
5298 files updated, 0 files merged, 0 files removed, 0 files unresolved

2. General caveats

Note that an operation performed in any shared repository will immediately affect all of its peers. In effect, it is as though commit instantly and atomically pushes to the repository's parent and all of its siblings (i.e. any other shared clones of the same parent). But, of course, there is no push: commit simply writes in the .hg/store directory shared by all peers.

In particular, operations that destroy or modify history -- strip, rebase, etc. -- will also destroy or modify history in all of the shared clone's peers. For example, if you accidentally strip too many revisions in a shared clone, poof! you've just stripped those revisions from all of its peers. If you are experimenting with destructive operations, you should make a full clone and play around in it first.

Also, think carefully about the interaction between Mercurial Queues (MqExtension). Because .hg/patches is not shared between repositories, it's possible for different shared repositories to have independent patch queues. But MQ commands like qpush and qpop create and destroy history, so pushing/popping patches will affect all of the shared clone's peers. It's probably not a good idea to mix MQ and shared clones; if you do so, you should definitely avoid pushing/popping patches in one clone while another clone has patches applied.

In short, this is a small modification that deeply affects Mercurial's usual "clones are independent" contract. Make sure you understand what it does before you shoot yourself in the foot!

2.1. Specific caveat: be careful with rollback

Keep in mind that rollback destroys history, so should also be used with care in shared clones. You can get yourself in a bit of a mess if one shared clone destroys the changeset that is currently "in use" by one of its peers. For example, say you have R1 and R2 sharing a repository. (They could be peers, or one could be a shared clone of the other: it doesn't really matter.) Here's one way to get yourself in trouble.

First, create a new changeset C:

cd R1
hg commit -m"Fix stuff"

Naturally, C becomes the "current" changeset for R1 (first parent of the working dir). Now switch to R2 and update to the new changeset:

cd ../R2
hg update

so that both R1 and R2 are using changeset C. Now what happens if you decide to rollback the commit?

cd ../R1
hg rollback

Looks fine so far: R1 is correctly moved back to the parent of C. But what about R2?

cd ../R2
hg status
abort: working directory has unknown parent 'dcd1496287c5'!

Oops! You've badly confused Mercurial in R2 because you destroyed history in R1, and there was no way for the working dir in R2 to be updated.

Luckily, there's a pretty simple workaround: in R2, run

hg debugsetparents <revision>

where revision identifies the changeset that R2 should be using now: possibly tip, or default, or another branch name.

3. Configuration

Configure your .hgrc to enable the extension by adding following lines:

share =

A shared repository stores the path to its parent in the file .hg/sharedpath. Changing this allows you to move the parent or child.

4. See also


ShareExtension (last edited 2022-08-21 00:49:52 by JeffCutsinger)