/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.64.286 by Jelmer Vernooij
Move command implementations into a separate cmds module.
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Fastimport/fastexport commands."""
18
19
from bzrlib import bzrdir
20
from bzrlib.commands import Command
21
from bzrlib.option import Option, ListOption, RegistryOption
22
23
from bzrlib.plugins.fastimport import load_fastimport
24
25
26
def _run(source, processor_factory, control, params, verbose,
27
    user_map=None):
28
    """Create and run a processor.
29
30
    :param source: a filename or '-' for standard input. If the
31
      filename ends in .gz, it will be opened as a gzip file and
32
      the stream will be implicitly uncompressed
33
    :param processor_factory: a callable for creating a processor
34
    :param control: the BzrDir of the destination or None if no
35
      destination is expected
36
    :param user_map: if not None, the file containing the user map.
37
    """
38
    from fastimport import parser
39
    stream = _get_source_stream(source)
40
    user_mapper = _get_user_mapper(user_map)
41
    proc = processor_factory(control, params=params, verbose=verbose)
42
    p = parser.ImportParser(stream, verbose=verbose, user_mapper=user_mapper)
43
    return proc.process(p.iter_commands)
44
45
46
def _get_source_stream(source):
47
    if source == '-':
48
        import sys
49
        from fastimport import helpers
50
        stream = helpers.binary_stream(sys.stdin)
51
    elif source.endswith('.gz'):
52
        import gzip
53
        stream = gzip.open(source, "rb")
54
    else:
55
        stream = open(source, "rb")
56
    return stream
57
58
59
def _get_user_mapper(filename):
60
    import user_mapper
61
    if filename is None:
62
        return None
63
    f = open(filename)
64
    lines = f.readlines()
65
    f.close()
66
    return user_mapper.UserMapper(lines)
67
68
69
class cmd_fast_import(Command):
70
    """Backend for fast Bazaar data importers.
71
72
    This command reads a mixed command/data stream and creates
73
    branches in a Bazaar repository accordingly. The preferred
74
    recipe is::
75
76
      bzr fast-import project.fi project.bzr
77
78
    Numerous commands are provided for generating a fast-import file
79
    to use as input. These are named fast-export-from-xxx where xxx
80
    is one of cvs, darcs, git, hg, mtn, p4 or svn.
81
    To specify standard input as the input stream, use a
82
    source name of '-' (instead of project.fi). If the source name
83
    ends in '.gz', it is assumed to be compressed in gzip format.
84
    
85
    project.bzr will be created if it doesn't exist. If it exists
86
    already, it should be empty or be an existing Bazaar repository
87
    or branch. If not specified, the current directory is assumed.
88
 
89
    fast-import will intelligently select the format to use when
90
    creating a repository or branch. If you are running Bazaar 1.17
91
    up to Bazaar 2.0, the default format for Bazaar 2.x ("2a") is used.
92
    Otherwise, the current default format ("pack-0.92" for Bazaar 1.x)
93
    is used. If you wish to specify a custom format, use the `--format`
94
    option.
95
96
     .. note::
97
     
98
        To maintain backwards compatibility, fast-import lets you
99
        create the target repository or standalone branch yourself.
100
        It is recommended though that you let fast-import create
101
        these for you instead.
102
103
    :Branch mapping rules:
104
105
     Git reference names are mapped to Bazaar branch names as follows:
106
      
107
     * refs/heads/foo is mapped to foo
108
     * refs/remotes/origin/foo is mapped to foo.remote
109
     * refs/tags/foo is mapped to foo.tag
110
     * */master is mapped to trunk, trunk.remote, etc.
111
     * */trunk is mapped to git-trunk, git-trunk.remote, etc.
112
113
    :Branch creation rules:
114
115
     When a shared repository is created or found at the destination,
116
     branches are created inside it. In the simple case of a single
117
     branch (refs/heads/master) inside the input file, the branch is
118
     project.bzr/trunk.
119
120
     When a standalone branch is found at the destination, the trunk
121
     is imported there and warnings are output about any other branches
122
     found in the input file.
123
124
     When a branch in a shared repository is found at the destination,
125
     that branch is made the trunk and other branches, if any, are
126
     created in sister directories.
127
128
    :Working tree updates:
