19
from bzrlib.errors import BzrError
20
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision
19
from bzrlib.bzrdir import BzrDir
20
import bzrlib.bzrdir as bzrdir
21
from bzrlib.errors import (BzrError,
21
28
from bzrlib.branch import Branch
22
29
from bzrlib.commit import Commit, NullCommitReporter
23
30
from bzrlib.commands import Command
24
from bzrlib.option import _global_option
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
25
36
from bzrlib.workingtree import WorkingTree
26
37
from errors import NoPyBaz
385
402
print 'Tree is up-to-date with %s' % last_revision
388
progress_bar = ProgressBar()
405
progress_bar = bzrlib.ui.ui_factory.progress_bar()
389
406
tempdir = tempfile.mkdtemp(prefix="baz2bzr-",
390
407
dir=os.path.dirname(output_dir))
409
wt = WorkingTree.open(output_dir)
410
except NotBranchError:
413
old_basis = EmptyTree()
415
old_basis = wt.basis_tree()
393
418
print "not fancy"
395
420
for result in iter_import_version(output_dir, ancestors, tempdir,
396
421
progress_bar, fast=fast, verbose=verbose, dry_run=dry_run,
397
max_count=max_count):
422
max_count=max_count, standalone=standalone):
399
424
show_progress(progress_bar, result)
409
434
print 'Dry run, not modifying output_dir'
411
if os.path.exists(output_dir):
412
# Move the bzr control directory back, and update the working tree
413
revdir = os.path.join(tempdir, "rd")
414
if os.path.exists(revdir):
415
# actual imports were done
416
tmp_bzr_dir = os.path.join(tempdir, '.bzr')
418
bzr_dir = os.path.join(output_dir, '.bzr')
419
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr')
421
os.rename(bzr_dir, tmp_bzr_dir) # Move the original bzr out of the way
422
os.rename(new_bzr_dir, bzr_dir)
424
tree = WorkingTree(output_dir)
427
# If something failed, move back the original bzr directory
428
os.rename(bzr_dir, new_bzr_dir)
429
os.rename(tmp_bzr_dir, bzr_dir)
432
# no imports - perhaps just append_revisions
434
tree = WorkingTree(output_dir)
437
revdir = os.path.join(tempdir, "rd")
438
os.rename(revdir, output_dir)
437
# Update the working tree of the branch
439
wt = WorkingTree.open(output_dir)
440
except NoWorkingTree:
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)
441
449
printer('Cleaning up')
495
503
return pybaz.Revision(revision_id[7:].replace('%', '/'))
496
504
except pybaz.errors.NamespaceError, e:
497
505
raise NotArchRevision(revision_id)
508
def create_shared_repository(output_dir):
509
bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
510
bd.create_repository(shared=True)
512
def create_branch(output_dir):
514
bd = bzrdir.BzrDirMetaFormat1().initialize(output_dir)
515
return bd.create_branch()
518
def create_checkout(source, to_location, revision_id=None):
519
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
520
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
521
return checkout.create_workingtree(revision_id)
524
def create_checkout_metadata(source, to_location, revision_id=None):
525
if revision_id is None:
526
revision_id = source.last_revision()
527
wt = create_checkout(source, to_location, NULL_REVISION)
528
wt.set_last_revision(revision_id)
529
wt._write_inventory(wt.basis_tree().inventory)
499
533
def iter_import_version(output_dir, ancestors, tempdir, pb, fast=False,
500
verbose=False, dry_run=False, max_count=None):
534
verbose=False, dry_run=False, max_count=None,
503
538
# Uncomment this for testing, it basically just has baz2bzr only update
517
552
previous_version=None
518
553
missing_ancestor = None
555
dry_output_dir = os.path.join(tempdir, 'od')
556
if os.path.exists(output_dir):
557
shutil.copytree(output_dir, dry_output_dir)
558
output_dir = dry_output_dir
560
if os.path.exists(output_dir):
561
target_branch = Branch.open(output_dir)
564
wt = BzrDir.create_standalone_workingtree(output_dir)
565
target_branch = wt.branch
567
target_branch = create_branch(output_dir)
520
569
for i in range(len(ancestors)):
521
570
revision = ancestors[i]
530
579
previous_version = version
532
581
yield Progress("revisions", i, len(ancestors))
533
if revdir is None and os.path.exists(output_dir):
534
# check for imported revisions and if present just append immediately
535
branch = Branch.open(output_dir)
536
if branch.repository.has_revision(rev_id):
537
branch.append_revision(rev_id)
583
if target_branch.repository.has_revision(rev_id):
584
target_branch.append_revision(rev_id)
539
586
if revdir is None:
540
587
revdir = os.path.join(tempdir, "rd")
548
595
print ("unable to access ancestor %s, making into a merge."
549
596
% missing_ancestor)
551
if os.path.exists(output_dir):
552
bzr_dir = os.path.join(output_dir, '.bzr')
553
new_bzr_dir = os.path.join(tempdir, "rd", '.bzr')
554
# This would be much faster with a simple os.rename(), but if
555
# we fail, we have corrupted the original .bzr directory. Is
556
# that a big problem, as we can just back out the last
557
# revisions in .bzr/revision_history I don't really know
558
# RBC20051024 - yes, it would be a problem as we could not then
559
# apply the corrupted revision.
560
shutil.copytree(bzr_dir, new_bzr_dir)
561
# Now revdir should have a tree with the latest .bzr, and the
562
# next revision of the baz tree
563
branch = Branch.open(revdir)
565
branch = Branch.initialize(revdir)
598
target_tree = create_checkout_metadata(target_branch, revdir)
599
branch = target_tree.branch
567
601
old = os.path.join(revdir, ".bzr")
568
602
new = os.path.join(tempdir, ".bzr")
569
603
os.rename(old, new)
570
604
baz_inv, log = apply_revision(tree, revision)
571
605
os.rename(new, old)
572
branch = Branch.open(revdir)
606
target_tree = WorkingTree.open(revdir)
607
branch = target_tree.branch
573
608
# cached so we can delete the log
574
609
log_date = log.date
575
610
log_summary = log.summary
598
632
target_tree.add_pending_merge(revision_id(merged_rev))
599
633
target_tree.set_inventory(baz_inv)
600
634
commitobj = Commit(reporter=ImportCommitReporter(pb))
601
commitobj.commit(branch, log_message.decode('ascii', 'replace'),
635
commitobj.commit(working_tree=target_tree,
636
message=log_message.decode('ascii', 'replace'),
602
637
verbose=False, committer=log_creator,
603
timestamp=timestamp, timezone=0, rev_id=rev_id)
638
timestamp=timestamp, timezone=0, rev_id=rev_id,
639
revprops={'branch-nick': str(revision.version)})
605
641
target_tree.unlock()
607
643
yield Progress("revisions", len(ancestors), len(ancestors))
608
unlink_unversioned(branch, revdir)
610
645
def get_direct_merges(revdir, revision, log):
611
646
continuation = log.continuation_of
719
756
class cmd_baz_import(Command):
720
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.
722
762
reuse_history allows you to specify any previous imports you
723
763
have done of different archives, which this archive has branches
724
764
tagged from. This will dramatically reduce the time to convert
725
765
the archive as it will not have to convert the history already
726
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
728
774
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
729
takes_options = ['verbose']
775
takes_options = ['verbose', Option('prefixes', type=str,
776
help="Prefixes of branches to import, colon-separated")]
731
778
def printer(self, name):
734
781
def run(self, to_root_dir, from_archive, verbose=False,
735
reuse_history_list=[]):
782
reuse_history_list=[], prefixes=None):
736
783
if reuse_history_list is None:
737
784
reuse_history_list = []
738
785
to_root = str(os.path.realpath(to_root_dir))
739
786
if not os.path.exists(to_root):
740
787
os.mkdir(to_root)
788
if prefixes is not None:
789
prefixes = prefixes.split(':')
741
790
import_archive(to_root, from_archive, verbose, self.printer,
791
reuse_history_list, prefixes=prefixes)
745
794
def import_archive(to_root, from_archive, verbose, printer,
746
reuse_history_from=[]):
795
reuse_history_from=[], standalone=False,
797
def selected(version):
801
for prefix in prefixes:
802
if version.nonarch.startswith(prefix):
747
805
real_to = os.path.realpath(to_root)
748
806
history_locations = [real_to] + reuse_history_from
807
if standalone is False:
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.")
749
815
for version in pybaz.Archive(str(from_archive)).iter_versions():
816
if not selected(version):
817
print "Skipping %s" % version
750
819
target = os.path.join(to_root, map_namespace(version))
751
820
printer("importing %s into %s" % (version, target))
752
821
if not os.path.exists(os.path.dirname(target)):
753
822
os.makedirs(os.path.dirname(target))
755
824
import_version(target, version, printer,
756
reuse_history_from=reuse_history_from)
825
reuse_history_from=reuse_history_from,
826
standalone=standalone)
757
827
except pybaz.errors.ExecProblem,e:
758
828
if str(e).find('The requested revision cannot be built.') != -1:
759
829
printer("Skipping version %s as it cannot be built due"