355
def import_version(output_dir, version, fast=False,
337
def import_version(output_dir, version, printer, fancy=True, fast=False,
356
338
verbose=False, dry_run=False, max_count=None,
357
reuse_history_from=[], standalone=True):
339
reuse_history_from=[]):
359
341
>>> q = test_environ()
361
Progress bars output to stderr, but doctest does not capture that.
363
>>> old_stderr = sys.stderr
364
>>> sys.stderr = sys.stdout
366
342
>>> result_path = os.path.join(q, "result")
367
343
>>> commit_test_revisions()
368
344
>>> version = pybaz.Version("test@example.com/test--test--0.1")
369
>>> old_ui = bzrlib.ui.ui_factory
370
>>> bzrlib.ui.ui_factory = bzrlib.ui.text.TextUIFactory(
371
... bar_type=bzrlib.progress.DotsProgressBar)
373
>>> import_version('/', version, dry_run=True)
345
>>> def printer(message): print message
346
>>> import_version('/', version, printer, fancy=False, dry_run=True)
374
347
Traceback (most recent call last):
375
NotPreviousImport: / is not the location of a previous import.
376
>>> import_version(result_path, version, dry_run=True)
348
UserError: / exists, but is not a bzr branch.
349
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
377
350
Traceback (most recent call last):
378
351
UserError: The version test@example.com/test--test--0.1 does not exist.
379
352
>>> version = pybaz.Version("test@example.com/test--test--0")
380
>>> import_version(result_path, version, dry_run=True) #doctest: +ELLIPSIS
381
importing test@example.com/test--test--0 into ...
383
revisions: ..........................................
353
>>> import_version(result_path, version, printer, fancy=False, dry_run=True)
384
356
Dry run, not modifying output_dir
386
>>> import_version(result_path, version) #doctest: +ELLIPSIS
387
importing test@example.com/test--test--0 into ...
389
revisions: .....................................................................
358
>>> import_version(result_path, version, printer, fancy=False)
392
>>> import_version(result_path, version) #doctest: +ELLIPSIS
363
>>> import_version(result_path, version, printer, fancy=False)
393
364
Tree is up-to-date with test@example.com/test--test--0--patch-2
394
365
>>> commit_more_test_revisions()
395
>>> import_version(result_path, version) #doctest: +ELLIPSIS
396
importing test@example.com/test--test--0 into ...
397
revisions: ....................................................
366
>>> import_version(result_path, version, printer, fancy=False)
400
>>> bzrlib.ui.ui_factory = old_ui
401
>>> sys.stderr = old_stderr
402
371
>>> teardown_environ(q)
404
progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
407
ancestors, old_revno = get_remaining_revisions(output_dir, version,
409
except NotBranchError, e:
410
raise NotPreviousImport(e.path)
411
if old_revno is None and len(ancestors) == 0:
412
progress_bar.note('Version %s has no revisions.' % version)
414
if len(ancestors) == 0:
415
last_revision = get_last_revision(Branch.open(output_dir))
416
progress_bar.note('Tree is up-to-date with %s' % last_revision)
374
ancestors, old_revno = get_remaining_revisions(output_dir, version,
376
except NotBranchError, e:
377
raise UserError("%s exists, but is not a bzr branch." % output_dir)
378
if old_revno is None and len(ancestors) == 0:
379
print 'Version %s has no revisions.' % version
381
if len(ancestors) == 0:
382
last_revision = get_last_revision(Branch.open(output_dir))
383
print 'Tree is up-to-date with %s' % last_revision
419
progress_bar.note("importing %s into %s" % (version, output_dir))
421
tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
422
dir=os.path.dirname(output_dir))
424
wt = WorkingTree.open(output_dir)
425
except (NotBranchError, NoWorkingTree):
428
old_basis = EmptyTree()
430
old_basis = wt.basis_tree()
386
progress_bar = ProgressBar()
387
tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
388
dir=os.path.dirname(output_dir))
432
393
for result in iter_import_version(output_dir, ancestors, tempdir,
434
fast=fast, verbose=verbose, dry_run=dry_run,
435
max_count=max_count, standalone=standalone):
436
show_progress(progress_bar, result)
438
progress_bar.note('Dry run, not modifying output_dir')
441
# Update the working tree of the branch
443
wt = WorkingTree.open(output_dir)
444
except NoWorkingTree:
447
wt.set_last_revision(wt.branch.last_revision())
448
merge_inner(wt.branch, wt.basis_tree(), old_basis,
449
ignore_zero=True, this_tree=wt)
394
progress_bar, fast=fast, verbose=verbose, dry_run=dry_run,
395
max_count=max_count):
397
show_progress(progress_bar, result)
399
sys.stdout.write('.')
454
progress_bar.note('Cleaning up')
455
shutil.rmtree(tempdir)
456
progress_bar.note("Import complete.")
404
sys.stdout.write('\n')
407
print 'Dry run, not modifying output_dir'
409
if os.path.exists(output_dir):
410
# Move the bzr control directory back, and update the working tree
411
revdir = os.path.join(tempdir, "rd")
412
if os.path.exists(revdir):
413
# actual imports were done
414
tmp_bzr_dir = os.path.join(tempdir, '.bzr')
416
bzr_dir = os.path.join(output_dir, '.bzr')
417
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr')
419
os.rename(bzr_dir, tmp_bzr_dir) # Move the original bzr out of the way
420
os.rename(new_bzr_dir, bzr_dir)
422
bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno),
423
check_clean=False, this_dir=output_dir,
426
# If something failed, move back the original bzr directory
427
os.rename(bzr_dir, new_bzr_dir)
428
os.rename(tmp_bzr_dir, bzr_dir)
431
# no imports - perhaps just append_revisions
433
bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno),
434
check_clean=False, this_dir=output_dir,
437
revdir = os.path.join(tempdir, "rd")
438
os.rename(revdir, output_dir)
458
progress_bar.finished()
441
printer('Cleaning up')
442
shutil.rmtree(tempdir)
443
printer("Import complete.")
460
445
class UserError(BzrCommandError):
461
446
def __init__(self, message):
510
489
return pybaz.Revision(revision_id[7:].replace('%', '/'))
511
490
except pybaz.errors.NamespaceError, e:
512
491
raise NotArchRevision(revision_id)
515
def create_shared_repository(output_dir):
516
bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
517
bd.create_repository(shared=True)
519
def create_branch(output_dir):
521
bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
522
return bd.create_branch()
525
def create_checkout(source, to_location, revision_id=None):
526
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
527
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
528
return checkout.create_workingtree(revision_id)
531
def create_checkout_metadata(source, to_location, revision_id=None):
532
if revision_id is None:
533
revision_id = source.last_revision()
534
wt = create_checkout(source, to_location, NULL_REVISION)
535
wt.set_last_revision(revision_id)
536
wt._write_inventory(wt.basis_tree().inventory)
540
493
def iter_import_version(output_dir, ancestors, tempdir, pb, fast=False,
541
verbose=False, dry_run=False, max_count=None,
494
verbose=False, dry_run=False, max_count=None):
545
497
# Uncomment this for testing, it basically just has baz2bzr only update
599
540
missing_ancestor = revision
601
pb.note("unable to access ancestor %s, making into a merge."
542
print ("unable to access ancestor %s, making into a merge."
602
543
% missing_ancestor)
604
target_tree = create_checkout_metadata(target_branch, revdir)
605
branch = target_tree.branch
545
if os.path.exists(output_dir):
546
bzr_dir = os.path.join(output_dir, '.bzr')
547
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr')
548
# This would be much faster with a simple os.rename(), but if
549
# we fail, we have corrupted the original .bzr directory. Is
550
# that a big problem, as we can just back out the last
551
# revisions in .bzr/revision_history I don't really know
552
# RBC20051024 - yes, it would be a problem as we could not then
553
# apply the corrupted revision.
554
shutil.copytree(bzr_dir, new_bzr_dir)
555
# Now revdir should have a tree with the latest .bzr, and the
556
# next revision of the baz tree
557
branch = Branch.open(revdir)
559
branch = Branch.initialize(revdir)
607
561
old = os.path.join(revdir, ".bzr")
608
562
new = os.path.join(tempdir, ".bzr")
609
563
os.rename(old, new)
610
564
baz_inv, log = apply_revision(tree, revision)
611
565
os.rename(new, old)
612
target_tree = WorkingTree.open(revdir)
613
branch = target_tree.branch
566
branch = Branch.open(revdir)
614
567
# cached so we can delete the log
615
568
log_date = log.date
616
569
log_summary = log.summary
627
580
log_message = "\n".join((log_summary, log_description))
629
582
log_message = log_summary
630
target_tree.lock_write()
631
583
branch.lock_write()
633
585
if missing_ancestor:
634
586
# if we want it to be in revision-history, do that here.
635
target_tree.add_pending_merge(revision_id(missing_ancestor))
587
branch.add_pending_merge(revision_id(missing_ancestor))
636
588
missing_ancestor = None
637
589
for merged_rev in direct_merges:
638
target_tree.add_pending_merge(revision_id(merged_rev))
639
target_tree.set_inventory(baz_inv)
640
commitobj = Commit(reporter=ImportCommitReporter())
641
commitobj.commit(working_tree=target_tree,
642
message=log_message.decode('ascii', 'replace'),
590
branch.add_pending_merge(revision_id(merged_rev))
591
branch.set_inventory(baz_inv)
592
commitobj = Commit(reporter=ImportCommitReporter(pb))
593
commitobj.commit(branch, log_message.decode('ascii', 'replace'),
643
594
verbose=False, committer=log_creator,
644
timestamp=timestamp, timezone=0, rev_id=rev_id,
595
timestamp=timestamp, timezone=0, rev_id=rev_id)
649
598
yield Progress("revisions", len(ancestors), len(ancestors))
599
unlink_unversioned(branch, revdir)
651
601
def get_direct_merges(revdir, revision, log):
652
602
continuation = log.continuation_of
746
697
if reuse_history_list is None:
747
698
reuse_history_list = []
748
import_version(to_location, from_branch,
750
reuse_history_from=reuse_history_list)
753
class NotInABranch(Exception):
754
def __init__(self, path):
755
Exception.__init__(self, "%s is not in a branch." % path)
699
import_version(to_location, from_branch, self.printer,
700
max_count=max_count, reuse_history_from=reuse_history_list)
759
703
class cmd_baz_import(Command):
760
"""Import an Arch or Baz archive into a bzr repository.
762
This command should be used on local archives (or mirrors) only. It is
763
quite slow on remote archives.
704
"""Import an Arch or Baz archive into bzr branches.
765
706
reuse_history allows you to specify any previous imports you
766
707
have done of different archives, which this archive has branches
767
708
tagged from. This will dramatically reduce the time to convert
768
709
the archive as it will not have to convert the history already
769
710
converted in that other branch.
771
If you specify prefixes, only branches whose names start with that prefix
772
will be imported. Skipped branches will be listed, so you can import any
773
branches you missed by accident. Here's an example of doing a partial
774
import from thelove@canonical.com:
775
bzr baz-import thelove thelove@canonical.com --prefixes dists:talloc-except
777
712
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
778
takes_options = ['verbose', Option('prefixes', type=str,
779
help="Prefixes of branches to import, colon-separated")]
713
takes_options = ['verbose']
715
def printer(self, name):
781
718
def run(self, to_root_dir, from_archive, verbose=False,
782
reuse_history_list=[], prefixes=None):
719
reuse_history_list=[]):
783
720
if reuse_history_list is None:
784
721
reuse_history_list = []
785
722
to_root = str(os.path.realpath(to_root_dir))
786
723
if not os.path.exists(to_root):
787
724
os.mkdir(to_root)
788
if prefixes is not None:
789
prefixes = prefixes.split(':')
790
import_archive(to_root, from_archive, verbose,
791
reuse_history_list, prefixes=prefixes)
794
def import_archive(to_root, from_archive, verbose,
795
reuse_history_from=[], standalone=False,
797
def selected(version):
801
for prefix in prefixes:
802
if version.nonarch.startswith(prefix):
725
import_archive(to_root, from_archive, verbose, self.printer,
729
def import_archive(to_root, from_archive, verbose, printer,
730
reuse_history_from=[]):
805
731
real_to = os.path.realpath(to_root)
806
732
history_locations = [real_to] + reuse_history_from
807
if standalone is False:
733
for version in pybaz.Archive(str(from_archive)).iter_versions():
734
target = os.path.join(to_root, map_namespace(version))
735
printer("importing %s into %s" % (version, target))
736
if not os.path.exists(os.path.dirname(target)):
737
os.makedirs(os.path.dirname(target))
809
bd = BzrDir.open(to_root)
811
except NotBranchError:
812
create_shared_repository(to_root)
813
except NoRepositoryPresent:
814
raise BzrCommandError("Can't create repository at existing branch.")
815
versions = list(pybaz.Archive(str(from_archive)).iter_versions())
816
progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
818
for num, version in enumerate(versions):
819
progress_bar.update("Branch", num, len(versions))
820
if not selected(version):
821
print "Skipping %s" % version
823
target = os.path.join(to_root, map_namespace(version))
824
if not os.path.exists(os.path.dirname(target)):
825
os.makedirs(os.path.dirname(target))
827
import_version(target, version,
828
reuse_history_from=reuse_history_from,
829
standalone=standalone)
830
except pybaz.errors.ExecProblem,e:
831
if str(e).find('The requested revision cannot be built.') != -1:
833
"Skipping version %s as it cannot be built due"
739
import_version(target, version, printer,
740
reuse_history_from=reuse_history_from)
741
except pybaz.errors.ExecProblem,e:
742
if str(e).find('The requested revision cannot be built.') != -1:
743
printer("Skipping version %s as it cannot be built due"
834
744
" to a missing parent archive." % version)
838
if str(e).find('already exists, and the last revision ') != -1:
840
"Skipping version %s as it has had commits made"
748
if str(e).find('already exists, and the last revision ') != -1:
749
printer("Skipping version %s as it has had commits made"
841
750
" since it was converted to bzr." % version)
845
progress_bar.finished()
848
755
def map_namespace(a_version):