129
130
     The working tree is generated for the trunk branch. If multiple
131
     branches are created, a message is output on completion explaining
132
     how to create the working trees for other branches.
133
134
    :Custom exporters:
135
136
     The fast-export-from-xxx commands typically call more advanced
137
     xxx-fast-export scripts. You are welcome to use the advanced
138
     scripts if you prefer.
139
140
     If you wish to write a custom exporter for your project, see
141
     http://bazaar-vcs.org/BzrFastImport for the detailed protocol
142
     specification. In many cases, exporters can be written quite
143
     quickly using whatever scripting/programming language you like.
144
145
    :User mapping:
146
147
     Some source repositories store just the user name while Bazaar
148
     prefers a full email address. You can adjust user-ids while
149
     importing by using the --user-map option. The argument is a
150
     text file with lines in the format::
151
152
       old-id = new-id
153
154
     Blank lines and lines beginning with # are ignored.
155
     If old-id has the special value '@', then users without an
156
     email address will get one created by using the matching new-id
157
     as the domain, unless a more explicit address is given for them.
158
     For example, given the user-map of::
159
160
       @ = example.com
161
       bill = William Jones <bill@example.com>
162
163
     then user-ids are mapped as follows::
164
     
165
      maria => maria <maria@example.com>
166
      bill => William Jones <bill@example.com>
167
168
     .. note::
169
     
170
        User mapping is supported by both the fast-import and
171
        fast-import-filter commands.
172
173
    :Blob tracking:
174
175
     As some exporters (like git-fast-export) reuse blob data across
176
     commits, fast-import makes two passes over the input file by
177
     default. In the first pass, it collects data about what blobs are
178
     used when, along with some other statistics (e.g. total number of
179
     commits). In the second pass, it generates the repository and
180
     branches.
181
     
182
     .. note::
183
     
184
        The initial pass isn't done if the --info option is used
185
        to explicitly pass in information about the input stream.
186
        It also isn't done if the source is standard input. In the
187
        latter case, memory consumption may be higher than otherwise
188
        because some blobs may be kept in memory longer than necessary.
189
190
    :Restarting an import:
191
192
     At checkpoints and on completion, the commit-id -> revision-id
193
     map is saved to a file called 'fastimport-id-map' in the control
194
     directory for the repository (e.g. .bzr/repository). If the import
195
     is interrupted or unexpectedly crashes, it can be started again
196
     and this file will be used to skip over already loaded revisions.
197
     As long as subsequent exports from the original source begin
198
     with exactly the same revisions, you can use this feature to
199
     maintain a mirror of a repository managed by a foreign tool.
200
     If and when Bazaar is used to manage the repository, this file
201
     can be safely deleted.
202
203
    :Examples:
204
205
     Import a Subversion repository into Bazaar::
206
207
       bzr fast-export-from-svn /svn/repo/path project.fi
208
       bzr fast-import project.fi project.bzr
209
210
     Import a CVS repository into Bazaar::
211
212
       bzr fast-export-from-cvs /cvs/repo/path project.fi
213
       bzr fast-import project.fi project.bzr
214
215
     Import a Git repository into Bazaar::
216
217
       bzr fast-export-from-git /git/repo/path project.fi
218
       bzr fast-import project.fi project.bzr
219
220
     Import a Mercurial repository into Bazaar::
221
222
       bzr fast-export-from-hg /hg/repo/path project.fi
223
       bzr fast-import project.fi project.bzr
224
225
     Import a Darcs repository into Bazaar::
226
227
       bzr fast-export-from-darcs /darcs/repo/path project.fi
228
       bzr fast-import project.fi project.bzr
