diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2010-12-11 19:55:34 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2010-12-11 19:55:34 +0100 |
commit | 45c2422c4c9df53fc432cb1ebce5e1dc166a6985 (patch) | |
tree | 5b4fea2b71ed63dc0d5b8da584ba6ae9d12312aa | |
parent | 1990dfe3e07a4172273f511485027e960511c923 (diff) | |
download | bzr-fastimport-45c2422c4c9df53fc432cb1ebce5e1dc166a6985.tar.gz |
Move command implementations into a separate cmds module.
-rw-r--r-- | __init__.py | 898 | ||||
-rw-r--r-- | cmds.py | 878 | ||||
-rw-r--r-- | tests/test_commands.py | 2 |
3 files changed, 895 insertions, 883 deletions
diff --git a/__init__.py b/__init__.py index 2fc555c..61e14c6 100644 --- a/__init__.py +++ b/__init__.py @@ -81,9 +81,7 @@ page on Launchpad, https://launchpad.net/bzr-fastimport. version_info = (0, 10, 0, 'dev', 0) -from bzrlib import bzrdir -from bzrlib.commands import Command, register_command -from bzrlib.option import Option, ListOption, RegistryOption +from bzrlib.commands import plugin_cmds def load_fastimport(): @@ -100,882 +98,18 @@ def test_suite(): return tests.test_suite() -def _run(source, processor_factory, control, params, verbose, - user_map=None): - """Create and run a processor. - - :param source: a filename or '-' for standard input. If the - filename ends in .gz, it will be opened as a gzip file and - the stream will be implicitly uncompressed - :param processor_factory: a callable for creating a processor - :param control: the BzrDir of the destination or None if no - destination is expected - :param user_map: if not None, the file containing the user map. - """ - from fastimport import parser - stream = _get_source_stream(source) - user_mapper = _get_user_mapper(user_map) - proc = processor_factory(control, params=params, verbose=verbose) - p = parser.ImportParser(stream, verbose=verbose, user_mapper=user_mapper) - return proc.process(p.iter_commands) - - -def _get_source_stream(source): - if source == '-': - import sys - from fastimport import helpers - stream = helpers.binary_stream(sys.stdin) - elif source.endswith('.gz'): - import gzip - stream = gzip.open(source, "rb") - else: - stream = open(source, "rb") - return stream - - -def _get_user_mapper(filename): - import user_mapper - if filename is None: - return None - f = open(filename) - lines = f.readlines() - f.close() - return user_mapper.UserMapper(lines) - - -class cmd_fast_import(Command): - """Backend for fast Bazaar data importers. - - This command reads a mixed command/data stream and creates - branches in a Bazaar repository accordingly. The preferred - recipe is:: - - bzr fast-import project.fi project.bzr - - Numerous commands are provided for generating a fast-import file - to use as input. These are named fast-export-from-xxx where xxx - is one of cvs, darcs, git, hg, mtn, p4 or svn. - To specify standard input as the input stream, use a - source name of '-' (instead of project.fi). If the source name - ends in '.gz', it is assumed to be compressed in gzip format. - - project.bzr will be created if it doesn't exist. If it exists - already, it should be empty or be an existing Bazaar repository - or branch. If not specified, the current directory is assumed. - - fast-import will intelligently select the format to use when - creating a repository or branch. If you are running Bazaar 1.17 - up to Bazaar 2.0, the default format for Bazaar 2.x ("2a") is used. - Otherwise, the current default format ("pack-0.92" for Bazaar 1.x) - is used. If you wish to specify a custom format, use the `--format` - option. - - .. note:: - - To maintain backwards compatibility, fast-import lets you - create the target repository or standalone branch yourself. - It is recommended though that you let fast-import create - these for you instead. - - :Branch mapping rules: - - Git reference names are mapped to Bazaar branch names as follows: - - * refs/heads/foo is mapped to foo - * refs/remotes/origin/foo is mapped to foo.remote - * refs/tags/foo is mapped to foo.tag - * */master is mapped to trunk, trunk.remote, etc. - * */trunk is mapped to git-trunk, git-trunk.remote, etc. - - :Branch creation rules: - - When a shared repository is created or found at the destination, - branches are created inside it. In the simple case of a single - branch (refs/heads/master) inside the input file, the branch is - project.bzr/trunk. - - When a standalone branch is found at the destination, the trunk - is imported there and warnings are output about any other branches - found in the input file. - - When a branch in a shared repository is found at the destination, - that branch is made the trunk and other branches, if any, are - created in sister directories. - - :Working tree updates: - - The working tree is generated for the trunk branch. If multiple - branches are created, a message is output on completion explaining - how to create the working trees for other branches. - - :Custom exporters: - - The fast-export-from-xxx commands typically call more advanced - xxx-fast-export scripts. You are welcome to use the advanced - scripts if you prefer. - - If you wish to write a custom exporter for your project, see - http://bazaar-vcs.org/BzrFastImport for the detailed protocol - specification. In many cases, exporters can be written quite - quickly using whatever scripting/programming language you like. - - :User mapping: - - Some source repositories store just the user name while Bazaar - prefers a full email address. You can adjust user-ids while - importing by using the --user-map option. The argument is a - text file with lines in the format:: - - old-id = new-id - - Blank lines and lines beginning with # are ignored. - If old-id has the special value '@', then users without an - email address will get one created by using the matching new-id - as the domain, unless a more explicit address is given for them. - For example, given the user-map of:: - - @ = example.com - bill = William Jones <bill@example.com> - - then user-ids are mapped as follows:: - - maria => maria <maria@example.com> - bill => William Jones <bill@example.com> - - .. note:: - - User mapping is supported by both the fast-import and - fast-import-filter commands. - - :Blob tracking: - - As some exporters (like git-fast-export) reuse blob data across - commits, fast-import makes two passes over the input file by - default. In the first pass, it collects data about what blobs are - used when, along with some other statistics (e.g. total number of - commits). In the second pass, it generates the repository and - branches. - - .. note:: - - The initial pass isn't done if the --info option is used - to explicitly pass in information about the input stream. - It also isn't done if the source is standard input. In the - latter case, memory consumption may be higher than otherwise - because some blobs may be kept in memory longer than necessary. - - :Restarting an import: - - At checkpoints and on completion, the commit-id -> revision-id - map is saved to a file called 'fastimport-id-map' in the control - directory for the repository (e.g. .bzr/repository). If the import - is interrupted or unexpectedly crashes, it can be started again - and this file will be used to skip over already loaded revisions. - As long as subsequent exports from the original source begin - with exactly the same revisions, you can use this feature to - maintain a mirror of a repository managed by a foreign tool. - If and when Bazaar is used to manage the repository, this file - can be safely deleted. - - :Examples: - - Import a Subversion repository into Bazaar:: - - bzr fast-export-from-svn /svn/repo/path project.fi - bzr fast-import project.fi project.bzr - - Import a CVS repository into Bazaar:: - - bzr fast-export-from-cvs /cvs/repo/path project.fi - bzr fast-import project.fi project.bzr - - Import a Git repository into Bazaar:: - - bzr fast-export-from-git /git/repo/path project.fi - bzr fast-import project.fi project.bzr - - Import a Mercurial repository into Bazaar:: - - bzr fast-export-from-hg /hg/repo/path project.fi - bzr fast-import project.fi project.bzr - - Import a Darcs repository into Bazaar:: - - bzr fast-export-from-darcs /darcs/repo/path project.fi - bzr fast-import project.fi project.bzr - """ - hidden = False - _see_also = ['fast-export', 'fast-import-filter', 'fast-import-info'] - takes_args = ['source', 'destination?'] - takes_options = ['verbose', - Option('user-map', type=str, - help="Path to file containing a map of user-ids.", - ), - Option('info', type=str, - help="Path to file containing caching hints.", - ), - Option('trees', - help="Update all working trees, not just trunk's.", - ), - Option('count', type=int, - help="Import this many revisions then exit.", - ), - Option('checkpoint', type=int, - help="Checkpoint automatically every N revisions." - " The default is 10000.", - ), - Option('autopack', type=int, - help="Pack every N checkpoints. The default is 4.", - ), - Option('inv-cache', type=int, - help="Number of inventories to cache.", - ), - RegistryOption.from_kwargs('mode', - 'The import algorithm to use.', - title='Import Algorithm', - default='Use the preferred algorithm (inventory deltas).', - classic="Use the original algorithm (mutable inventories).", - experimental="Enable experimental features.", - value_switches=True, enum_switch=False, - ), - Option('import-marks', type=str, - help="Import marks from file." - ), - Option('export-marks', type=str, - help="Export marks to file." - ), - RegistryOption('format', - help='Specify a format for the created repository. See' - ' "bzr help formats" for details.', - lazy_registry=('bzrlib.bzrdir', 'format_registry'), - converter=lambda name: bzrdir.format_registry.make_bzrdir(name), - value_switches=False, title='Repository format'), - ] - aliases = [] - def run(self, source, destination='.', verbose=False, info=None, - trees=False, count=-1, checkpoint=10000, autopack=4, inv_cache=-1, - mode=None, import_marks=None, export_marks=None, format=None, - user_map=None): - load_fastimport() - from bzrlib.plugins.fastimport.processors import generic_processor - from bzrlib.plugins.fastimport.helpers import ( - open_destination_directory, - ) - # If no format is given and the user is running a release - # leading up to 2.0, select 2a for them. Otherwise, use - # the default format. - if format is None: - import bzrlib - bzr_version = bzrlib.version_info[0:2] - if bzr_version in [(1,17), (1,18), (2,0)]: - format = bzrdir.format_registry.make_bzrdir('2a') - control = open_destination_directory(destination, format=format) - - # If an information file was given and the source isn't stdin, - # generate the information by reading the source file as a first pass - if info is None and source != '-': - info = self._generate_info(source) - - # Do the work - if mode is None: - mode = 'default' - params = { - 'info': info, - 'trees': trees, - 'count': count, - 'checkpoint': checkpoint, - 'autopack': autopack, - 'inv-cache': inv_cache, - 'mode': mode, - 'import-marks': import_marks, - 'export-marks': export_marks, - } - return _run(source, generic_processor.GenericProcessor, control, - params, verbose, user_map=user_map) - - def _generate_info(self, source): - from cStringIO import StringIO - from fastimport import parser - from fastimport.processors import info_processor - stream = _get_source_stream(source) - output = StringIO() - try: - proc = info_processor.InfoProcessor(verbose=True, outf=output) - p = parser.ImportParser(stream) - return_code = proc.process(p.iter_commands) - lines = output.getvalue().splitlines() - finally: - output.close() - stream.seek(0) - return lines - - -class cmd_fast_import_filter(Command): - """Filter a fast-import stream to include/exclude files & directories. - - This command is useful for splitting a subdirectory or bunch of - files out from a project to create a new project complete with history - for just those files. It can also be used to create a new project - repository that removes all references to files that should not have - been committed, e.g. security-related information (like passwords), - commercially sensitive material, files with an incompatible license or - large binary files like CD images. - - To specify standard input as the input stream, use a source name - of '-'. If the source name ends in '.gz', it is assumed to be - compressed in gzip format. - - :File/directory filtering: - - This is supported by the -i and -x options. Excludes take precedence - over includes. - - When filtering out a subdirectory (or file), the new stream uses the - subdirectory (or subdirectory containing the file) as the root. As - fast-import doesn't know in advance whether a path is a file or - directory in the stream, you need to specify a trailing '/' on - directories passed to the `--includes option`. If multiple files or - directories are given, the new root is the deepest common directory. - - Note: If a path has been renamed, take care to specify the *original* - path name, not the final name that it ends up with. - - :User mapping: - - Some source repositories store just the user name while Bazaar - prefers a full email address. You can adjust user-ids - by using the --user-map option. The argument is a - text file with lines in the format:: - - old-id = new-id - - Blank lines and lines beginning with # are ignored. - If old-id has the special value '@', then users without an - email address will get one created by using the matching new-id - as the domain, unless a more explicit address is given for them. - For example, given the user-map of:: - - @ = example.com - bill = William Jones <bill@example.com> - - then user-ids are mapped as follows:: - - maria => maria <maria@example.com> - bill => William Jones <bill@example.com> - - .. note:: - - User mapping is supported by both the fast-import and - fast-import-filter commands. - - :Examples: - - Create a new project from a library (note the trailing / on the - directory name of the library):: - - front-end | bzr fast-import-filter -i lib/xxx/ > xxx.fi - bzr fast-import xxx.fi mylibrary.bzr - (lib/xxx/foo is now foo) - - Create a new repository without a sensitive file:: - - front-end | bzr fast-import-filter -x missile-codes.txt > clean.fi - bzr fast-import clean.fi clean.bzr - """ - hidden = False - _see_also = ['fast-import'] - takes_args = ['source'] - takes_options = ['verbose', - ListOption('include_paths', short_name='i', type=str, - help="Only include commits affecting these paths." - " Directories should have a trailing /." - ), - ListOption('exclude_paths', short_name='x', type=str, - help="Exclude these paths from commits." - ), - Option('user-map', type=str, - help="Path to file containing a map of user-ids.", - ), - ] - aliases = [] - encoding_type = 'exact' - def run(self, source, verbose=False, include_paths=None, - exclude_paths=None, user_map=None): - load_fastimport() - from fastimport.processors import filter_processor - params = { - 'include_paths': include_paths, - 'exclude_paths': exclude_paths, - } - return _run(source, filter_processor.FilterProcessor, params, - verbose, user_map=user_map) - - -class cmd_fast_import_info(Command): - """Output information about a fast-import stream. - - This command reads a fast-import stream and outputs - statistics and interesting properties about what it finds. - When run in verbose mode, the information is output as a - configuration file that can be passed to fast-import to - assist it in intelligently caching objects. - - To specify standard input as the input stream, use a source name - of '-'. If the source name ends in '.gz', it is assumed to be - compressed in gzip format. - - :Examples: - - Display statistics about the import stream produced by front-end:: - - front-end | bzr fast-import-info - - - Create a hints file for running fast-import on a large repository:: - - front-end | bzr fast-import-info -v - > front-end.cfg - """ - hidden = False - _see_also = ['fast-import'] - takes_args = ['source'] - takes_options = ['verbose'] - aliases = [] - def run(self, source, verbose=False): - load_fastimport() - from fastimport.processors import info_processor - return _run(source, info_processor.InfoProcessor, {}, verbose) - - -class cmd_fast_import_query(Command): - """Query a fast-import stream displaying selected commands. - - To specify standard input as the input stream, use a source name - of '-'. If the source name ends in '.gz', it is assumed to be - compressed in gzip format. - - To specify a commit to display, give its mark using the - --commit-mark option. The commit will be displayed with - file-commands included but with inline blobs hidden. - - To specify the commands to display, use the -C option one or - more times. To specify just some fields for a command, use the - syntax:: - - command=field1,... - - By default, the nominated fields for the nominated commands - are displayed tab separated. To see the information in - a name:value format, use verbose mode. - - Note: Binary fields (e.g. data for blobs) are masked out - so it is generally safe to view the output in a terminal. - - :Examples: - - Show the commit with mark 429:: - - bzr fast-import-query xxx.fi -m429 - - Show all the fields of the reset and tag commands:: - - bzr fast-import-query xxx.fi -Creset -Ctag - - Show the mark and merge fields of the commit commands:: - - bzr fast-import-query xxx.fi -Ccommit=mark,merge - """ - hidden = True - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source'] - takes_options = ['verbose', - Option('commit-mark', short_name='m', type=str, - help="Mark of the commit to display." - ), - ListOption('commands', short_name='C', type=str, - help="Display fields for these commands." - ), - ] - aliases = [] - def run(self, source, verbose=False, commands=None, commit_mark=None): - load_fastimport() - from fastimport.processors import query_processor - from bzrlib.plugins.fastimport import helpers - params = helpers.defines_to_dict(commands) or {} - if commit_mark: - params['commit-mark'] = commit_mark - return _run(source, query_processor.QueryProcessor, params, - verbose) - - -class cmd_fast_export(Command): - """Generate a fast-import stream from a Bazaar branch. - - This program generates a stream from a Bazaar branch in fast-import - format used by tools such as bzr fast-import, git-fast-import and - hg-fast-import. - - If no destination is given or the destination is '-', standard output - is used. Otherwise, the destination is the name of a file. If the - destination ends in '.gz', the output will be compressed into gzip - format. - - :Round-tripping: - - Recent versions of the fast-import specification support features - that allow effective round-tripping of many Bazaar branches. As - such, fast-exporting a branch and fast-importing the data produced - will create a new repository with equivalent history, i.e. - "bzr log -v -p --include-merges --forward" on the old branch and - new branch should produce similar, if not identical, results. - - .. note:: - - Be aware that the new repository may appear to have similar history - but internally it is quite different with new revision-ids and - file-ids assigned. As a consequence, the ability to easily merge - with branches based on the old repository is lost. Depending on your - reasons for producing a new repository, this may or may not be an - issue. - - :Interoperability: - - fast-export can use the following "extended features" to - produce a richer data stream: - - * *multiple-authors* - if a commit has multiple authors (as commonly - occurs in pair-programming), all authors will be included in the - output, not just the first author - - * *commit-properties* - custom metadata per commit that Bazaar stores - in revision properties (e.g. branch-nick and bugs fixed by this - change) will be included in the output. - - * *empty-directories* - directories, even the empty ones, will be - included in the output. - - To disable these features and produce output acceptable to git 1.6, - use the --plain option. To enable these features, use --no-plain. - Currently, --plain is the default but that will change in the near - future once the feature names and definitions are formally agreed - to by the broader fast-import developer community. - - :Examples: - - To produce data destined for import into Bazaar:: - - bzr fast-export --no-plain my-bzr-branch my.fi.gz - - To produce data destined for Git 1.6:: - - bzr fast-export --plain my-bzr-branch my.fi - - To import several unmerged but related branches into the same repository, - use the --{export,import}-marks options, and specify a name for the git - branch like this:: - - bzr fast-export --export-marks=marks.bzr project.dev | - GIT_DIR=project/.git git-fast-import --export-marks=marks.git - - bzr fast-export --import-marks=marks.bzr -b other project.other | - GIT_DIR=project/.git git-fast-import --import-marks=marks.git - - If you get a "Missing space after source" error from git-fast-import, - see the top of the commands.py module for a work-around. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination?'] - takes_options = ['verbose', 'revision', - Option('git-branch', short_name='b', type=str, - argname='FILE', - help='Name of the git branch to create (default=master).' - ), - Option('checkpoint', type=int, argname='N', - help="Checkpoint every N revisions (default=10000)." - ), - Option('marks', type=str, argname='FILE', - help="Import marks from and export marks to file." - ), - Option('import-marks', type=str, argname='FILE', - help="Import marks from file." - ), - Option('export-marks', type=str, argname='FILE', - help="Export marks to file." - ), - Option('plain', - help="Exclude metadata to maximise interoperability." - ), - ] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination=None, verbose=False, - git_branch="master", checkpoint=10000, marks=None, - import_marks=None, export_marks=None, revision=None, - plain=True): - load_fastimport() - from bzrlib.plugins.fastimport import exporter - - if marks: - import_marks = export_marks = marks - exporter = exporter.BzrFastExporter(source, - destination=destination, - git_branch=git_branch, checkpoint=checkpoint, - import_marks_file=import_marks, export_marks_file=export_marks, - revision=revision, verbose=verbose, plain_format=plain) - return exporter.run() - - -class cmd_fast_export_from_cvs(Command): - """Generate a fast-import file from a CVS repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - cvs2svn 2.3 or later must be installed as its cvs2bzr script is used - under the covers to do the export. - - The source must be the path on your filesystem to the part of the - repository you wish to convert. i.e. either that path or a parent - directory must contain a CVSROOT subdirectory. The path may point to - either the top of a repository or to a path within it. In the latter - case, only that project within the repository will be converted. - - .. note:: - Remote access to the repository is not sufficient - the path - must point into a copy of the repository itself. See - http://cvs2svn.tigris.org/faq.html#repoaccess for instructions - on how to clone a remote CVS repository locally. - - By default, the trunk, branches and tags are all exported. If you - only want the trunk, use the `--trunk-only` option. - - By default, filenames, log messages and author names are expected - to be encoded in ascii. Use the `--encoding` option to specify an - alternative. If multiple encodings are used, specify the option - multiple times. For a list of valid encoding names, see - http://docs.python.org/lib/standard-encodings.html. - - Windows users need to install GNU sort and use the `--sort` - option to specify its location. GNU sort can be downloaded from - http://unxutils.sourceforge.net/. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose', - Option('trunk-only', - help="Export just the trunk, ignoring tags and branches." - ), - ListOption('encoding', type=str, argname='CODEC', - help="Encoding used for filenames, commit messages " - "and author names if not ascii." - ), - Option('sort', type=str, argname='PATH', - help="GNU sort program location if not on the path." - ), - ] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False, trunk_only=False, - encoding=None, sort=None): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - custom = [] - if trunk_only: - custom.append("--trunk-only") - if encoding: - for enc in encoding: - custom.extend(['--encoding', enc]) - if sort: - custom.extend(['--sort', sort]) - fast_export_from(source, destination, 'cvs', verbose, custom) - - -class cmd_fast_export_from_darcs(Command): - """Generate a fast-import file from a Darcs repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - Darcs 2.2 or later must be installed as various subcommands are - used to access the source repository. The source may be a network - URL but using a local URL is recommended for performance reasons. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose', - Option('encoding', type=str, argname='CODEC', - help="Encoding used for commit messages if not utf-8." - ), - ] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False, encoding=None): - from bzrlib.plugins.fastimport.exporters import fast_export_from - custom = None - if encoding is not None: - custom = ['--encoding', encoding] - fast_export_from(source, destination, 'darcs', verbose, custom) - - -class cmd_fast_export_from_hg(Command): - """Generate a fast-import file from a Mercurial repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - Mercurial 1.2 or later must be installed as its libraries are used - to access the source repository. Given the APIs currently used, - the source repository must be a local file, not a network URL. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose'] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - fast_export_from(source, destination, 'hg', verbose) - - -class cmd_fast_export_from_git(Command): - """Generate a fast-import file from a Git repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - Git 1.6 or later must be installed as the git fast-export - subcommand is used under the covers to generate the stream. - The source must be a local directory. - - .. note:: - - Earlier versions of Git may also work fine but are - likely to receive less active support if problems arise. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose'] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - fast_export_from(source, destination, 'git', verbose) - - -class cmd_fast_export_from_mtn(Command): - """Generate a fast-import file from a Monotone repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - Monotone 0.43 or later must be installed as the mtn git_export - subcommand is used under the covers to generate the stream. - The source must be a local directory. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose'] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - fast_export_from(source, destination, 'mtn', verbose) - - -class cmd_fast_export_from_p4(Command): - """Generate a fast-import file from a Perforce repository. - - Source is a Perforce depot path, e.g., //depot/project - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - bzrp4 must be installed as its p4_fast_export.py module is used under - the covers to do the export. bzrp4 can be downloaded from - https://launchpad.net/bzrp4/. - - The P4PORT environment variable must be set, and you must be logged - into the Perforce server. - - By default, only the HEAD changelist is exported. To export all - changelists, append '@all' to the source. To export a revision range, - append a comma-delimited pair of changelist numbers to the source, - e.g., '100,200'. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = [] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - custom = [] - fast_export_from(source, destination, 'p4', verbose, custom) - - -class cmd_fast_export_from_svn(Command): - """Generate a fast-import file from a Subversion repository. - - Destination is a dump file, typically named xxx.fi where xxx is - the name of the project. If '-' is given, standard output is used. - - Python-Subversion (Python bindings to the Subversion APIs) - 1.4 or later must be installed as this library is used to - access the source repository. The source may be a network URL - but using a local URL is recommended for performance reasons. - """ - hidden = False - _see_also = ['fast-import', 'fast-import-filter'] - takes_args = ['source', 'destination'] - takes_options = ['verbose', - Option('trunk-path', type=str, argname="STR", - help="Path in repo to /trunk.\n" - "May be `regex:/cvs/(trunk)/proj1/(.*)` in " - "which case the first group is used as the " - "branch name and the second group is used " - "to match files.", - ), - Option('branches-path', type=str, argname="STR", - help="Path in repo to /branches." - ), - Option('tags-path', type=str, argname="STR", - help="Path in repo to /tags." - ), - ] - aliases = [] - encoding_type = 'exact' - def run(self, source, destination, verbose=False, trunk_path=None, - branches_path=None, tags_path=None): - load_fastimport() - from bzrlib.plugins.fastimport.exporters import fast_export_from - custom = [] - if trunk_path is not None: - custom.extend(['--trunk-path', trunk_path]) - if branches_path is not None: - custom.extend(['--branches-path', branches_path]) - if tags_path is not None: - custom.extend(['--tags-path', tags_path]) - fast_export_from(source, destination, 'svn', verbose, custom) - - -register_command(cmd_fast_import) -register_command(cmd_fast_import_filter) -register_command(cmd_fast_import_info) -register_command(cmd_fast_import_query) -register_command(cmd_fast_export) -register_command(cmd_fast_export_from_cvs) -register_command(cmd_fast_export_from_darcs) -register_command(cmd_fast_export_from_hg) -register_command(cmd_fast_export_from_git) -register_command(cmd_fast_export_from_mtn) -register_command(cmd_fast_export_from_p4) -register_command(cmd_fast_export_from_svn) +for name in [ + "fast_import", + "fast_import_filter", + "fast_import_info", + "fast_import_query", + "fast_export", + "fast_export_from_cvs", + "fast_export_from_darcs", + "fast_export_from_hg", + "fast_export_from_git", + "fast_export_from_mtn", + "fast_export_from_p4", + "fast_export_from_svn" + ]: + plugin_cmds.register_lazy("cmd_%s" % name, [], "bzrlib.plugins.fastimport.cmds") @@ -0,0 +1,878 @@ +# Copyright (C) 2008 Canonical Ltd +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +"""Fastimport/fastexport commands.""" + +from bzrlib import bzrdir +from bzrlib.commands import Command +from bzrlib.option import Option, ListOption, RegistryOption + +from bzrlib.plugins.fastimport import load_fastimport + + +def _run(source, processor_factory, control, params, verbose, + user_map=None): + """Create and run a processor. + + :param source: a filename or '-' for standard input. If the + filename ends in .gz, it will be opened as a gzip file and + the stream will be implicitly uncompressed + :param processor_factory: a callable for creating a processor + :param control: the BzrDir of the destination or None if no + destination is expected + :param user_map: if not None, the file containing the user map. + """ + from fastimport import parser + stream = _get_source_stream(source) + user_mapper = _get_user_mapper(user_map) + proc = processor_factory(control, params=params, verbose=verbose) + p = parser.ImportParser(stream, verbose=verbose, user_mapper=user_mapper) + return proc.process(p.iter_commands) + + +def _get_source_stream(source): + if source == '-': + import sys + from fastimport import helpers + stream = helpers.binary_stream(sys.stdin) + elif source.endswith('.gz'): + import gzip + stream = gzip.open(source, "rb") + else: + stream = open(source, "rb") + return stream + + +def _get_user_mapper(filename): + import user_mapper + if filename is None: + return None + f = open(filename) + lines = f.readlines() + f.close() + return user_mapper.UserMapper(lines) + + +class cmd_fast_import(Command): + """Backend for fast Bazaar data importers. + + This command reads a mixed command/data stream and creates + branches in a Bazaar repository accordingly. The preferred + recipe is:: + + bzr fast-import project.fi project.bzr + + Numerous commands are provided for generating a fast-import file + to use as input. These are named fast-export-from-xxx where xxx + is one of cvs, darcs, git, hg, mtn, p4 or svn. + To specify standard input as the input stream, use a + source name of '-' (instead of project.fi). If the source name + ends in '.gz', it is assumed to be compressed in gzip format. + + project.bzr will be created if it doesn't exist. If it exists + already, it should be empty or be an existing Bazaar repository + or branch. If not specified, the current directory is assumed. + + fast-import will intelligently select the format to use when + creating a repository or branch. If you are running Bazaar 1.17 + up to Bazaar 2.0, the default format for Bazaar 2.x ("2a") is used. + Otherwise, the current default format ("pack-0.92" for Bazaar 1.x) + is used. If you wish to specify a custom format, use the `--format` + option. + + .. note:: + + To maintain backwards compatibility, fast-import lets you + create the target repository or standalone branch yourself. + It is recommended though that you let fast-import create + these for you instead. + + :Branch mapping rules: + + Git reference names are mapped to Bazaar branch names as follows: + + * refs/heads/foo is mapped to foo + * refs/remotes/origin/foo is mapped to foo.remote + * refs/tags/foo is mapped to foo.tag + * */master is mapped to trunk, trunk.remote, etc. + * */trunk is mapped to git-trunk, git-trunk.remote, etc. + + :Branch creation rules: + + When a shared repository is created or found at the destination, + branches are created inside it. In the simple case of a single + branch (refs/heads/master) inside the input file, the branch is + project.bzr/trunk. + + When a standalone branch is found at the destination, the trunk + is imported there and warnings are output about any other branches + found in the input file. + + When a branch in a shared repository is found at the destination, + that branch is made the trunk and other branches, if any, are + created in sister directories. + + :Working tree updates: + + The working tree is generated for the trunk branch. If multiple + branches are created, a message is output on completion explaining + how to create the working trees for other branches. + + :Custom exporters: + + The fast-export-from-xxx commands typically call more advanced + xxx-fast-export scripts. You are welcome to use the advanced + scripts if you prefer. + + If you wish to write a custom exporter for your project, see + http://bazaar-vcs.org/BzrFastImport for the detailed protocol + specification. In many cases, exporters can be written quite + quickly using whatever scripting/programming language you like. + + :User mapping: + + Some source repositories store just the user name while Bazaar + prefers a full email address. You can adjust user-ids while + importing by using the --user-map option. The argument is a + text file with lines in the format:: + + old-id = new-id + + Blank lines and lines beginning with # are ignored. + If old-id has the special value '@', then users without an + email address will get one created by using the matching new-id + as the domain, unless a more explicit address is given for them. + For example, given the user-map of:: + + @ = example.com + bill = William Jones <bill@example.com> + + then user-ids are mapped as follows:: + + maria => maria <maria@example.com> + bill => William Jones <bill@example.com> + + .. note:: + + User mapping is supported by both the fast-import and + fast-import-filter commands. + + :Blob tracking: + + As some exporters (like git-fast-export) reuse blob data across + commits, fast-import makes two passes over the input file by + default. In the first pass, it collects data about what blobs are + used when, along with some other statistics (e.g. total number of + commits). In the second pass, it generates the repository and + branches. + + .. note:: + + The initial pass isn't done if the --info option is used + to explicitly pass in information about the input stream. + It also isn't done if the source is standard input. In the + latter case, memory consumption may be higher than otherwise + because some blobs may be kept in memory longer than necessary. + + :Restarting an import: + + At checkpoints and on completion, the commit-id -> revision-id + map is saved to a file called 'fastimport-id-map' in the control + directory for the repository (e.g. .bzr/repository). If the import + is interrupted or unexpectedly crashes, it can be started again + and this file will be used to skip over already loaded revisions. + As long as subsequent exports from the original source begin + with exactly the same revisions, you can use this feature to + maintain a mirror of a repository managed by a foreign tool. + If and when Bazaar is used to manage the repository, this file + can be safely deleted. + + :Examples: + + Import a Subversion repository into Bazaar:: + + bzr fast-export-from-svn /svn/repo/path project.fi + bzr fast-import project.fi project.bzr + + Import a CVS repository into Bazaar:: + + bzr fast-export-from-cvs /cvs/repo/path project.fi + bzr fast-import project.fi project.bzr + + Import a Git repository into Bazaar:: + + bzr fast-export-from-git /git/repo/path project.fi + bzr fast-import project.fi project.bzr + + Import a Mercurial repository into Bazaar:: + + bzr fast-export-from-hg /hg/repo/path project.fi + bzr fast-import project.fi project.bzr + + Import a Darcs repository into Bazaar:: + + bzr fast-export-from-darcs /darcs/repo/path project.fi + bzr fast-import project.fi project.bzr + """ + hidden = False + _see_also = ['fast-export', 'fast-import-filter', 'fast-import-info'] + takes_args = ['source', 'destination?'] + takes_options = ['verbose', + Option('user-map', type=str, + help="Path to file containing a map of user-ids.", + ), + Option('info', type=str, + help="Path to file containing caching hints.", + ), + Option('trees', + help="Update all working trees, not just trunk's.", + ), + Option('count', type=int, + help="Import this many revisions then exit.", + ), + Option('checkpoint', type=int, + help="Checkpoint automatically every N revisions." + " The default is 10000.", + ), + Option('autopack', type=int, + help="Pack every N checkpoints. The default is 4.", + ), + Option('inv-cache', type=int, + help="Number of inventories to cache.", + ), + RegistryOption.from_kwargs('mode', + 'The import algorithm to use.', + title='Import Algorithm', + default='Use the preferred algorithm (inventory deltas).', + classic="Use the original algorithm (mutable inventories).", + experimental="Enable experimental features.", + value_switches=True, enum_switch=False, + ), + Option('import-marks', type=str, + help="Import marks from file." + ), + Option('export-marks', type=str, + help="Export marks to file." + ), + RegistryOption('format', + help='Specify a format for the created repository. See' + ' "bzr help formats" for details.', + lazy_registry=('bzrlib.bzrdir', 'format_registry'), + converter=lambda name: bzrdir.format_registry.make_bzrdir(name), + value_switches=False, title='Repository format'), + ] + def run(self, source, destination='.', verbose=False, info=None, + trees=False, count=-1, checkpoint=10000, autopack=4, inv_cache=-1, + mode=None, import_marks=None, export_marks=None, format=None, + user_map=None): + load_fastimport() + from bzrlib.plugins.fastimport.processors import generic_processor + from bzrlib.plugins.fastimport.helpers import ( + open_destination_directory, + ) + # If no format is given and the user is running a release + # leading up to 2.0, select 2a for them. Otherwise, use + # the default format. + if format is None: + import bzrlib + bzr_version = bzrlib.version_info[0:2] + if bzr_version in [(1,17), (1,18), (2,0)]: + format = bzrdir.format_registry.make_bzrdir('2a') + control = open_destination_directory(destination, format=format) + + # If an information file was given and the source isn't stdin, + # generate the information by reading the source file as a first pass + if info is None and source != '-': + info = self._generate_info(source) + + # Do the work + if mode is None: + mode = 'default' + params = { + 'info': info, + 'trees': trees, + 'count': count, + 'checkpoint': checkpoint, + 'autopack': autopack, + 'inv-cache': inv_cache, + 'mode': mode, + 'import-marks': import_marks, + 'export-marks': export_marks, + } + return _run(source, generic_processor.GenericProcessor, control, + params, verbose, user_map=user_map) + + def _generate_info(self, source): + from cStringIO import StringIO + from fastimport import parser + from fastimport.processors import info_processor + stream = _get_source_stream(source) + output = StringIO() + try: + proc = info_processor.InfoProcessor(verbose=True, outf=output) + p = parser.ImportParser(stream) + return_code = proc.process(p.iter_commands) + lines = output.getvalue().splitlines() + finally: + output.close() + stream.seek(0) + return lines + + +class cmd_fast_import_filter(Command): + """Filter a fast-import stream to include/exclude files & directories. + + This command is useful for splitting a subdirectory or bunch of + files out from a project to create a new project complete with history + for just those files. It can also be used to create a new project + repository that removes all references to files that should not have + been committed, e.g. security-related information (like passwords), + commercially sensitive material, files with an incompatible license or + large binary files like CD images. + + To specify standard input as the input stream, use a source name + of '-'. If the source name ends in '.gz', it is assumed to be + compressed in gzip format. + + :File/directory filtering: + + This is supported by the -i and -x options. Excludes take precedence + over includes. + + When filtering out a subdirectory (or file), the new stream uses the + subdirectory (or subdirectory containing the file) as the root. As + fast-import doesn't know in advance whether a path is a file or + directory in the stream, you need to specify a trailing '/' on + directories passed to the `--includes option`. If multiple files or + directories are given, the new root is the deepest common directory. + + Note: If a path has been renamed, take care to specify the *original* + path name, not the final name that it ends up with. + + :User mapping: + + Some source repositories store just the user name while Bazaar + prefers a full email address. You can adjust user-ids + by using the --user-map option. The argument is a + text file with lines in the format:: + + old-id = new-id + + Blank lines and lines beginning with # are ignored. + If old-id has the special value '@', then users without an + email address will get one created by using the matching new-id + as the domain, unless a more explicit address is given for them. + For example, given the user-map of:: + + @ = example.com + bill = William Jones <bill@example.com> + + then user-ids are mapped as follows:: + + maria => maria <maria@example.com> + bill => William Jones <bill@example.com> + + .. note:: + + User mapping is supported by both the fast-import and + fast-import-filter commands. + + :Examples: + + Create a new project from a library (note the trailing / on the + directory name of the library):: + + front-end | bzr fast-import-filter -i lib/xxx/ > xxx.fi + bzr fast-import xxx.fi mylibrary.bzr + (lib/xxx/foo is now foo) + + Create a new repository without a sensitive file:: + + front-end | bzr fast-import-filter -x missile-codes.txt > clean.fi + bzr fast-import clean.fi clean.bzr + """ + hidden = False + _see_also = ['fast-import'] + takes_args = ['source'] + takes_options = ['verbose', + ListOption('include_paths', short_name='i', type=str, + help="Only include commits affecting these paths." + " Directories should have a trailing /." + ), + ListOption('exclude_paths', short_name='x', type=str, + help="Exclude these paths from commits." + ), + Option('user-map', type=str, + help="Path to file containing a map of user-ids.", + ), + ] + encoding_type = 'exact' + def run(self, source, verbose=False, include_paths=None, + exclude_paths=None, user_map=None): + load_fastimport() + from fastimport.processors import filter_processor + params = { + 'include_paths': include_paths, + 'exclude_paths': exclude_paths, + } + return _run(source, filter_processor.FilterProcessor, params, + verbose, user_map=user_map) + + +class cmd_fast_import_info(Command): + """Output information about a fast-import stream. + + This command reads a fast-import stream and outputs + statistics and interesting properties about what it finds. + When run in verbose mode, the information is output as a + configuration file that can be passed to fast-import to + assist it in intelligently caching objects. + + To specify standard input as the input stream, use a source name + of '-'. If the source name ends in '.gz', it is assumed to be + compressed in gzip format. + + :Examples: + + Display statistics about the import stream produced by front-end:: + + front-end | bzr fast-import-info - + + Create a hints file for running fast-import on a large repository:: + + front-end | bzr fast-import-info -v - > front-end.cfg + """ + hidden = False + _see_also = ['fast-import'] + takes_args = ['source'] + takes_options = ['verbose'] + def run(self, source, verbose=False): + load_fastimport() + from fastimport.processors import info_processor + return _run(source, info_processor.InfoProcessor, {}, verbose) + + +class cmd_fast_import_query(Command): + """Query a fast-import stream displaying selected commands. + + To specify standard input as the input stream, use a source name + of '-'. If the source name ends in '.gz', it is assumed to be + compressed in gzip format. + + To specify a commit to display, give its mark using the + --commit-mark option. The commit will be displayed with + file-commands included but with inline blobs hidden. + + To specify the commands to display, use the -C option one or + more times. To specify just some fields for a command, use the + syntax:: + + command=field1,... + + By default, the nominated fields for the nominated commands + are displayed tab separated. To see the information in + a name:value format, use verbose mode. + + Note: Binary fields (e.g. data for blobs) are masked out + so it is generally safe to view the output in a terminal. + + :Examples: + + Show the commit with mark 429:: + + bzr fast-import-query xxx.fi -m429 + + Show all the fields of the reset and tag commands:: + + bzr fast-import-query xxx.fi -Creset -Ctag + + Show the mark and merge fields of the commit commands:: + + bzr fast-import-query xxx.fi -Ccommit=mark,merge + """ + hidden = True + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source'] + takes_options = ['verbose', + Option('commit-mark', short_name='m', type=str, + help="Mark of the commit to display." + ), + ListOption('commands', short_name='C', type=str, + help="Display fields for these commands." + ), + ] + def run(self, source, verbose=False, commands=None, commit_mark=None): + load_fastimport() + from fastimport.processors import query_processor + from bzrlib.plugins.fastimport import helpers + params = helpers.defines_to_dict(commands) or {} + if commit_mark: + params['commit-mark'] = commit_mark + return _run(source, query_processor.QueryProcessor, params, + verbose) + + +class cmd_fast_export(Command): + """Generate a fast-import stream from a Bazaar branch. + + This program generates a stream from a Bazaar branch in fast-import + format used by tools such as bzr fast-import, git-fast-import and + hg-fast-import. + + If no destination is given or the destination is '-', standard output + is used. Otherwise, the destination is the name of a file. If the + destination ends in '.gz', the output will be compressed into gzip + format. + + :Round-tripping: + + Recent versions of the fast-import specification support features + that allow effective round-tripping of many Bazaar branches. As + such, fast-exporting a branch and fast-importing the data produced + will create a new repository with equivalent history, i.e. + "bzr log -v -p --include-merges --forward" on the old branch and + new branch should produce similar, if not identical, results. + + .. note:: + + Be aware that the new repository may appear to have similar history + but internally it is quite different with new revision-ids and + file-ids assigned. As a consequence, the ability to easily merge + with branches based on the old repository is lost. Depending on your + reasons for producing a new repository, this may or may not be an + issue. + + :Interoperability: + + fast-export can use the following "extended features" to + produce a richer data stream: + + * *multiple-authors* - if a commit has multiple authors (as commonly + occurs in pair-programming), all authors will be included in the + output, not just the first author + + * *commit-properties* - custom metadata per commit that Bazaar stores + in revision properties (e.g. branch-nick and bugs fixed by this + change) will be included in the output. + + * *empty-directories* - directories, even the empty ones, will be + included in the output. + + To disable these features and produce output acceptable to git 1.6, + use the --plain option. To enable these features, use --no-plain. + Currently, --plain is the default but that will change in the near + future once the feature names and definitions are formally agreed + to by the broader fast-import developer community. + + :Examples: + + To produce data destined for import into Bazaar:: + + bzr fast-export --no-plain my-bzr-branch my.fi.gz + + To produce data destined for Git 1.6:: + + bzr fast-export --plain my-bzr-branch my.fi + + To import several unmerged but related branches into the same repository, + use the --{export,import}-marks options, and specify a name for the git + branch like this:: + + bzr fast-export --export-marks=marks.bzr project.dev | + GIT_DIR=project/.git git-fast-import --export-marks=marks.git + + bzr fast-export --import-marks=marks.bzr -b other project.other | + GIT_DIR=project/.git git-fast-import --import-marks=marks.git + + If you get a "Missing space after source" error from git-fast-import, + see the top of the commands.py module for a work-around. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination?'] + takes_options = ['verbose', 'revision', + Option('git-branch', short_name='b', type=str, + argname='FILE', + help='Name of the git branch to create (default=master).' + ), + Option('checkpoint', type=int, argname='N', + help="Checkpoint every N revisions (default=10000)." + ), + Option('marks', type=str, argname='FILE', + help="Import marks from and export marks to file." + ), + Option('import-marks', type=str, argname='FILE', + help="Import marks from file." + ), + Option('export-marks', type=str, argname='FILE', + help="Export marks to file." + ), + Option('plain', + help="Exclude metadata to maximise interoperability." + ), + ] + encoding_type = 'exact' + def run(self, source, destination=None, verbose=False, + git_branch="master", checkpoint=10000, marks=None, + import_marks=None, export_marks=None, revision=None, + plain=True): + load_fastimport() + from bzrlib.plugins.fastimport import exporter + + if marks: + import_marks = export_marks = marks + exporter = exporter.BzrFastExporter(source, + destination=destination, + git_branch=git_branch, checkpoint=checkpoint, + import_marks_file=import_marks, export_marks_file=export_marks, + revision=revision, verbose=verbose, plain_format=plain) + return exporter.run() + + +class cmd_fast_export_from_cvs(Command): + """Generate a fast-import file from a CVS repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + cvs2svn 2.3 or later must be installed as its cvs2bzr script is used + under the covers to do the export. + + The source must be the path on your filesystem to the part of the + repository you wish to convert. i.e. either that path or a parent + directory must contain a CVSROOT subdirectory. The path may point to + either the top of a repository or to a path within it. In the latter + case, only that project within the repository will be converted. + + .. note:: + Remote access to the repository is not sufficient - the path + must point into a copy of the repository itself. See + http://cvs2svn.tigris.org/faq.html#repoaccess for instructions + on how to clone a remote CVS repository locally. + + By default, the trunk, branches and tags are all exported. If you + only want the trunk, use the `--trunk-only` option. + + By default, filenames, log messages and author names are expected + to be encoded in ascii. Use the `--encoding` option to specify an + alternative. If multiple encodings are used, specify the option + multiple times. For a list of valid encoding names, see + http://docs.python.org/lib/standard-encodings.html. + + Windows users need to install GNU sort and use the `--sort` + option to specify its location. GNU sort can be downloaded from + http://unxutils.sourceforge.net/. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose', + Option('trunk-only', + help="Export just the trunk, ignoring tags and branches." + ), + ListOption('encoding', type=str, argname='CODEC', + help="Encoding used for filenames, commit messages " + "and author names if not ascii." + ), + Option('sort', type=str, argname='PATH', + help="GNU sort program location if not on the path." + ), + ] + encoding_type = 'exact' + def run(self, source, destination, verbose=False, trunk_only=False, + encoding=None, sort=None): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + custom = [] + if trunk_only: + custom.append("--trunk-only") + if encoding: + for enc in encoding: + custom.extend(['--encoding', enc]) + if sort: + custom.extend(['--sort', sort]) + fast_export_from(source, destination, 'cvs', verbose, custom) + + +class cmd_fast_export_from_darcs(Command): + """Generate a fast-import file from a Darcs repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + Darcs 2.2 or later must be installed as various subcommands are + used to access the source repository. The source may be a network + URL but using a local URL is recommended for performance reasons. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose', + Option('encoding', type=str, argname='CODEC', + help="Encoding used for commit messages if not utf-8." + ), + ] + encoding_type = 'exact' + def run(self, source, destination, verbose=False, encoding=None): + from bzrlib.plugins.fastimport.exporters import fast_export_from + custom = None + if encoding is not None: + custom = ['--encoding', encoding] + fast_export_from(source, destination, 'darcs', verbose, custom) + + +class cmd_fast_export_from_hg(Command): + """Generate a fast-import file from a Mercurial repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + Mercurial 1.2 or later must be installed as its libraries are used + to access the source repository. Given the APIs currently used, + the source repository must be a local file, not a network URL. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose'] + encoding_type = 'exact' + def run(self, source, destination, verbose=False): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + fast_export_from(source, destination, 'hg', verbose) + + +class cmd_fast_export_from_git(Command): + """Generate a fast-import file from a Git repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + Git 1.6 or later must be installed as the git fast-export + subcommand is used under the covers to generate the stream. + The source must be a local directory. + + .. note:: + + Earlier versions of Git may also work fine but are + likely to receive less active support if problems arise. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose'] + encoding_type = 'exact' + def run(self, source, destination, verbose=False): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + fast_export_from(source, destination, 'git', verbose) + + +class cmd_fast_export_from_mtn(Command): + """Generate a fast-import file from a Monotone repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + Monotone 0.43 or later must be installed as the mtn git_export + subcommand is used under the covers to generate the stream. + The source must be a local directory. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose'] + encoding_type = 'exact' + def run(self, source, destination, verbose=False): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + fast_export_from(source, destination, 'mtn', verbose) + + +class cmd_fast_export_from_p4(Command): + """Generate a fast-import file from a Perforce repository. + + Source is a Perforce depot path, e.g., //depot/project + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + bzrp4 must be installed as its p4_fast_export.py module is used under + the covers to do the export. bzrp4 can be downloaded from + https://launchpad.net/bzrp4/. + + The P4PORT environment variable must be set, and you must be logged + into the Perforce server. + + By default, only the HEAD changelist is exported. To export all + changelists, append '@all' to the source. To export a revision range, + append a comma-delimited pair of changelist numbers to the source, + e.g., '100,200'. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = [] + encoding_type = 'exact' + def run(self, source, destination, verbose=False): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + custom = [] + fast_export_from(source, destination, 'p4', verbose, custom) + + +class cmd_fast_export_from_svn(Command): + """Generate a fast-import file from a Subversion repository. + + Destination is a dump file, typically named xxx.fi where xxx is + the name of the project. If '-' is given, standard output is used. + + Python-Subversion (Python bindings to the Subversion APIs) + 1.4 or later must be installed as this library is used to + access the source repository. The source may be a network URL + but using a local URL is recommended for performance reasons. + """ + hidden = False + _see_also = ['fast-import', 'fast-import-filter'] + takes_args = ['source', 'destination'] + takes_options = ['verbose', + Option('trunk-path', type=str, argname="STR", + help="Path in repo to /trunk.\n" + "May be `regex:/cvs/(trunk)/proj1/(.*)` in " + "which case the first group is used as the " + "branch name and the second group is used " + "to match files.", + ), + Option('branches-path', type=str, argname="STR", + help="Path in repo to /branches." + ), + Option('tags-path', type=str, argname="STR", + help="Path in repo to /tags." + ), + ] + encoding_type = 'exact' + def run(self, source, destination, verbose=False, trunk_path=None, + branches_path=None, tags_path=None): + load_fastimport() + from bzrlib.plugins.fastimport.exporters import fast_export_from + custom = [] + if trunk_path is not None: + custom.extend(['--trunk-path', trunk_path]) + if branches_path is not None: + custom.extend(['--branches-path', branches_path]) + if tags_path is not None: + custom.extend(['--tags-path', tags_path]) + fast_export_from(source, destination, 'svn', verbose, custom) diff --git a/tests/test_commands.py b/tests/test_commands.py index 0608c9e..81a43c8 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -22,7 +22,7 @@ import gzip from bzrlib import tests -from bzrlib.plugins.fastimport import ( +from bzrlib.plugins.fastimport.cmds import ( _get_source_stream, ) |