~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:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from bzrlib.errors import NotBranchError, BzrCommandError
 
17
import errno
 
18
 
 
19
from bzrlib.errors import BzrError
 
20
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision
18
21
from bzrlib.branch import Branch
 
22
from bzrlib.clone import copy_branch
19
23
from bzrlib.commit import Commit, NullCommitReporter
20
24
from bzrlib.commands import Command
21
25
from bzrlib.option import _global_option
33
37
import os.path
34
38
import shutil
35
39
import bzrlib
36
 
from bzrlib.errors import BzrError
37
40
import bzrlib.trace
38
41
import bzrlib.merge
39
42
import bzrlib.inventory
236
239
            "Directory \"%s\" already exists, and the last revision is not"
237
240
            " an Arch revision (%s)" % (branch.base, last_patch))
238
241
 
 
242
def do_branch(br_from, to_location, revision_id):
 
243
    """Derived from branch in builtins."""
 
244
    br_from.lock_read()
 
245
    try:
 
246
        try:
 
247
            os.mkdir(to_location)
 
248
        except OSError, e:
 
249
            if e.errno == errno.EEXIST:
 
250
                raise UserError('Target directory "%s" already'
 
251
                                      ' exists.' % to_location)
 
252
            if e.errno == errno.ENOENT:
 
253
                raise UserError('Parent of "%s" does not exist.' %
 
254
                                      to_location)
 
255
            else:
 
256
                raise
 
257
        try:
 
258
            copy_branch(br_from, to_location, revision_id, None)
 
259
        except NoSuchRevision:
 
260
            rmtree(to_location)
 
261
            msg = "The branch %s has no revision %s." % (from_location, revision_id)
 
262
            raise UserError(msg)
 
263
    finally:
 
264
        br_from.unlock()
239
265
 
240
 
def get_remaining_revisions(output_dir, version):
 
266
def get_remaining_revisions(output_dir, version, reuse_history_from=[]):
241
267
    last_patch = None
242
268
    old_revno = None
243
 
    if os.path.exists(output_dir):
 
269
    output_exists = os.path.exists(output_dir)
 
270
    if output_exists:
244
271
        # We are starting from an existing directory, figure out what
245
272
        # the current version is
246
273
        branch = Branch.open(output_dir)
252
279
 
253
280
    try:
254
281
        ancestors = version_ancestry(version)
 
282
        if not output_exists and reuse_history_from != []:
 
283
            for ancestor in reversed(ancestors):
 
284
                if last_patch is not None:
 
285
                    # found something to copy
 
286
                    break
 
287
                # try to grab a copy of ancestor
 
288
                # note that is not optimised: we could look for namespace
 
289
                # transitions and only look for the past after the 
 
290
                # transition.
 
291
                for history_root in reuse_history_from:
 
292
                    possible_source = os.path.join(history_root,
 
293
                        map_namespace(ancestor.version))
 
294
                    try:
 
295
                        source = Branch.open(possible_source)
 
296
                        rev_id = revision_id(ancestor)
 
297
                        if rev_id in source.revision_history():
 
298
                            do_branch(source, output_dir, rev_id)
 
299
                            last_patch = ancestor
 
300
                            break
 
301
                    except NotBranchError:
 
302
                        pass
255
303
    except NoSuchVersion, e:
256
304
        raise UserError(str(e))
257
305
 
270
318
        ancestors = ancestors[i+1:]
271
319
    return ancestors, old_revno
272
320
 
 
321
 
 
322
###class Importer(object):
 
323
###    """An importer.
 
324
###    
 
325
###    Currently this is used as a parameter object, though more behaviour is
 
326
###    possible later.
 
327
###    """
 
328
###
 
329
###    def __init__(self, output_dir, version, printer, fancy=True, fast=False,
 
330
###                 verbose=False, dry_run=False, max_count=None, 
 
331
###                   reuse_history_from=[]):
 
332
###        self.output_dir = output_dir
 
333
###        self.version = version
 
334
###        self.
 
335
 
 
336
 
273
337
def import_version(output_dir, version, printer, fancy=True, fast=False,
274
 
                   verbose=False, dry_run=False, max_count=None):
 
338
                   verbose=False, dry_run=False, max_count=None,
 
339
                   reuse_history_from=[]):
275
340
    """
276
341
    >>> q = test_environ()
277
342
    >>> result_path = os.path.join(q, "result")
306
371
    >>> teardown_environ(q)
307
372
    """
308
373
    try:
309
 
        ancestors, old_revno = get_remaining_revisions(output_dir, version)
 
374
        ancestors, old_revno = get_remaining_revisions(output_dir, version,
 
375
                                                       reuse_history_from)
310
376
    except NotBranchError, e:
311
377
        raise UserError("%s exists, but is not a bzr branch." % output_dir)
312
378
    if old_revno is None and len(ancestors) == 0:
504
570
        log_description = log.description
505
571
        is_continuation = log.continuation_of is not None
506
572
        log_creator = log.creator
507
 
        direct_merges = get_direct_merges(revdir, revision)
 
573
        direct_merges = get_direct_merges(revdir, revision, log)
508
574
 
509
575
        timestamp = email.Utils.mktime_tz(log_date + (0,))
