Revision ed35777f5cd7878a8802997c5a695bf8e16a4098

DarcsBridgeUsage

============ darcs-bridge ============

What is it?

darcs-bridge translates between git and darcs v2 repos, either as a one-off conversion, or incrementally over time.

How does it work?

Internally, darcs-bridge uses the de-facto standard git fast-import stream format to communicate repository states between git and darcs. See the git fast-import man-page <http://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html>_ for a description of the format.

TODO: more.

How do I use it?

There are several use-cases for darcs-bridge, we give instructions for each, below:

  1. I want to move from Git to Darcs, and not use Git anymore:

Assume we have a local Git repo /home/owen/repos/foo_project and we want to create a darcs mirror under /home/owen/repos/foo_project_darcs.

::

cd /home/owen/repos
mkdir foo_project_darcs
(cd foo_project && git fast-export -M -C --progress=1 <BRANCH_LIST> --) | darcs-fastconvert import foo_project_darcs/master

Here, is a space-separated list of branch names you wish to export, e.g. “master feature1 production”. The master branch will be imported into foo_project_darcs/master and other branches will be alongside the master Darcs repo, in this case: foo_project_darcs/master-head-feature1 and foo_project_darcs/master-head-production.

  1. I want to move from Darcs to Git, and not use Darcs anymore:

Assume we have a local Darcs master repo /home/owen/repos/my_project and darcs-branch /home/owen/repos/my_project-branch1 and we want to create a git mirror under /home/owen/repos/my_project_git.

::

cd /home/owen/repos
git init my_project_git
darcs-fastconvert export my_project my_project-branch1 | (cd my_project_git && git fast-import && git checkout master)

The Git repo should now contain 2 branches: master and my_project-branch1. A common prefix of the two branches will be shared by both branches, but no merges will be detected, as detailed below.

  1. I want to create a bridge that allows incremental updates, and use both Git and Darcs:

A bridge can be created from an existing Darcs or Git respository. Say we have a Darcs repo that we’d like to bridge at /owen/repos/my_project, to create a bridge, we can proceed as follows:

::

cd /home/owen/repos
darcs-fastconvert create-bridge my_project

git clone my_project_bridge/my_project_git

Now we have a equivalent darcs and git repository: the original Darcs repository is still located in my_project and the newly created Git repo is located in my_project_git. Note that we have a my_project_bridge directory, which contains clones of both repos. These repos must not be modified directly - changes should instead be made in the original repo and pushed to the bridge-repos:

::

cd my_project_git

*wibble files and commit*

git push 

Pushing to the bridged repos first ensures that the bridge is correctly synced (that the bridged Git-repo is either equal or a superset of the bridged Darcs-repo), before allowing the push to continue.

N.B. Whereas Git forces the user to pull any changes locally before allowing the push to go ahead, Darcs can only warn the user, a repeated push attempt will succeed, without error, but should be avoided, due to conflicts not being correctly handled. Any changes should be pulled in, and the patch/commits be modified/re-recorded accordingly, before again pushing to the bridge.

Since re-recording changes to avoid conflicts is awkward within Darcs, a manual bridge sync command can be periodically used, before creating any local patches.

::

# To pull in changes from Git, into Darcs (in the bridge)
darcs-fastconvert sync my_project_bridge darcs
# Pull changes into our local copy of the bridged repo...
darcs pull my_project_bridge/my_project

# And vice-versa, to pull in changes from Darcs, into Git (in the bridge)
darcs-fastconvert sync my_project_bridge git
# Pull changes into our local Git repo...
git pull my_project_bridge/my_project_git
  1. I want to apply a Git patch to my Darcs repository:

  2. I want to modify the branches that the bridge is managing:

By default, the bridge will only manage the “master” branch of both repos. Any merges will still correctly converted (only with explicit tagging, for Darcs) but the original branch will not be present. We can instruct the bridge to handle extra branches by explicitly naming them:

What are the limitations?

Darcs merges can only be handled explicitly, if a special form of tagging is used (which is automatically employed when importing Git merges):

  1. There are no unrecorded changes.
  2. A tag is created, before the merge on the target branch with the exact message: darcs tag -m ‘darcs-fastconvert merge pre-target: MERGE_ID’
  3. A tag is created on each merge-source branch, before the merge, with the exact message: darcs tag -m ‘darcs-fastconvert merge pre-source: MERGE_ID’
  4. The branches are pulled, in their entirety: darcs pull -a BRANCH_NAME
  5. All resolutions are made, without any other changes, in as many patches as necessary.
  6. Finally, a end tag is created on the merge-target branch, with the exact message: darcs tag -m ‘darcs-fastconvert merge post: MERGE_ID’

It is important that MERGE_ID is unique in the repos, so the merge can be uniquely determined. The MERGE_ID must be equal across all corresponding merge-tags.

When exporting a tagged merge, the initial tag notifies the exporter of an impending merge, the end tag delimits the merge (and any resolutions) and each source-tag gives the context within which the merged-in patches were created. It is vital to obtain the patches’ original context, since we need to commute-out any patches that are in the context of the patches after having been merged-in, so that we can obtain the patches’ original form and context.

Non-tagged merges aren’t handled - this means that any conflicting changes will be exported such that some information is lost (namely, the original changes the conflicting patches made) since conflicting-changes are merged such that their changes are undone; see the darcs FAQ for more information about conflicts: http://wiki.darcs.net/ConflictsFAQ Any resolutions will be exported correctly, so the end-state of the exported repo will be consistent with that of the darcs repo.

Patch-ids change on each distinct import of changes … TODO more

What needs work?

Performance - performance is currently sub-optimal, particularly for …

Merge conflict-resolutions are squashed into a single patch, when exporting…

Aren’t there already tool(s) to do that?

There are several tools that provide some level of conversion between darcs and git, with varying feature-sets:

darcs-fastconvert

darcs-bridge was originally based on darcs-fastconvert written by Petr Ročkai, which provided simple import and export of darcs/git repositories using the fast-import stream format. It did not manage multiple branches or merges

darcs-to-git

Written in Ruby, originally written by Steve Purcell. Gives one-way conversion from Darcs to Git - shelling out to Darcs and Git, to translate Darcs patches into Git commits. Supports incremental importing.

darcs2git

tailor