~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to baz_import.py

  • Committer: Aaron Bentley
  • Date: 2005-10-28 03:01:02 UTC
  • mfrom: (147.4.13)
  • mto: (147.4.24 trunk)
  • mto: This revision was merged to the branch mainline in revision 324.
  • Revision ID: aaron.bentley@utoronto.ca-20051028030102-eead1e484007de74
Merged lifeless

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Aaron Bentley
 
1
# Copyright (C) 2005 by Aaron Bentley
2
2
 
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
import errno
18
18
 
19
 
from bzrlib.bzrdir import BzrDir
20
 
import bzrlib.bzrdir as bzrdir
21
 
from bzrlib.errors import (BzrError,
22
 
                           NotBranchError,
23
 
                           NoWorkingTree,
24
 
                           BzrCommandError, 
25
 
                           NoSuchRevision,
26
 
                           NoRepositoryPresent,
27
 
                          )
 
19
from bzrlib.errors import BzrError
 
20
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision
28
21
from bzrlib.branch import Branch
 
22
from bzrlib.clone import copy_branch
29
23
from bzrlib.commit import Commit, NullCommitReporter
30
24
from bzrlib.commands import Command
31
 
from bzrlib.option import _global_option, Option
32
 
from bzrlib.merge import merge_inner
33
 
from bzrlib.revision import NULL_REVISION
34
 
from bzrlib.tree import EmptyTree
35
 
import bzrlib.ui
36
 
import bzrlib.ui.text
37
 
from bzrlib.workingtree import WorkingTree
 
25
from bzrlib.option import _global_option
38
26
from errors import NoPyBaz
39
27
try:
40
28
    import pybaz
58
46
from progress import *
59
47
 
60
48
class ImportCommitReporter(NullCommitReporter):
 
49
    def __init__(self, pb):
 
50
        self.pb = pb
61
51
 
62
52
    def escaped(self, escape_count, message):
 
53
        self.pb.clear()
63
54
        bzrlib.trace.warning("replaced %d control characters in message" %
64
55
                             escape_count)
65
56
 
79
70
 
80
71
saved_dir = None
81
72
 
82
 
def make_archive(name, location):
83
 
    pb_location = pybaz.ArchiveLocation(location)
84
 
    pb_location.create_master(pybaz.Archive(name), 
85
 
                              pybaz.ArchiveLocationParams())
86
 
 
87
73
def test_environ():
88
74
    """
89
75
    >>> q = test_environ()
101
87
    os.environ["HOME"] = os.path.join(tdir, "home")
102
88
    os.mkdir(os.environ["HOME"])
103
89
    arch_dir = os.path.join(tdir, "archive_dir")
104
 
    make_archive("test@example.com", arch_dir)
 
90
    pybaz.make_archive("test@example.com", arch_dir)
105
91
    work_dir = os.path.join(tdir, "work_dir")
106
92
    os.mkdir(work_dir)
107
93
    os.chdir(work_dir)
269
255
            else:
270
256
                raise
271
257
        try:
272
 
            br_from.bzrdir.clone(to_location, revision_id)
 
258
            copy_branch(br_from, to_location, revision_id, None)
273
259
        except NoSuchRevision:
274
260
            rmtree(to_location)
275
 
            msg = "The branch %s has no revision %s." % (from_location, 
276
 
                                                         revision_id)
 
261
            msg = "The branch %s has no revision %s." % (from_location, revision_id)
277
262
            raise UserError(msg)
278
263
    finally:
279
264
        br_from.unlock()
287
272
        # the current version is
288
273
        branch = Branch.open(output_dir)
289
274
        last_patch = get_last_revision(branch)
290
 
        if last_patch is None:
291
 
            if branch.last_revision() != None:
292
 
                raise NotPreviousImport(branch.base)
293
 
        elif version is None:
 
275
        if version is None:
294
276
            version = last_patch.version
295
277
    elif version is None:
296
278
        raise UserError("No version specified, and directory does not exist.")
344
326
###    possible later.
345
327
###    """
346
328
###
347
 
###    def __init__(self, output_dir, version, fast=False,
 
329
###    def __init__(self, output_dir, version, printer, fancy=True, fast=False,
348
330
###                 verbose=False, dry_run=False, max_count=None, 
349
331
###                   reuse_history_from=[]):
350
332
###        self.output_dir = output_dir
352
334
###        self.
353
335
 