510
576
        if log_summary is None:
520
586
                # if we want it to be in revision-history, do that here.
521
587
                branch.add_pending_merge(revision_id(missing_ancestor))
522
588
                missing_ancestor = None
523
 
            for merge in direct_merges:
524
 
                branch.add_pending_merge(revision_id(merge.revision))
 
589
            for merged_rev in direct_merges:
 
590
                branch.add_pending_merge(revision_id(merged_rev))
525
591
            branch.set_inventory(baz_inv)
526
592
            commitobj = Commit(reporter=ImportCommitReporter(pb))
527
593
            commitobj.commit(branch, log_message.decode('ascii', 'replace'), 
532
598
    yield Progress("revisions", len(ancestors), len(ancestors))
533
599
    unlink_unversioned(branch, revdir)
534
600
 
535
 
def get_direct_merges(revdir, revision):
536
 
    if pybaz.WorkingTree(revdir).tree_version != revision.version:
537
 
        pybaz.WorkingTree(revdir).set_tree_version(revision.version)
 
601
def get_direct_merges(revdir, revision, log):
 
602
    continuation = log.continuation_of
 
603
    previous_version = revision.version
 
604
    if pybaz.WorkingTree(revdir).tree_version != previous_version:
 
605
        pybaz.WorkingTree(revdir).set_tree_version(previous_version)
538
606
    log_path = "%s/{arch}/%s/%s/%s/%s/patch-log/%s" % (revdir, 
539
607
        revision.category.nonarch, revision.branch.nonarch, 
540
608
        revision.version.nonarch, revision.archive, revision.patchlevel)
541
609
    temp_path = tempfile.mktemp(dir=os.path.dirname(revdir))
542
610
    os.rename(log_path, temp_path)
543
611
    merges = list(iter_new_merges(revdir, revision.version))
544
 
    direct = direct_merges (merges)
 
612
    direct = direct_merges(merges, [continuation])
545
613
    os.rename(temp_path, log_path)
546
614
    return direct
547
615
 
611
679
_global_option('max-count', type = int)
612
680
class cmd_baz_import_branch(Command):
613
681
    """Import an Arch or Baz branch into a bzr branch"""
614
 
    takes_args = ['to_location', 'from_branch?']
 
682
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
615
683
    takes_options = ['verbose', 'max-count']
616
684
 
617
685
    def printer(self, name):
618
686
        print name
619
687
 
620
688
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
621
 
            verbose=False, dry_run=False):
 
689
            verbose=False, dry_run=False, reuse_history_list=[]):
622
690
        to_location = os.path.realpath(str(to_location))
623
691
        if from_branch is not None:
624
692
            try:
626
694
            except pybaz.errors.NamespaceError:
627
695
                print "%s is not a valid Arch branch." % from_branch
628
696
                return 1
 
697
        if reuse_history_list is None:
 
698
            reuse_history_list = []
629
699
        import_version(to_location, from_branch, self.printer, 
630
 
                       max_count=max_count)
 
700
                       max_count=max_count, reuse_history_from=reuse_history_list)
631
701
 
632
702
 
633
703
class cmd_baz_import(Command):
634
 
    """Import an Arch or Baz archive into bzr branches."""
635
 
    takes_args = ['to_root_dir', 'from_archive']
 
704
    """Import an Arch or Baz archive into bzr branches.
 
705
    
 
706
    reuse_history allows you to specify any previous imports you 
 
707
    have done of different archives, which this archive has branches
 
708
    tagged from. This will dramatically reduce the time to convert 
 
709
    the archive as it will not have to convert the history already
 
710
    converted in that other branch.
 
711
    """
 
712
    takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
636
713
    takes_options = ['verbose']
637
714
 
638
715
    def printer(self, name):
639
716
        print name
640
717
 
641
 
    def run(self, to_root_dir, from_archive, verbose=False):
 
718
    def run(self, to_root_dir, from_archive, verbose=False,
 
719
            reuse_history_list=[]):
 
720
        if reuse_history_list is None:
 
721
            reuse_history_list = []
642
722
        to_root = str(os.path.realpath(to_root_dir))
643
723
        if not os.path.exists(to_root):
644
724
            os.mkdir(to_root)
645
 
        import_archive(to_root, from_archive, verbose, self.printer)
646
 
 
647
 
 
648
 
def import_archive(to_root, from_archive, verbose, printer):
 
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=[]):
 
731
    real_to = os.path.realpath(to_root)
 
732
    history_locations = [real_to] + reuse_history_from
649
733
    for version in pybaz.Archive(str(from_archive)).iter_versions():
650
734
        target = os.path.join(to_root, map_namespace(version))
651
735
        printer("importing %s into %s" % (version, target))
652
736
        if not os.path.exists(os.path.dirname(target)):
653
737
            os.makedirs(os.path.dirname(target))
654
738
        try:
655
 
            import_version(target, version, printer)
 
739
            import_version(target, version, printer,
 
740
                           reuse_history_from=reuse_history_from)
656
741
        except pybaz.errors.ExecProblem,e:
657
742
            if str(e).find('The requested revision cannot be built.') != -1:
658
743
                printer("Skipping version %s as it cannot be built due"