source: tailor/README @ 879

Revision 879, 23.3 KB checked in by Jelmer Vernooij <jelmer@…>, 8 years ago (diff)

bzrng-replace-bzr
Remove the old 'bzr' backend and replace it with the 'bzrng' (bzrlib-based)
backend.

Line 
1Tailor 1.0
2##########
3
4.. contents::
5
6About
7=====
8
9Tailor is a tool to migrate changesets between ArX_, Bazaar_, `Bazaar-NG`_,
10CVS_, Codeville_, Darcs_, Git_, Mercurial_, Monotone_, Subversion_ and Tla_
11[#]_ repositories.
12
13This script makes it easier to keep the upstream changes merged in
14a branch of a product, storing needed information such as the upstream
15URI and revision in special properties on the branched directory.
16
17The following ascii-art illustrates the usual scenario::
18
19                           +------------+            +------------+
20  +--------------+         | Immutable  |            | Working    |
21  | Upstream CVS |-------->| darcs      |----------->| darcs      |
22  | repository   | tailor  | repository | darcs pull | repository |
23  +--------------+         +------------+            +------------+
24                                                           |^         
25                                                           ||
26                                                           ||
27                                                           v|
28                                                          User
29
30Ideally you should be able to swap and replace "CVS server" and "darcs
31repository" with any combination of the supported systems.
32
33A more convoluted setup shows how brave people are using it to get a
34two way sync::
35
36  +----------+        +--------+        +--------+       +---------+
37  |          | -----> | hybrid | darcs  |        | ----> |   my    |
38  | upstream | tailor |  CVS   | -----> | master | darcs | working |
39  |   CVS    | <----- | darcs  | <----- | darcs  | <---- |  darcs  |
40  |          |        |  sync  | tailor |        |       |         |
41  +----------+        +--------+        +--------+       +---------+
42               (cron)            (cron)
43
44
45.. [#] ArX, Baazar-NG, Codeville, Git and Mercurial systems may be
46       used only as the `target` backend, since the `source` support
47       isn't coded yet. Contributions on these backends will be very
48       appreciated, since I do not use them enough to figure out the
49       best way to get pending changes and build tailor ChangeSets out
50       of them.
51
52       To the opposite, Bazaar and Tla are supported only as source
53       systems.
54
55.. _arx: http://www.nongnu.org/arx/
56.. _bazaar: http://bazaar.canonical.com/
57.. _bazaar-ng: http://www.bazaar-ng.org/
58.. _codeville: http://www.codeville.org/
59.. _cvs: http://www.nongnu.org/cvs/
60.. _darcs: http://www.darcs.net/
61.. _git: http://git.or.cz/
62.. _mercurial: http://www.selenic.com/mercurial/
63.. _monotone: http://www.venge.net/monotone/
64.. _subversion: http://subversion.tigris.org/
65.. _tla: http://www.gnuarch.org/arch/index.html
66
67
68Installation
69============
70
71tailor is written in Python, and thus Python must be installed on
72your system to use it.  It has been successfully used with Python 2.3
73and 2.4.
74
75Since it relies on external tools to do the real work such as `cvs`,
76`darcs` [#]_ and `svn`, they need to be installed as well, although only
77those you will actually use.
78
79Make tailor executable::
80
81 $ chmod +x tailor
82
83You can either run tailor where it is currently located, or move it
84along with the vcpx directory to a location in your PATH.
85
86There's even a standard setup.py that you may use to install the
87script using Python's conventional distutils.
88
89.. [#] Darcs 1.0.2 is too old, 1.0.3 is good, 1.0.4 (the fourth
90       release candidate is under final testing) is recommended since
91       it's faster in most operations!
92
93
94Testing
95=======
96
97You can run the test suite with the following command line::
98
99 $ tailor test -v
100
101that runs all the tests in sequence, or::
102
103 $ tailor test -v TailorTest
104
105to trigger just a subset of them.
106
107
108Operation
109=========
110
111tailor needs now a configuration file that collects the various bits
112of information it needs to do it's job.
113
114The simplest way of starting out a new configuration is by omitting
115the --configfile command line option, and specifying the other as
116needed plus --verbose: in this situation, tailor will print out an
117equivalent configuration that you can redirect to a file, that you
118later will pass as --configfile.
119
120
121Examples
122--------
123
1241. Bootstrap a new tailored project, starting at upstream revision 10
125
126   a. First create a config file::
127   
128       $ tailor --verbose -s svn -R http://svn.server/path/to/svnrepo \
129                --module /Product/trunk -r 10 --subdir Product \
130                ~/darcs/MyProduct > myproject.tailor
131
132   b. Modify it as you like (mostly adjusting root-directories and the
133      like)::
134     
135       $ emacs myproject.tailor
136
137   c. Run tailor on it::
138   
139       $ tailor --configfile myproject.tailor
140
1412. Bootstrap a new product, fetching its whole CVS repository and
142   storing under SVN
143
144   a. First create a config file::
145
146       $ tailor --verbose --source-kind cvs --target-kind svn \
147                --repository :pserver:cvs.zope.org:/cvs-repository \
148                --module CMF/CMFCore --revision INITIAL \
149                --target-repository file:///some/where/svnrepo \
150                --target-module / cmfcore > cmfcore.tailor
151
152   b. Modify it as you like (mostly adjusting root-directories and the
153      like)::
154
155       $ emacs cmfcore.tailor
156
157   .. note:: By default, tailor uses "." as ``subdir``, to mean that
158             it will extract upstream source directly inside the
159             ``root-directory``.
160
161             This is known to cause problems with CVS as source, with
162             which you could see some wierd error like
163
164             ::
165
166               $ cvs -q -d ...:/cvsroot/mymodule checkout -d . ... mymodule
167               cvs checkout: existing repository /cvsroot/mymodule does not match /cvsroot/mymodule/mymodule
168               cvs checkout: ignoring module mymodule
169
170             When this is the case, the culprit may be a CVS
171             shortcoming not being able to handle ``-d .`` in the
172             right way.  Specify a different ``subdir`` option to
173             avoid the problem.
174
175   c. Run tailor on it once, to bootstrap the project::
176   
177       $ tailor -D -v --configfile cmfcore.tailor
178
179      If the target repository is on the local filesystem (ie, it
180      starts with ``file:///``) and it does not exist, tailor
181      creates a new empty Subversion repository at the specified
182      location.
183     
184   .. note:: Before step d) below, you may want to install an
185             appropriate hook in the repository to enable the
186             propset command to operate on unversioned properties,
187             as described in the `svn manual`__. Then you can
188             specify '--use-svn-propset' option, and tailor will
189             put the original author and timestamp in the proper
190             svn metadata instead of appending them to the changelog.
191
192             Other than the annoying repository manual intervention,
193             this thread__ and this other__ explain why using
194             ``-r{DATE}`` may produce strange results with this setup.
195
196   d. Run tailor again and again, to sync up with latest changes::
197
198       $ tailor -D -v --configfile myproject.tailor
199   
200__ http://svnbook.red-bean.com/en/1.0/ch05s02.html#svn-ch-5-sect-2.1
201__ http://svn.haxx.se/users/archive-2005-07/0605.shtml
202__ http://svn.haxx.se/users/archive-2005-03/0596.shtml
203
204
2053. Given the configuration file shown below in `Config file format`_,
206   the following command::
207
208    $ tailor --configfile example.tailor
209
210   is equivalent to this one::
211
212    $ tailor --configfile example.tailor tailor
213
214   in that they operate respectively on the default project(s) or
215   the ones specified on the command line (and in this case there
216   is just a single default project, tailor).
217
218   This one instead::
219
220    $ tailor --configfile example.tailor tailor tailor-reverse
221
222   operates on both projects.
223
224
225CVS start-revision
226------------------
227
228With CVS, you can specify a particular *point in time* specifying
229a `start-revision` with a timestamp like ``2001-12-25 23:26:48 UTC``.
230
231To specify also a particular `branch`, prepend it before the
232timestamp, as in ``unstable-branch 2001-12-25 23:26:48 UTC``.
233
234To migrate the whole history of a specific `branch`, use something
235like ``somebranch INITIAL``.
236
237
238Resolving conflicts
239===================
240
241Should one of the replayed changes generate any conflict, tailor
242will prompt the user to correct them. This is done after the upstream
243patch has been applied and before the final commit on the target
244system, so that manually tweaking the conflict can produce a clean
245patch.
246
247
248Shortcomings
249============
250
251Tailor currently suffers of the following reported problems:
252
253a) It does not handle "empty" CVS checkouts, in other words you cannot
254   bootstrap a project that has nothing in its CVS upstream
255   repository, or from a point in time where this condition was true.
256
257b) It's completely unsupported under Windows, evenif it now uses
258   2.4's subprocess_ that seems able to hide Windows crazyness...
259
260c) ArX, Baazar-NG, Codeville, Git, and Mercurial are (currently) only
261   supported as *target*; Bazaar and Tla only as *source*.
262
263d) Specifying ``--subdir .`` may not work, in particular when dealing
264   with remote CVS repositories (it does when the CVS repository is
265   on local machine).
266   
267This list will always be incomplete, but I'll do my best to keep it
268short :-)
269
270.. _subprocess: http://www.lysator.liu.se/~astrand/popen5/
271
272
273Config file format
274==================
275
276When your project is composed by multiple upstream modules, it is
277easier to collect such information in a single file. This is done by
278specifying the `--configfile` option with a file name as argument. In
279this case, tailor will read the above information from a standard
280Python ConfigParser file.
281
282For example::
283
284    [DEFAULT]
285    verbose = True
286    projects = tailor
287
288    [tailor]
289    root-directory = /tmp/n9
290    source = darcs:tailor
291    target = svn:tailor
292    state-file = tailor.state
293
294    [tailor-reverse]
295    root-directory = /tmp/n9
296    source = svn:tailor
297    target = darcs:tailor
298    state-file = reverse.state
299   
300    [svn:tailor]
301    repository = file:///tmp/testtai
302    module = /project1
303    subdir = svnside
304   
305    [darcs:tailor]
306    repository = ~/WiP/cvsync
307    subdir = darcside
308
309The configuration may hold one or more `projects`_ and two or more
310`repositories`_: project names do not contains colons ":",
311repository names must and the first part of the name before the
312colon specify the kind of the repository.  So, the above example
313contains two projects, one that goes from `darcs` to `subversion`, the
314other in the opposite direction.
315
316The ``[DEFAULT]`` section contains the default values, that will be
317used when a specific setting is missing from the particular section.
318
319You can specify on which project tailor should operate by
320giving its name on the command line, even more than one. When not
321explicitly given, tailor will look at ``projects`` in the
322``[DEFAULT]`` section, and if its missing it will loop over all
323projects in the configuration.
324
325The following simpler config just go in one direction, for a single
326project, so no need neither for ``[DEFAULT].projects`` nor command
327line arguments::
328
329    [pxlib]
330    source = cvs:pxlib
331    target = hg:pxlib
332    root-directory = ~/mypxlib
333    start-revision = INITIAL
334    subdir = pxlib
335   
336    [cvs:pxlib]
337    repository = :pserver:anonymous@cvs.sf.net:/cvsroot/pxlib
338    module = pxlib
339
340    [hg:pxlib]
341    hg-command = /usr/local/bin/hg
342
343This will use a single directory, ``pxlib`` to contain both the source
344and the target system. If you prefer keeping the separated, you just
345need to specify a different directory for each repository [#]_, as in::
346
347    [pxlib]
348    source = cvs:pxlib
349    target = hg:pxlib
350    root-directory = ~/mypxlib
351    start-revision = INITIAL
352   
353    [cvs:pxlib]
354    repository = :pserver:anonymous@cvs.sf.net:/cvsroot/pxlib
355    module = pxlib
356    subdir = original
357    delay-before-apply = 10
358
359    [hg:pxlib]
360    hg-command = /usr/local/bin/hg
361    subdir = migrated
362
363This will extract upstream CVS sources into ``~/mypxlib/original``,
364and create a new Mercurial repository in ``~/mypxlib/migrated``.
365
366On final example to show the syntax of Bazaar sources::
367
368    [project]
369    target = hg:target
370    start-revision = base-0
371    root-directory = /tmp/calife
372    state-file = tailor.state
373    source = baz:source
374
375    [baz:source]
376    module = calife--pam--3.0
377    repository = roberto@keltia.net--2003-depot
378    subdir = tla
379
380    [hg:target]
381    repository = /tmp/HG/calife-pam
382    subdir = hg
383
384.. [#] NB: when the source and the target repositories specify
385       different directories with the ``subdir`` option, tailor
386       uses ``rsync`` to keep them in sync, so that tool needs
387       to be installed.
388
389
390Configuration sections
391----------------------
392
393Default
394~~~~~~~
395
396The ``[DEFAULT]`` section in the configuration file may set the
397default value for any of the recognized options: when a value is
398missing from a specific section it is looked up in this section.
399
400One particular option, ``projects``, is meaningful only in the
401``[DEFAULT]`` section: it's a comma separated list of project names,
402the one that will be operated on by tailor when no project is
403specified on the command line.  When the there are no ``projects``
404setting nor any on the command line, tailor activates all configured
405projects, in order of appearance in the config file.
406
407
408Projects
409~~~~~~~~
410
411A project is identified by a section whose name does not contain any
412colon (":") character, and configured with the following values:
413
414root-directory
415  This is where all the fun will happen: this directory will contain
416  the source and the target working copy, and usually the state and
417  the log file. It supports the conventional `~user` to indicate user's
418  home directory and defaults to the current working directory.
419
420subdir
421  This is the subdirectory, relative to the `root-directory`, where
422  tailor will extract the source working copy. It may be '.' for some
423  backend kinds. The source and target backends will use this value
424  if they don't explicitly override it.
425
426state-file
427  Name of the state file needed to store tailor last activity.
428
429source
430  The source repository: a repository name is something like
431  "darcs:somename", that will be loaded from the homonymous section
432  in the configuration.
433
434target
435  The counterpart of `source`, the repository that will receive the
436  changes coming from there.
437
438Non mandatory options:
439
440verbose
441  Print the commands as they are executed.
442
443debug
444  Print also their output.
445 
446before-commit
447  This is a function name, or a sequence of function names enclosed
448  by brackets, that will be executed on each changeset just before
449  it get replayed on the target system: this may be used to perform
450  any kind of alteration on the content of the changeset, or to skip
451  some of them.
452
453after-commit
454  This is a function name, or a sequence of function names enclosed
455  by brackets, that will be executed on each changeset just after
456  the commit on the target system: this may be used for example to
457  create a tag.
458
459subdir
460  The name of the subdirectory, under ``root-directory``, that will
461  contain the source and target repositories/working directories.
462
463start-revision
464  This identifies from when tailor should start the migration. It can
465  be either ``INITIAL``, to indicate the start of the history, or
466  ``HEAD`` to indicate the current latest changeset, or a backend
467  specific way of indicate a particular revision/tag in the history.
468  See also `CVS start-revision`_ above.
469
470patch-name-format
471  Some backends have a distinct notion of `patch name` and `change
472  log`, others just suggest a policy that the first line of the
473  message is a summary, the rest if present is a more detailed
474  description of the change.  With this option you can control the
475  format of the name, or of the first line of the changelog.
476
477  The prototype may contain ``%(keyword)s`` such as 'author', 'date',
478  'revision', 'firstlogline', 'remaininglog' or 'project'.  It
479  defaults to ``[%(project)s @ %(revision)s]``; setting it to the
480  empty string means that tailor will simply use the original
481  changelog.
482
483  When you set it empty, as in
484
485  ::
486
487    [project]
488    patch-name-format =
489
490  tailor will keep the original changelog as is.
491
492remove-first-log-line
493  Remove the first line of the upstream changelog. This is intended to
494  go in pair with ``patch-name-format``, when using it's 'firstlogline'
495  variable to build the name of the patch.  By default is ``False``.
496 
497  A reasonable usage is::
498
499    [DEFAULT]
500    patch-name-format=[%(project)s @ %(revision)s]: %(firstlogline)s
501    remove-first-log-line=True
502
503refill-changelogs
504  Off by default, when active tailor reformats every changelog before
505  committing on the target system.
506
507Repositories
508~~~~~~~~~~~~
509
510All the section whose name contains at least one colon character
511denote a repository.  A single repository may be shared by zero, one or
512more projects.  The first part of the name up to the first colon
513indicates the `kind` of the repository, one of ``arx``, ``baz``, ``bzr``,
514``cdv``, ``cvs``, ``darcs``, ``git``, ``hg``, ``hglib``, ``monotone``,
515``svn``, ``svndump`` and ``tla``.
516
517When a repository is used as a `source`, it must indicate its origin
518with ``repository``, and for some backends also a ``module``, but are
519not required when it's a target system, even if some backend may use
520the information to create the target repository (like ``svn`` backend
521does).
522
523Each repository may then impose a particular external binary to be
524used, as done in the example above for ``hg``. Actually two of them,
525`bzr` and `hglib`, accept an option ``python-path`` to indicate
526where the BazaarNG Python library is located.
527
528A repository may also have it's own ``subdir``: when the `source` and
529`target` repositories use different subdirectories, tailor uses
530``rsync`` to copy the changes between the two after each applied
531changeset.  When the source repository basedir is a subdirectory of
532target basedir tailor prefixes all paths coming from upstream to match
533the relative position.
534
535Another option is ``encoding``, which states the charset encoding the
536particular repository uses, and it's particularly important when it
537differs from local system setup, that you may inspect executing::
538
539  python -m locale
540
541CVS and CVSPS repositories may turn off automatic tagging of entries,
542that tailor does by default to prevent manual interventions in the
543CVS working copy, using ``tag_entries = False``.
544
545Subversion repositories may specify ``use-propset = True``, to
546indicate that tailor is allowed to properly inject the upstream
547changeset's author and timestamp into the target repository.  As
548stated above, this requires a manual intervention on the repository
549itself and thus is off by default, and tailor simply appends those
550values to the changelog.  When active at bootstrap time and the
551repository is local, tailor creates automatically a minimal
552``hooks/pre-revprop-change`` script inside the repository, so no other
553intervention is needed.
554
555Sometime the migration is fast enough to put the upstream server under
556an excessive load. When this is the case, you may specify
557``delay-before-apply = 5``, that is the number of seconds tailor will
558wait before applying each changeset. It defaults to None, ie no delay
559at all.
560
561
562Using a Python script as configuration file
563-------------------------------------------
564
565Instead of executing ``tailor --configfile project.tailor.conf``
566you can prepend the following signature to the config itself::
567
568  #!/usr/bin/env /path/to/tailor
569
570Giving execute mode to it will permit the launch of the tailor
571process by running the config script directly::
572
573  $ ./project.tailor.conf
574
575When a config file is signed in this way [#]_, either you pass it as
576argument to ``--configfile`` or executed as above, tailor will
577actually execute it as a full fledged Python script, that may define
578functions that alter the behaviour of tailor itself.
579
580A common usage of this functionality is to define so called `hooks`,
581sequences of functions that are executed at particular points in
582the tailorization process.
583
584Just to illustrate the functionality, consider the following example::
585
586    #!/usr/bin/env tailor
587
588    """
589    [DEFAULT]
590    debug = False
591    verbose = True
592
593    [project]
594    target = bzr:target
595    root-directory = /tmp/prova
596    state-file = tailor.state
597    source = darcs:source
598    before-commit = before
599    after-commit = after
600    start-revision = Almost arbitrarily tagging this as version 0.8
601
602    [bzr:target]
603    python-path = /opt/src/bzr.dev
604    subdir = bzrside
605
606    [darcs:source]
607    repository = /home/lele/WiP/cvsync
608    subdir = darcside
609    """
610
611    def before(wd, changeset):
612        print "BEFORE", changeset
613        changeset.author = "LELE"
614        return changeset
615
616    def after(wd, changeset):
617        print "AFTER", changeset
618
619With the above in a `script` called say ``tester``, just doing::
620
621    $ chmod 755 tester
622    $ ./tester
623
624will migrate the history from a darcs repository to a bazaar-ng one,
625forcing the author to a well-known name :-)
626
627.. [#] Tailor does actually read just the first two bytes from the
628       file, and compare them with "#!", so you are free to choose
629       whatever syntax works in your environment.
630
631
632State file
633----------
634
635The state file stores two things: the last upstream revision that
636has been applied to the tree, and a sequence of pending (not yet
637applied) changesets, that may be empty. In the latter case, tailor
638will fetch latest changes from the upstream repository.
639
640       
641Further help
642============
643
644See the output of ``tailor -h`` for some further tips.  There's
645also a `wiki page`_ that may give you some other hints.  The
646development of Tailor is mainly driven by user requests at this point,
647and the preferred comunication medium is the dedicated `mailing list`_
648[#]_.
649
650.. _wiki page:
651   http://www.darcs.net/DarcsWiki/Tailor
652
653.. _mailing list:
654   http://lists.zooko.com/mailman/listinfo/tailor
655   
656I will be more than happy to answer any doubt, question or suggestion
657you may have on it. I'm usually hanging out as "lelit" on the IRC
658channel devoted to darcs on the `freenode.net` network. Do not
659hesitate to contact me either by email or chatting there.
660
661.. [#] I wish to say a big `Thank you` to `Zooko <zooko@zooko.com>`_,
662       for hosting the ML and for supporting Tailor in several ways,
663       from suggestions to bug reporting and fixing.
664
665
666Authors
667=======
668
669Lele Gaifax <lele@nautilus.homeip.net>
670
671Since I'm not currently using all the supported systems (so little
672time, so many VCSs...) I'm not in position to test them out properly,
673but I'll do my best to keep them in sync, maybe with your support :-)
674
675ArX support
676-----------
677
678ArX_ support was contributed by `Walter Landry <wlandry@ucsd.edu>`_.
679
680Bazaar-NG support
681-----------------
682
683`Bazaar-NG`_ support was contributed by `Johan Rydberg
684<jrydberg@gnu.org>`_.
685
686Git support
687-----------
688
689`Git`_ support was contributed by `Todd Mokros
690<tmokros@tmokros.net>`_.
691
692Monotone support
693----------------
694
695Monotone_ support was kindly contributed by `Markus Schiltknecht
696<markus@bluegap.ch>`_ and further developed by `rghetta
697<birrachiara@tin.it>`_, that was able to linearize the multi-headed
698monotone history into something tailor groks. Kudos!
699
700Tla support
701-----------
702
703Tla_ support was contributed by `Robin Farine
704<robin.farine@terminus.org>`_.
705
706
707License
708=======
709
710Tailor is distribuited under the `GNU General Public License`__.
711
712__ http://www.fsf.org/licensing/licenses/gpl.html
713
714
715About this document
716===================
717
718This document and most of the internal documention use the
719reStructuredText format so that it can be easily converted into other
720formats, such as HTML.  For more information about this, please see:
721
722  http://docutils.sourceforge.net/rst.html
723
724
725.. vim:ft=rest
726.. Local Variables:
727.. mode: rst
728.. End:
Note: See TracBrowser for help on using the repository browser.