229
    """
230
    hidden = False
231
    _see_also = ['fast-export', 'fast-import-filter', 'fast-import-info']
232
    takes_args = ['source', 'destination?']
233
    takes_options = ['verbose',
234
                    Option('user-map', type=str,
235
                        help="Path to file containing a map of user-ids.",
236
                        ),
237
                    Option('info', type=str,
238
                        help="Path to file containing caching hints.",
239
                        ),
240
                    Option('trees',
241
                        help="Update all working trees, not just trunk's.",
242
                        ),
243
                    Option('count', type=int,
244
                        help="Import this many revisions then exit.",
245
                        ),
246
                    Option('checkpoint', type=int,
247
                        help="Checkpoint automatically every N revisions."
248
                             " The default is 10000.",
249
                        ),
250
                    Option('autopack', type=int,
251
                        help="Pack every N checkpoints. The default is 4.",
252
                        ),
253
                    Option('inv-cache', type=int,
254
                        help="Number of inventories to cache.",
255
                        ),
256
                    RegistryOption.from_kwargs('mode',
257
                        'The import algorithm to use.',
258
                        title='Import Algorithm',
259
                        default='Use the preferred algorithm (inventory deltas).',
260
                        classic="Use the original algorithm (mutable inventories).",
261
                        experimental="Enable experimental features.",
262
                        value_switches=True, enum_switch=False,
263
                        ),
264
                    Option('import-marks', type=str,
265
                        help="Import marks from file."
266
                        ),
267
                    Option('export-marks', type=str,
268
                        help="Export marks to file."
269
                        ),
270
                    RegistryOption('format',
271
                            help='Specify a format for the created repository. See'
272
                                 ' "bzr help formats" for details.',
273
                            lazy_registry=('bzrlib.bzrdir', 'format_registry'),
274
                            converter=lambda name: bzrdir.format_registry.make_bzrdir(name),
275
                            value_switches=False, title='Repository format'),
276
                     ]
277
    def run(self, source, destination='.', verbose=False, info=None,
278
        trees=False, count=-1, checkpoint=10000, autopack=4, inv_cache=-1,
279
        mode=None, import_marks=None, export_marks=None, format=None,
280
        user_map=None):
281
        load_fastimport()
282
        from bzrlib.plugins.fastimport.processors import generic_processor
283
        from bzrlib.plugins.fastimport.helpers import (
284
            open_destination_directory,
285
            )
286
        # If no format is given and the user is running a release
287
        # leading up to 2.0, select 2a for them. Otherwise, use
288
        # the default format.
289
        if format is None:
290
            import bzrlib
291
            bzr_version = bzrlib.version_info[0:2]
292
            if bzr_version in [(1,17), (1,18), (2,0)]:
293
                format = bzrdir.format_registry.make_bzrdir('2a')
294
        control = open_destination_directory(destination, format=format)
295
296
        # If an information file was given and the source isn't stdin,
297
        # generate the information by reading the source file as a first pass
298
        if info is None and source != '-':
299
            info = self._generate_info(source)
300
301
        # Do the work
302
        if mode is None:
303
            mode = 'default'
304
        params = {
305
            'info': info,
306
            'trees': trees,
307
            'count': count,
308
            'checkpoint': checkpoint,
309
            'autopack': autopack,
310
            'inv-cache': inv_cache,
311
            'mode': mode,
312
            'import-marks': import_marks,
313
            'export-marks': export_marks,
314
            }
315
        return _run(source, generic_processor.GenericProcessor, control,
0.64.287 by Jelmer Vernooij
Fix fast-import-filter.
316
                params, verbose, user_map=user_map)
0.64.286 by Jelmer Vernooij
Move command implementations into a separate cmds module.
317
318
    def _generate_info(self, source):
319
        from cStringIO import StringIO
320
        from fastimport import parser
321
        from fastimport.processors import info_processor
322
        stream = _get_source_stream(source)
323
        output = StringIO()
324
        try:
325
            proc = info_processor.InfoProcessor(verbose=True, outf=output)
326
            p = parser.ImportParser(stream)
327
            return_code = proc.process(p.iter_commands)
328
            lines = output.getvalue().splitlines()
329
        finally:
330
            output.close()
331
            stream.seek(0)
332
        return lines
333
334
335
class cmd_fast_import_filter(Command):
336
    """Filter a fast-import stream to include/exclude files & directories.
337
338
    This command is useful for splitting a subdirectory or bunch of
339
    files out from a project to create a new project complete with history
340
    for just those files. It can also be used to create a new project
341
    repository that removes all references to files that should not have
342
    been committed, e.g. security-related information (like passwords),
343
    commercially sensitive material, files with an incompatible license or
344
    large binary files like CD images.
345
346
    To specify standard input as the input stream, use a source name
347
    of '-'. If the source name ends in '.gz', it is assumed to be
348
    compressed in gzip format.
