Revision f8e1bc594a88fc774e6ba395b1a95f8e9ba05bdf
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.
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
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:
- 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.
- 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.
I want to create a bridge that allows incremental updates, and use both Git and Darcs:
I want to apply a Git patch to my Darcs repository:
I want to modify the branches that the bridge is managing:
What are the limitations?
Darcs merges can only be handled explicitly, if a special form of tagging is used:
- There are no unrecorded changes.
- 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’
- 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’
- The branches are pulled, in their entirety: darcs pull -a BRANCH_NAME
- All resolutions are made, without any other changes, in as many patches as necessary.
- 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.
What needs work?
Performance - performance is currently sub-optimal, particularly for …
Merge conflict-resolutions are squashed into a single patch, when exporting…