354
336
 
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=[]):
358
340
    """
359
341
    >>> q = test_environ()
360
 
    
361
 
    Progress bars output to stderr, but doctest does not capture that.
362
 
 
363
 
    >>> old_stderr = sys.stderr
364
 
    >>> sys.stderr = sys.stdout
365
 
 
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)
372
 
 
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 ...
382
 
    ...
383
 
    revisions: ..........................................
 
353
    >>> import_version(result_path, version, printer, fancy=False, dry_run=True)
 
354
    not fancy
 
355
    ....
384
356
    Dry run, not modifying output_dir
385
357
    Cleaning up
386
 
    >>> import_version(result_path, version) #doctest: +ELLIPSIS
387
 
    importing test@example.com/test--test--0 into ...
388
 
    ...
389
 
    revisions: .....................................................................
 
358
    >>> import_version(result_path, version, printer, fancy=False)
 
359
    not fancy
 
360
    ....
390
361
    Cleaning up
391
362
    Import complete.
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)
 
367
    not fancy
 
368
    ..
398
369
    Cleaning up
399
370
    Import complete.
400
 
    >>> bzrlib.ui.ui_factory = old_ui
401
 
    >>> sys.stderr = old_stderr
402
371
    >>> teardown_environ(q)
403
372
    """
404
 
    progress_bar = bzrlib.ui.ui_factory.nested_progress_bar()
405
373
    try:
406
 
        try:
407
 
            ancestors, old_revno = get_remaining_revisions(output_dir, version,
408
 
                                                           reuse_history_from)
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)
413
 
            return
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)
417
 
            return
 
374
        ancestors, old_revno = get_remaining_revisions(output_dir, version,
 
375
                                                       reuse_history_from)
 
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
 
380
        return
 
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
 
384
        return
418
385
 
419
 
        progress_bar.note("importing %s into %s" % (version, output_dir))
420
 
    
421
 
        tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
422
 
                                   dir=os.path.dirname(output_dir))
423
 
        try:
424
 
            wt = WorkingTree.open(output_dir)
425
 
        except (NotBranchError, NoWorkingTree):
426
 
            wt = None
427
 
        if wt is None:
428
 
            old_basis = EmptyTree()
429
 
        else:
430
 
            old_basis = wt.basis_tree()
 
386
    progress_bar = ProgressBar()
 
387
    tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
 
388
                               dir=os.path.dirname(output_dir))
 
389
    try:
 
390
        if not fancy:
 
391
            print "not fancy"
431
392
        try:
432
393
            for result in iter_import_version(output_dir, ancestors, tempdir,
433
 
                    pb=progress_bar,
434
 
                    fast=fast, verbose=verbose, dry_run=dry_run,
435
 
                    max_count=max_count, standalone=standalone):
436
 
                show_progress(progress_bar, result)
437
 
            if dry_run:
438
 
                progress_bar.note('Dry run, not modifying output_dir')
439
 
                return
440
 
    
441
 
            # Update the working tree of the branch
442
 
            try:
443
 
                wt = WorkingTree.open(output_dir)
444
 
            except NoWorkingTree:
445
 
                wt = None
446
 
            if wt is not None:
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)
450
 
                wt.revert([])
451
 
    
 
394
                    progress_bar, fast=fast, verbose=verbose, dry_run=dry_run,
 
395
                    max_count=max_count):
 
396
                if fancy:
 
397
                    show_progress(progress_bar, result)
 
398
                else:
 
399
                    sys.stdout.write('.')
452
400
        finally:
453
 
            
454
 
            progress_bar.note('Cleaning up')
455
 
            shutil.rmtree(tempdir)
456
 
        progress_bar.note("Import complete.")
 
401
            if fancy:
 
402
                progress_bar.clear()
 
403
            else:
 
404
                sys.stdout.write('\n')
 
405
 
 
406
        if dry_run:
 
407
            print 'Dry run, not modifying output_dir'
 
408
            return
 
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')
 
415
                
 
416
                bzr_dir = os.path.join(output_dir, '.bzr')
 
417
                new_bzr_dir = os.path.join(tempdir, "rd", '.bzr')
 
418
    
 
419
                os.rename(bzr_dir, tmp_bzr_dir) # Move the original bzr out of the way
 
420
                os.rename(new_bzr_dir, bzr_dir)
 
421
                try:
 
422
                    bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno), 
 
423
                                       check_clean=False, this_dir=output_dir, 
 
424
                                       ignore_zero=True)
 
425
                except:
 
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)
 
429
                    raise
 
430
            else:
 
431
                # no imports - perhaps just append_revisions
 
432
                # should not fail:
 
433
                bzrlib.merge.merge((output_dir, -1), (output_dir, None), # old_revno), 
 
434
                                   check_clean=False, this_dir=output_dir, 
 
435
                                   ignore_zero=True)
 