349
350
    :File/directory filtering:
351
352
     This is supported by the -i and -x options. Excludes take precedence
353
     over includes.
354
355
     When filtering out a subdirectory (or file), the new stream uses the
356
     subdirectory (or subdirectory containing the file) as the root. As
357
     fast-import doesn't know in advance whether a path is a file or
358
     directory in the stream, you need to specify a trailing '/' on
359
     directories passed to the `--includes option`. If multiple files or
360
     directories are given, the new root is the deepest common directory.
361
362
     Note: If a path has been renamed, take care to specify the *original*
363
     path name, not the final name that it ends up with.
364
365
    :User mapping:
366
367
     Some source repositories store just the user name while Bazaar
368
     prefers a full email address. You can adjust user-ids
369
     by using the --user-map option. The argument is a
370
     text file with lines in the format::
371
372
       old-id = new-id
373
374
     Blank lines and lines beginning with # are ignored.
375
     If old-id has the special value '@', then users without an
376
     email address will get one created by using the matching new-id
377
     as the domain, unless a more explicit address is given for them.
378
     For example, given the user-map of::
379
380
       @ = example.com
381
       bill = William Jones <bill@example.com>
382
383
     then user-ids are mapped as follows::
384
     
385
      maria => maria <maria@example.com>
386
      bill => William Jones <bill@example.com>
387
388
     .. note::
389
     
390
        User mapping is supported by both the fast-import and
391
        fast-import-filter commands.
392
393
    :Examples:
394
395
     Create a new project from a library (note the trailing / on the
396
     directory name of the library)::
397
398
       front-end | bzr fast-import-filter -i lib/xxx/ > xxx.fi
399
       bzr fast-import xxx.fi mylibrary.bzr
400
       (lib/xxx/foo is now foo)
401
402
     Create a new repository without a sensitive file::
403
404
       front-end | bzr fast-import-filter -x missile-codes.txt > clean.fi
405
       bzr fast-import clean.fi clean.bzr
406
    """
407
    hidden = False
408
    _see_also = ['fast-import']
0.64.293 by Jelmer Vernooij
SOURCE argument to bzr fast-import-filter is now optional, consistent with examples.
409
    takes_args = ['source?']
0.64.286 by Jelmer Vernooij
Move command implementations into a separate cmds module.
410
    takes_options = ['verbose',
411
                    ListOption('include_paths', short_name='i', type=str,
412
                        help="Only include commits affecting these paths."
413
                             " Directories should have a trailing /."
414
                        ),
415
                    ListOption('exclude_paths', short_name='x', type=str,
416
                        help="Exclude these paths from commits."
417
                        ),
418
                    Option('user-map', type=str,
419
                        help="Path to file containing a map of user-ids.",
420
                        ),
421
                     ]
422
    encoding_type = 'exact'
0.64.293 by Jelmer Vernooij
SOURCE argument to bzr fast-import-filter is now optional, consistent with examples.
423
    def run(self, source=None, verbose=False, include_paths=None,
0.64.286 by Jelmer Vernooij
Move command implementations into a separate cmds module.
424
        exclude_paths=None, user_map=None):
425
        load_fastimport()
426
        from fastimport.processors import filter_processor
427
        params = {
428
            'include_paths': include_paths,
429
            'exclude_paths': exclude_paths,
430
            }
0.64.287 by Jelmer Vernooij
Fix fast-import-filter.
431
        from fastimport import parser
432
        stream = _get_source_stream(source)
433
        user_mapper = _get_user_mapper(user_map)
434
        proc = filter_processor.FilterProcessor(params=params, verbose=verbose)
435
        p = parser.ImportParser(stream, verbose=verbose, user_mapper=user_mapper)
436
        return proc.process(p.iter_commands)
0.64.286 by Jelmer Vernooij
Move command implementations into a separate cmds module.
437
438
439
class cmd_fast_import_info(Command):
440
    """Output information about a fast-import stream.
441
442
    This command reads a fast-import stream and outputs
443
    statistics and interesting properties about what it finds.
444
    When run in verbose mode, the information is output as a
445
    configuration file that can be passed to fast-import to
446
    assist it in intelligently caching objects.
447
448
    To specify standard input as the input stream, use a source name
449
    of '-'. If the source name ends in '.gz', it is assumed to be
