345
341
###class Importer(object):
346
342
### """An importer.
348
344
### Currently this is used as a parameter object, though more behaviour is
349
345
### possible later.
352
### def __init__(self, output_dir, version, fast=False,
353
### verbose=False, dry_run=False, max_count=None,
348
### def __init__(self, output_dir, version, printer, fancy=True, fast=False,
349
### verbose=False, dry_run=False, max_count=None,
354
350
### reuse_history_from=[]):
355
351
### self.output_dir = output_dir
356
352
### self.version = version
360
def import_version(output_dir, version, encoding, fast=False,
356
def import_version(output_dir, version, printer, fancy=True, fast=False,
361
357
verbose=False, dry_run=False, max_count=None,
362
358
reuse_history_from=[], standalone=True):
364
360
>>> q = test_environ()
366
Progress bars output to stderr, but doctest does not capture that.
368
>>> old_stderr = sys.stderr
369
>>> sys.stderr = sys.stdout
371
361
>>> result_path = os.path.join(q, "result")
372
362
>>> commit_test_revisions()
373
363
>>> version = pybaz.Version("test@example.com/test--test--0.1")
374
>>> old_ui = bzrlib.ui.ui_factory
375
>>> bzrlib.ui.ui_factory = bzrlib.ui.text.TextUIFactory(
376
... bar_type=bzrlib.progress.DotsProgressBar)
378
>>> import_version('/', version, None, dry_run=True)
364
>>> def printer(message): print message
365
>>> import_version('/', version, printer, fancy=False, dry_run=True)
379
366
Traceback (most recent call last):
380
367
NotPreviousImport: / is not the location of a previous import.
381
>>> import_version(result_path, version, None, dry_run=True)
368
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
382
369
Traceback (most recent call last):
383
370
UserError: The version test@example.com/test--test--0.1 does not exist.
384
371
>>> version = pybaz.Version("test@example.com/test--test--0")
385
>>> import_version(result_path, version, None, dry_run=True) #doctest: +ELLIPSIS
386
importing test@example.com/test--test--0 into ...
388
revisions: ..........................................
372
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
389
375
Dry run, not modifying output_dir
391
>>> import_version(result_path, version, None) #doctest: +ELLIPSIS
392
importing test@example.com/test--test--0 into ...
394
revisions: .....................................................................
377
>>> import_version(result_path, version, printer, fancy=False)
397
>>> import_version(result_path, version, None) #doctest: +ELLIPSIS
382
>>> import_version(result_path, version, printer, fancy=False)
398
383
Tree is up-to-date with test@example.com/test--test--0--patch-2
399
384
>>> commit_more_test_revisions()
400
>>> import_version(result_path, version, None) #doctest: +ELLIPSIS
401
importing test@example.com/test--test--0 into ...
402
revisions: ....................................................
385
>>> import_version(result_path, version, printer, fancy=False)
405
>>> bzrlib.ui.ui_factory = old_ui
406
>>> sys.stderr = old_stderr
407
390
>>> teardown_environ(q)
409
progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
393
ancestors, old_revno = get_remaining_revisions(output_dir, version,
395
except NotBranchError, e:
396
raise NotPreviousImport(e.path)
397
if old_revno is None and len(ancestors) == 0:
398
print 'Version %s has no revisions.' % version
400
if len(ancestors) == 0:
401
last_revision = get_last_revision(Branch.open(output_dir))
402
print 'Tree is up-to-date with %s' % last_revision
405
progress_bar = bzrlib.ui.ui_factory.progress_bar()
406
tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
407
dir=os.path.dirname(output_dir))
409
wt = WorkingTree.open(output_dir)
410
except (NotBranchError, NoWorkingTree):
413
old_basis = EmptyTree()
415
old_basis = wt.basis_tree()
412
ancestors, old_revno = get_remaining_revisions(output_dir, version,
415
except NotBranchError, e:
416
raise NotPreviousImport(e.path)
417
if old_revno is None and len(ancestors) == 0:
418
progress_bar.note('Version %s has no revisions.' % version)
420
if len(ancestors) == 0:
421
last_revision, last_encoding = \
422
get_last_revision(Branch.open(output_dir))
423
progress_bar.note('Tree is up-to-date with %s' % last_revision)
426
progress_bar.note("importing %s into %s" % (version, output_dir))
428
tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
429
dir=os.path.dirname(output_dir))
420
for result in iter_import_version(output_dir, ancestors, tempdir,
421
progress_bar, fast=fast, verbose=verbose, dry_run=dry_run,
422
max_count=max_count, standalone=standalone):
424
show_progress(progress_bar, result)
426
sys.stdout.write('.')
431
sys.stdout.write('\n')
434
print 'Dry run, not modifying output_dir'
437
# Update the working tree of the branch
431
439
wt = WorkingTree.open(output_dir)
432
except (NotBranchError, NoWorkingTree):
440
except NoWorkingTree:
435
for result in iter_import_version(output_dir, ancestors, tempdir,
436
pb=progress_bar, encoding=encoding, fast=fast,
437
verbose=verbose, dry_run=dry_run, max_count=max_count,
438
standalone=standalone):
439
show_progress(progress_bar, result)
441
progress_bar.note('Dry run, not modifying output_dir')
444
# Update the working tree of the branch
446
wt = WorkingTree.open(output_dir)
447
except NoWorkingTree:
450
wt.set_last_revision(wt.branch.last_revision())
451
wt.set_root_id(BAZ_IMPORT_ROOT)
456
progress_bar.note('Cleaning up')
457
shutil.rmtree(tempdir)
458
progress_bar.note("Import complete.")
443
wt.set_last_revision(wt.branch.last_revision())
444
merge_inner(wt.branch, wt.basis_tree(), old_basis,
445
ignore_zero=True, this_tree=wt)
460
progress_bar.finished()
449
printer('Cleaning up')
450
shutil.rmtree(tempdir)
451
printer("Import complete.")
462
453
class UserError(BzrCommandError):
463
454
def __init__(self, message):
464
455
"""Exception to throw when a user makes an impossible request
667
627
if missing_ancestor:
668
628
# if we want it to be in revision-history, do that here.
669
target_tree.set_parent_ids(
670
[revision_id(missing_ancestor, encoding)],
671
allow_leftmost_as_ghost=True)
629
target_tree.add_pending_merge(revision_id(missing_ancestor))
672
630
missing_ancestor = None
673
631
for merged_rev in direct_merges:
674
target_tree.add_pending_merge(revision_id(merged_rev,
676
target_tree.set_root_id(BAZ_IMPORT_ROOT)
632
target_tree.add_pending_merge(revision_id(merged_rev))
678
633
target_tree.set_inventory(baz_inv)
679
commitobj = Commit(reporter=ImportCommitReporter())
634
commitobj = Commit(reporter=ImportCommitReporter(pb))
680
635
commitobj.commit(working_tree=target_tree,
681
message=log_message.decode(log_encoding, 'replace'),
682
verbose=False, committer=log_creator, timestamp=timestamp,
683
timezone=0, rev_id=rev_id, revprops={})
636
message=log_message.decode('ascii', 'replace'),
637
verbose=False, committer=log_creator,
638
timestamp=timestamp, timezone=0, rev_id=rev_id,
639
revprops={'branch-nick': str(revision.version)})
685
641
target_tree.unlock()
770
def baz_import_branch(to_location, from_branch, fast, max_count, verbose,
771
encoding, dry_run, reuse_history_list):
772
to_location = os.path.realpath(str(to_location))
773
if from_branch is not None:
775
from_branch = pybaz.Version(from_branch)
776
except pybaz.errors.NamespaceError:
777
print "%s is not a valid Arch branch." % from_branch
779
if reuse_history_list is None:
780
reuse_history_list = []
781
import_version(to_location, from_branch, encoding, max_count=max_count,
782
reuse_history_from=reuse_history_list)
725
_global_option('max-count', type = int)
726
class cmd_baz_import_branch(Command):
727
"""Import an Arch or Baz branch into a bzr branch"""
728
takes_args = ['to_location', 'from_branch?', 'reuse_history*']
729
takes_options = ['verbose', 'max-count']
731
def printer(self, name):
734
def run(self, to_location, from_branch=None, fast=False, max_count=None,
735
verbose=False, dry_run=False, reuse_history_list=[]):
736
to_location = os.path.realpath(str(to_location))
737
if from_branch is not None:
739
from_branch = pybaz.Version(from_branch)
740
except pybaz.errors.NamespaceError:
741
print "%s is not a valid Arch branch." % from_branch
743
if reuse_history_list is None:
744
reuse_history_list = []
745
import_version(to_location, from_branch, self.printer,
747
reuse_history_from=reuse_history_list)
785
750
class NotInABranch(Exception):
792
def baz_import(to_root_dir, from_archive, encoding, verbose=False,
793
reuse_history_list=[], prefixes=None):
794
if reuse_history_list is None:
795
reuse_history_list = []
796
to_root = str(os.path.realpath(to_root_dir))
797
if not os.path.exists(to_root):
799
if prefixes is not None:
800
prefixes = prefixes.split(':')
801
import_archive(to_root, from_archive, verbose, encoding,
802
reuse_history_list, prefixes=prefixes)
805
def import_archive(to_root, from_archive, verbose,
806
encoding, reuse_history_from=[], standalone=False,
756
class cmd_baz_import(Command):
757
"""Import an Arch or Baz archive into bzr branches.
759
This command should be used on local archives (or mirrors) only. It is
760
quite slow on remote archives.
762
reuse_history allows you to specify any previous imports you
763
have done of different archives, which this archive has branches
764
tagged from. This will dramatically reduce the time to convert
765
the archive as it will not have to convert the history already
766
converted in that other branch.
768
If you specify prefixes, only branches whose names start with that prefix
769
will be imported. Skipped branches will be listed, so you can import any
770
branches you missed by accident. Here's an example of doing a partial
771
import from thelove@canonical.com:
772
bzr baz-import thelove thelove@canonical.com --prefixes dists:talloc-except
774
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
775
takes_options = ['verbose', Option('prefixes', type=str,
776
help="Prefixes of branches to import, colon-separated")]
778
def printer(self, name):
781
def run(self, to_root_dir, from_archive, verbose=False,
782
reuse_history_list=[], prefixes=None):
783
if reuse_history_list is None:
784
reuse_history_list = []
785
to_root = str(os.path.realpath(to_root_dir))
786
if not os.path.exists(to_root):
788
if prefixes is not None:
789
prefixes = prefixes.split(':')
790
import_archive(to_root, from_archive, verbose, self.printer,
791
reuse_history_list, prefixes=prefixes)
794
def import_archive(to_root, from_archive, verbose, printer,
795
reuse_history_from=[], standalone=False,
808
797
def selected(version):
809
798
if prefixes is None:
823
812
create_shared_repository(to_root)
824
813
except NoRepositoryPresent:
825
814
raise BzrCommandError("Can't create repository at existing branch.")
826
versions = list(pybaz.Archive(str(from_archive)).iter_versions())
827
progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
829
for num, version in enumerate(versions):
830
progress_bar.update("Branch", num, len(versions))
831
if not selected(version):
832
print "Skipping %s" % version
834
target = os.path.join(to_root, map_namespace(version))
835
if not os.path.exists(os.path.dirname(target)):
836
os.makedirs(os.path.dirname(target))
838
import_version(target, version, encoding,
839
reuse_history_from=reuse_history_from,
840
standalone=standalone)
841
except pybaz.errors.ExecProblem,e:
842
if str(e).find('The requested revision cannot be built.') != -1:
844
"Skipping version %s as it cannot be built due"
815
for version in pybaz.Archive(str(from_archive)).iter_versions():
816
if not selected(version):
817
print "Skipping %s" % version
819
target = os.path.join(to_root, map_namespace(version))
820
printer("importing %s into %s" % (version, target))
821
if not os.path.exists(os.path.dirname(target)):
822
os.makedirs(os.path.dirname(target))
824
import_version(target, version, printer,
825
reuse_history_from=reuse_history_from,
826
standalone=standalone)
827
except pybaz.errors.ExecProblem,e:
828
if str(e).find('The requested revision cannot be built.') != -1:
829
printer("Skipping version %s as it cannot be built due"
845
830
" to a missing parent archive." % version)
849
if str(e).find('already exists, and the last revision ') != -1:
851
"Skipping version %s as it has had commits made"
834
if str(e).find('already exists, and the last revision ') != -1:
835
printer("Skipping version %s as it has had commits made"
852
836
" since it was converted to bzr." % version)
856
progress_bar.finished()
859
841
def map_namespace(a_version):