436
        else:
 
437
            revdir = os.path.join(tempdir, "rd")
 
438
            os.rename(revdir, output_dir)
 
439
 
457
440
    finally:
458
 
        progress_bar.finished()
 
441
        printer('Cleaning up')
 
442
        shutil.rmtree(tempdir)
 
443
    printer("Import complete.")
459
444
            
460
445
class UserError(BzrCommandError):
461
446
    def __init__(self, message):
465
450
        """
466
451
        BzrCommandError.__init__(self, message)
467
452
 
468
 
class NotPreviousImport(UserError):
469
 
    def __init__(self, path):
470
 
        UserError.__init__(self, "%s is not the location of a previous import."
471
 
                           % path)
472
 
 
473
 
 
474
453
def revision_id(arch_revision):
475
454
    """
476
455
    Generate a Bzr revision id from an Arch revision id.  'x' in the id
510
489
            return pybaz.Revision(revision_id[7:].replace('%', '/'))
511
490
        except pybaz.errors.NamespaceError, e:
512
491
            raise NotArchRevision(revision_id)
513
 
 
514
 
 
515
 
def create_shared_repository(output_dir):
516
 
    bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
517
 
    bd.create_repository(shared=True)
518
 
 
519
 
def create_branch(output_dir):
520
 
    os.mkdir(output_dir)
521
 
    bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
522
 
    return bd.create_branch()
523
 
 
524
 
 
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)
529
 
 
530
 
 
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)
537
 
    return wt
538
 
 
539
 
 
 
492
            
540
493
def iter_import_version(output_dir, ancestors, tempdir, pb, fast=False,
541
 
                        verbose=False, dry_run=False, max_count=None,
542
 
                        standalone=False):
 
494
                        verbose=False, dry_run=False, max_count=None):
543
495
    revdir = None
544
496
 
545
497
    # Uncomment this for testing, it basically just has baz2bzr only update
558
510
 
559
511
    previous_version=None
560
512
    missing_ancestor = None
561
 
    if dry_run:
562
 
        dry_output_dir = os.path.join(tempdir, 'od')
563
 
        if os.path.exists(output_dir):
564
 
            shutil.copytree(output_dir, dry_output_dir)
565
 
        output_dir = dry_output_dir
566
 
 
567
 
    if os.path.exists(output_dir):
568
 
        target_branch = Branch.open(output_dir)
569
 
    else:
570
 
        if standalone:
571
 
            wt = BzrDir.create_standalone_workingtree(output_dir)
572
 
            target_branch = wt.branch
573
 
        else:
574
 
            target_branch = create_branch(output_dir)
575
513
 
576
514
    for i in range(len(ancestors)):
577
515
        revision = ancestors[i]
580
518
        if verbose:
581
519
            version = str(revision.version)
582
520
            if version != previous_version:
583
 
                pb.note('On version: %s' % version)
 
521
                clear_progress_bar()
 
522
                print '\rOn version: %s' % version
584
523
            yield Progress(str(revision.patchlevel), i, len(ancestors))
585
524
            previous_version = version
586
525
        else:
587
526
            yield Progress("revisions", i, len(ancestors))
588
 
 
589
 
        if target_branch.repository.has_revision(rev_id):
590
 
            target_branch.append_revision(rev_id)
591
 
            continue
 
527
        if revdir is None and os.path.exists(output_dir):
 
528
            # check for imported revisions and if present just append immediately
 
529
            branch = Branch.open(output_dir)
 
530
            if branch.has_revision(rev_id):
 
531
                branch.append_revision(rev_id)
 
532
                continue
592
533
        if revdir is None:
593
534
            revdir = os.path.join(tempdir, "rd")
594
535
            try:
598
539
                    raise
599
540
                missing_ancestor = revision
600
541
                revdir = None
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)
603
544
                continue
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)
 
558
            else:
 
559
                branch = Branch.initialize(revdir)
606
560
        else:
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))
628
581
        else:
629
582
            log_message = log_summary
630
 
        target_tree.lock_write()
631
583
        branch.lock_write()
632
584
        try:
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,
645
 
                             revprops={})
 
595
                             timestamp=timestamp, timezone=0, rev_id=rev_id)
646
596
        finally:
647
 
            target_tree.unlock()
648
597
            branch.unlock()
649
598
    yield Progress("revisions", len(ancestors), len(ancestors))
 
599
    unlink_unversioned(branch, revdir)
650
600
 
651
601
def get_direct_merges(revdir, revision, log):
652
602
    continuation = log.continuation_of