450
    compressed in gzip format.
451
452
    :Examples:
453
454
     Display statistics about the import stream produced by front-end::
455
456
      front-end | bzr fast-import-info -
457
458
     Create a hints file for running fast-import on a large repository::
459
460
       front-end | bzr fast-import-info -v - > front-end.cfg
461
    """
462
    hidden = False
463
    _see_also = ['fast-import']
464
    takes_args = ['source']
465
    takes_options = ['verbose']
466
    def run(self, source, verbose=False):
467
        load_fastimport()
468
        from fastimport.processors import info_processor
469
        return _run(source, info_processor.InfoProcessor, {}, verbose)
470
471
472
class cmd_fast_import_query(Command):
473
    """Query a fast-import stream displaying selected commands.
474
475
    To specify standard input as the input stream, use a source name
476
    of '-'. If the source name ends in '.gz', it is assumed to be
477
    compressed in gzip format.
478
479
    To specify a commit to display, give its mark using the
480
    --commit-mark option. The commit will be displayed with
481
    file-commands included but with inline blobs hidden.
482
483
    To specify the commands to display, use the -C option one or
484
    more times. To specify just some fields for a command, use the
485
    syntax::
486
487
      command=field1,...
488
489
    By default, the nominated fields for the nominated commands
490
    are displayed tab separated. To see the information in
491
    a name:value format, use verbose mode.
492
493
    Note: Binary fields (e.g. data for blobs) are masked out
494
    so it is generally safe to view the output in a terminal.
495
496
    :Examples:
497
498
     Show the commit with mark 429::
499
500
      bzr fast-import-query xxx.fi -m429
501
502
     Show all the fields of the reset and tag commands::
503
504
      bzr fast-import-query xxx.fi -Creset -Ctag
505
506
     Show the mark and merge fields of the commit commands::
507
508
      bzr fast-import-query xxx.fi -Ccommit=mark,merge
509
    """
510
    hidden = True
511
    _see_also = ['fast-import', 'fast-import-filter']
512
    takes_args = ['source']
513
    takes_options = ['verbose',
514
                    Option('commit-mark', short_name='m', type=str,
515
                        help="Mark of the commit to display."
516
                        ),
517
                    ListOption('commands', short_name='C', type=str,
518
                        help="Display fields for these commands."
519
                        ),
520
                     ]
521
    def run(self, source, verbose=False, commands=None, commit_mark=None):
522
        load_fastimport()
523
        from fastimport.processors import query_processor
524
        from bzrlib.plugins.fastimport import helpers
525
        params = helpers.defines_to_dict(commands) or {}
526
        if commit_mark:
527
            params['commit-mark'] = commit_mark
528
        return _run(source, query_processor.QueryProcessor, params,
529
            verbose)
530
531
532
class cmd_fast_export(Command):
533
    """Generate a fast-import stream from a Bazaar branch.
534
535
    This program generates a stream from a Bazaar branch in fast-import
536
    format used by tools such as bzr fast-import, git-fast-import and
537
    hg-fast-import.
538
539
    If no destination is given or the destination is '-', standard output
540
    is used. Otherwise, the destination is the name of a file. If the
541
    destination ends in '.gz', the output will be compressed into gzip
542
    format.
543
 
544
    :Round-tripping:
545
546
     Recent versions of the fast-import specification support features
547
     that allow effective round-tripping of many Bazaar branches. As
548
     such, fast-exporting a branch and fast-importing the data produced
549
     will create a new repository with equivalent history, i.e.
550
     "bzr log -v -p --include-merges --forward" on the old branch and
551
     new branch should produce similar, if not identical, results.
552
553
     .. note::
554
    
555
        Be aware that the new repository may appear to have similar history
556
        but internally it is quite different with new revision-ids and
557
        file-ids assigned. As a consequence, the ability to easily merge
558
        with branches based on the old repository is lost. Depending on your
559
        reasons for producing a new repository, this may or may not be an
560
        issue.
561
562
    :Interoperability:
563
564
     fast-export can use the following "extended features" to
565
     produce a richer data stream:
566
567
     * *multiple-authors* - if a commit has multiple authors (as commonly
568
       occurs in pair-programming), all authors will be included in the
569
       output, not just the first author