663
613
    os.rename(temp_path, log_path)
664
614
    return direct
665
615
 
666
 
def unlink_unversioned(wt):
667
 
    for unversioned in wt.extras():
668
 
        path = wt.abspath(unversioned)
 
616
def unlink_unversioned(branch, revdir):
 
617
    for unversioned in branch.working_tree().extras():
 
618
        path = os.path.join(revdir, unversioned)
669
619
        if os.path.isdir(path):
670
620
            shutil.rmtree(path)
671
621
        else:
682
632
    try:
683
633
        return tree, bzr_inventory_data(tree), log 
684
634
    except BadFileKind, e:
685
 
        raise UserError("Cannot convert %s because %s is a %s" % 
686
 
                        (revision,e.path, e.kind))
 
635
        raise UserError("Cannot convert %s because %s is a %s" % (revision,e.path, e.kind) )
687
636
 
688
637
 
689
638
def apply_revision(tree, revision):
692
641
    try:
693
642
        return bzr_inventory_data(tree), log
694
643
    except BadFileKind, e:
695
 
        raise UserError("Cannot convert %s because %s is a %s" % 
696
 
                        (revision,e.path, e.kind))
 
644
        raise UserError("Cannot convert %s because %s is a %s" % (revision,e.path, e.kind) )
697
645
 
698
646
 
699
647
class BadFileKind(Exception):
730
678
 
731
679
_global_option('max-count', type = int)
732
680
class cmd_baz_import_branch(Command):
733
 
    """Import an Arch or Baz branch into a bzr branch."""
 
681
    """Import an Arch or Baz branch into a bzr branch"""
734
682
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
735
683
    takes_options = ['verbose', 'max-count']
736
684
 
 
685
    def printer(self, name):
 
686
        print name
 
687
 
737
688
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
738
689
            verbose=False, dry_run=False, reuse_history_list=[]):
739
690
        to_location = os.path.realpath(str(to_location))
745
696
                return 1
746
697
        if reuse_history_list is None:
747
698
            reuse_history_list = []
748
 
        import_version(to_location, from_branch, 
749
 
                       max_count=max_count, 
750
 
                       reuse_history_from=reuse_history_list)
751
 
 
752
 
 
753
 
class NotInABranch(Exception):
754
 
    def __init__(self, path):
755
 
        Exception.__init__(self, "%s is not in a branch." % path)
756
 
        self.path = path
 
699
        import_version(to_location, from_branch, self.printer, 
 
700
                       max_count=max_count, reuse_history_from=reuse_history_list)
757
701
 
758
702
 
759
703
class cmd_baz_import(Command):
760
 
    """Import an Arch or Baz archive into a bzr repository.
761
 
 
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.
764
705
    
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.
770
 
 
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
776
711
    """
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']
 
714
 
 
715
    def printer(self, name):
 
716
        print name
780
717
 
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)
792
 
 
793
 
 
794
 
def import_archive(to_root, from_archive, verbose,
795
 
                   reuse_history_from=[], standalone=False,
796
 
                   prefixes=None):
797
 
    def selected(version):
798
 
        if prefixes is None:
799
 
            return True
800
 
        else:
801
 
            for prefix in prefixes:
802
 
                if version.nonarch.startswith(prefix):
803
 
                    return True
804
 
            return False
 
725
        import_archive(to_root, from_archive, verbose, self.printer, 
 
726
                       reuse_history_list)
 
727
 
 
728
 
 
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))
808
738
        try:
809
 
            bd = BzrDir.open(to_root)
810
 
            bd.find_repository()
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()
817
 
    try:
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
822
 
                continue
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))
826
 
            try:
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:
832
 
                    progress_bar.note(
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)
835
 
                else:
836
 
                    raise
837
 
            except UserError, e:
838
 
                if str(e).find('already exists, and the last revision ') != -1:
839
 
                    progress_bar.note(
840
 
                        "Skipping version %s as it has had commits made"
 
745
            else:
 
746
                raise
 
747
        except UserError, e:
 
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)
842
 
                else:
843
 
                    raise
844
 
    finally:
845
 
        progress_bar.finished()
 
751
            else:
 
752
                raise
846
753
 
847
754
 
848
755
def map_namespace(a_version):
857
764
        return "%s/%s" % (category, branch)
858
765
    return "%s/%s/%s" % (category, version, branch)
859
766
 
860
 
 
861
767
def map_file_id(file_id):
862
768
    """Convert a baz file id to a bzr one."""
863
769
    return file_id.replace('%', '%25').replace('/', '%2f')