570
571
     * *commit-properties* - custom metadata per commit that Bazaar stores
572
       in revision properties (e.g. branch-nick and bugs fixed by this
573
       change) will be included in the output.
574
575
     * *empty-directories* - directories, even the empty ones, will be
576
       included in the output.
577
578
     To disable these features and produce output acceptable to git 1.6,
579
     use the --plain option. To enable these features, use --no-plain.
580
     Currently, --plain is the default but that will change in the near
581
     future once the feature names and definitions are formally agreed
582
     to by the broader fast-import developer community.
583
584
    :Examples:
585
586
     To produce data destined for import into Bazaar::
587
588
       bzr fast-export --no-plain my-bzr-branch my.fi.gz
589
590
     To produce data destined for Git 1.6::
591
592
       bzr fast-export --plain my-bzr-branch my.fi
593
594
     To import several unmerged but related branches into the same repository,
595
     use the --{export,import}-marks options, and specify a name for the git
596
     branch like this::
597
    
598
       bzr fast-export --export-marks=marks.bzr project.dev |
599
              GIT_DIR=project/.git git-fast-import --export-marks=marks.git
600
601
       bzr fast-export --import-marks=marks.bzr -b other project.other |
602
              GIT_DIR=project/.git git-fast-import --import-marks=marks.git
603
604
     If you get a "Missing space after source" error from git-fast-import,
605
     see the top of the commands.py module for a work-around.
606
    """
607
    hidden = False
608
    _see_also = ['fast-import', 'fast-import-filter']
609
    takes_args = ['source', 'destination?']
610
    takes_options = ['verbose', 'revision',
611
                    Option('git-branch', short_name='b', type=str,
612
                        argname='FILE',
613
                        help='Name of the git branch to create (default=master).'
614
                        ),
615
                    Option('checkpoint', type=int, argname='N',
616
                        help="Checkpoint every N revisions (default=10000)."
617
                        ),
618
                    Option('marks', type=str, argname='FILE',
619
                        help="Import marks from and export marks to file."
620
                        ),
621
                    Option('import-marks', type=str, argname='FILE',
622
                        help="Import marks from file."
623
                        ),
624
                    Option('export-marks', type=str, argname='FILE',
625
                        help="Export marks to file."
626
                        ),
627
                    Option('plain',
628
                        help="Exclude metadata to maximise interoperability."
629
                        ),
630
                     ]
631
    encoding_type = 'exact'
632
    def run(self, source, destination=None, verbose=False,
633
        git_branch="master", checkpoint=10000, marks=None,
634
        import_marks=None, export_marks=None, revision=None,
635
        plain=True):
636
        load_fastimport()
637
        from bzrlib.plugins.fastimport import exporter
638
639
        if marks:
640
            import_marks = export_marks = marks
641
        exporter = exporter.BzrFastExporter(source,
642
            destination=destination,
643
            git_branch=git_branch, checkpoint=checkpoint,
644
            import_marks_file=import_marks, export_marks_file=export_marks,
645
            revision=revision, verbose=verbose, plain_format=plain)
646
        return exporter.run()
647
648
649
class cmd_fast_export_from_cvs(Command):
650
    """Generate a fast-import file from a CVS repository.
651
652
    Destination is a dump file, typically named xxx.fi where xxx is
653
    the name of the project. If '-' is given, standard output is used.
654
655
    cvs2svn 2.3 or later must be installed as its cvs2bzr script is used
656
    under the covers to do the export.
657
    
658
    The source must be the path on your filesystem to the part of the
659
    repository you wish to convert. i.e. either that path or a parent
660
    directory must contain a CVSROOT subdirectory. The path may point to
661
    either the top of a repository or to a path within it. In the latter
662
    case, only that project within the repository will be converted.
663
664
    .. note::
665
       Remote access to the repository is not sufficient - the path
666
       must point into a copy of the repository itself. See
667
       http://cvs2svn.tigris.org/faq.html#repoaccess for instructions
668
       on how to clone a remote CVS repository locally.
669
670
    By default, the trunk, branches and tags are all exported. If you
671
    only want the trunk, use the `--trunk-only` option.
672
673
    By default, filenames, log messages and author names are expected
674
    to be encoded in ascii. Use the `--encoding` option to specify an
675
    alternative. If multiple encodings are used, specify the option
676
    multiple times. For a list of valid encoding names, see
677
    http://docs.python.org/lib/standard-encodings.html.
678
679
    Windows users need to install GNU sort and use the `--sort`
680
    option to specify its location. GNU sort can be downloaded from
681
    http://unxutils.sourceforge.net/.
682
    """
683
    hidden = False
684
    _see_also = ['fast-import', 'fast-import-filter']
685
    takes_args = ['source', 'destination']
686
    takes_options = ['verbose',
687
                    Option('trunk-only',
688
                        help="Export just the trunk, ignoring tags and branches."
689
                        ),
690
                    ListOption('encoding', type=str, argname='CODEC',
691
                        help="Encoding used for filenames, commit messages "
692
                             "and author names if not ascii."
693
                        ),
694
                    Option('sort', type=str, argname='PATH',
695
                        help="GNU sort program location if not on the path."
696
                        ),
697
                    ]
698
    encoding_type = 'exact'
699
    def run(self, source, destination, verbose=False, trunk_only=False,
700
        encoding=None, sort=None):
701
        load_fastimport()
702
        from bzrlib.plugins.fastimport.exporters import fast_export_from
703
        custom = []
704
        if trunk_only:
705
            custom.append("--trunk-only")
706
        if encoding:
707
            for enc in encoding:
708
                custom.extend(['--encoding', enc])
709
        if sort:
710
            custom.extend(['--sort', sort])
711
        fast_export_from(source, destination, 'cvs', verbose, custom)
712
713
714
class cmd_fast_export_from_darcs(Command):
715
    """Generate a fast-import file from a Darcs repository.
716
717
    Destination is a dump file, typically named xxx.fi where xxx is
718
    the name of the project. If '-' is given, standard output is used.
719
720
    Darcs 2.2 or later must be installed as various subcommands are
721
    used to access the source repository. The source may be a network
722
    URL but using a local URL is recommended for performance reasons.
723
    """
724
    hidden = False
725
    _see_also = ['fast-import', 'fast-import-filter']
726
    takes_args = ['source', 'destination']
727
    takes_options = ['verbose',
728
                    Option('encoding', type=str, argname='CODEC',
729
                        help="Encoding used for commit messages if not utf-8."
730
                        ),
731
                    ]
732
    encoding_type = 'exact'
733
    def run(self, source, destination, verbose=False, encoding=None):
734
        from bzrlib.plugins.fastimport.exporters import fast_export_from
735
        custom = None
736
        if encoding is not None:
737
            custom = ['--encoding', encoding]
738
        fast_export_from(source, destination, 'darcs', verbose, custom)
739
740
741
class cmd_fast_export_from_hg(Command):
742
    """Generate a fast-import file from a Mercurial repository.
743
744
    Destination is a dump file, typically named xxx.fi where xxx is
745
    the name of the project. If '-' is given, standard output is used.
746
747
    Mercurial 1.2 or later must be installed as its libraries are used
748
    to access the source repository. Given the APIs currently used,
749
    the source repository must be a local file, not a network URL.
750
    """
751
    hidden = False
752
    _see_also = ['fast-import', 'fast-import-filter']
753
    takes_args = ['source', 'destination']
754
    takes_options = ['verbose']
755
    encoding_type = 'exact'
756
    def run(self, source, destination, verbose=False):
757
        load_fastimport()
758
        from bzrlib.plugins.fastimport.exporters import fast_export_from
759
        fast_export_from(source, destination, 'hg', verbose)
760
761
762
class cmd_fast_export_from_git(Command):
763
    """Generate a fast-import file from a Git repository.
764
765
    Destination is a dump file, typically named xxx.fi where xxx is
766
    the name of the project. If '-' is given, standard output is used.
767
768
    Git 1.6 or later must be installed as the git fast-export
769
    subcommand is used under the covers to generate the stream.
770
    The source must be a local directory.
771
772
    .. note::
773
    
774
       Earlier versions of Git may also work fine but are
775
       likely to receive less active support if problems arise.
776
    """
777
    hidden = False
778
    _see_also = ['fast-import', 'fast-import-filter']
779
    takes_args = ['source', 'destination']
780
    takes_options = ['verbose']
781
    encoding_type = 'exact'
782
    def run(self, source, destination, verbose=False):
783
        load_fastimport()
784
        from bzrlib.plugins.fastimport.exporters import fast_export_from
785
        fast_export_from(source, destination, 'git', verbose)
786
787
788
class cmd_fast_export_from_mtn(Command):
789
    """Generate a fast-import file from a Monotone repository.
790
791
    Destination is a dump file, typically named xxx.fi where xxx is
792
    the name of the project. If '-' is given, standard output is used.
793
794
    Monotone 0.43 or later must be installed as the mtn git_export
795
    subcommand is used under the covers to generate the stream.
796
    The source must be a local directory.
797
    """
798
    hidden = False
799
    _see_also = ['fast-import', 'fast-import-filter']
800
    takes_args = ['source', 'destination']
801
    takes_options = ['verbose']
802
    encoding_type = 'exact'
803
    def run(self, source, destination, verbose=False):
804
        load_fastimport()
805
        from bzrlib.plugins.fastimport.exporters import fast_export_from
806
        fast_export_from(source, destination, 'mtn', verbose)
807
808
809
class cmd_fast_export_from_p4(Command):
810
    """Generate a fast-import file from a Perforce repository.
811
812
    Source is a Perforce depot path, e.g., //depot/project
813
814
    Destination is a dump file, typically named xxx.fi where xxx is
815
    the name of the project. If '-' is given, standard output is used.
816
817
    bzrp4 must be installed as its p4_fast_export.py module is used under
818
    the covers to do the export.  bzrp4 can be downloaded from
819
    https://launchpad.net/bzrp4/.
820
821
    The P4PORT environment variable must be set, and you must be logged
822
    into the Perforce server.
823
824
    By default, only the HEAD changelist is exported.  To export all
825
    changelists, append '@all' to the source.  To export a revision range,
826
    append a comma-delimited pair of changelist numbers to the source,
827
    e.g., '100,200'.
828
    """
829
    hidden = False
830
    _see_also = ['fast-import', 'fast-import-filter']
831
    takes_args = ['source', 'destination']
832
    takes_options = []
833
    encoding_type = 'exact'
834
    def run(self, source, destination, verbose=False):
835
        load_fastimport()
836
        from bzrlib.plugins.fastimport.exporters import fast_export_from
837
        custom = []
838
        fast_export_from(source, destination, 'p4', verbose, custom)
839
840
841
class cmd_fast_export_from_svn(Command):
842
    """Generate a fast-import file from a Subversion repository.
843
844
    Destination is a dump file, typically named xxx.fi where xxx is
845
    the name of the project. If '-' is given, standard output is used.
846
847
    Python-Subversion (Python bindings to the Subversion APIs)
848
    1.4 or later must be installed as this library is used to
849
    access the source repository. The source may be a network URL
850
    but using a local URL is recommended for performance reasons.
851
    """
852
    hidden = False
853
    _see_also = ['fast-import', 'fast-import-filter']
854
    takes_args = ['source', 'destination']
855
    takes_options = ['verbose',
856
                    Option('trunk-path', type=str, argname="STR",
857
                        help="Path in repo to /trunk.\n"
858
                              "May be `regex:/cvs/(trunk)/proj1/(.*)` in "
859
                              "which case the first group is used as the "
860
                              "branch name and the second group is used "
861
                              "to match files.",
862
                        ),
863
                    Option('branches-path', type=str, argname="STR",
864
                        help="Path in repo to /branches."
865
                        ),
866
                    Option('tags-path', type=str, argname="STR",
867
                        help="Path in repo to /tags."
868
                        ),
869
                    ]
870
    encoding_type = 'exact'
871
    def run(self, source, destination, verbose=False, trunk_path=None,
872
        branches_path=None, tags_path=None):
873
        load_fastimport()
874
        from bzrlib.plugins.fastimport.exporters import fast_export_from
875
        custom = []
876
        if trunk_path is not None:
877
            custom.extend(['--trunk-path', trunk_path])
878
        if branches_path is not None:
879
            custom.extend(['--branches-path', branches_path])
880
        if tags_path is not None:
881
            custom.extend(['--tags-path', tags_path])
882
        fast_export_from(source, destination, 'svn', verbose, custom)