~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to baz_import.py

  • Committer: Robert Collins
  • Date: 2005-10-24 06:21:01 UTC
  • mto: (147.1.42) (364.1.3 bzrtools)
  • mto: This revision was merged to the branch mainline in revision 324.
  • Revision ID: robertc@robertcollins.net-20051024062101-0e4b070c687be780
Fix continuation direct_merges output, and allow reusing history in a version import

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
from bzrlib.errors import BzrError
 
18
from bzrlib.errors import NotBranchError, BzrCommandError, NoSuchRevision
18
19
from bzrlib.branch import Branch
 
20
from bzrlib.clone import copy_branch
19
21
from bzrlib.commit import Commit, NullCommitReporter
20
22
from bzrlib.commands import Command
21
23
from bzrlib.option import _global_option
33
35
import os.path
34
36
import shutil
35
37
import bzrlib
36
 
from bzrlib.errors import BzrError
37
38
import bzrlib.trace
38
39
import bzrlib.merge
39
40
import bzrlib.inventory
236
237
            "Directory \"%s\" already exists, and the last revision is not"
237
238
            " an Arch revision (%s)" % (branch.base, last_patch))
238
239
 
 
240
def do_branch(br_from, to_location, revision_id):
 
241
    """Derived from branch in builtins."""
 
242
    br_from.lock_read()
 
243
    try:
 
244
        try:
 
245
            os.mkdir(to_location)
 
246
        except OSError, e:
 
247
            if e.errno == errno.EEXIST:
 
248
                raise UserError('Target directory "%s" already'
 
249
                                      ' exists.' % to_location)
 
250
            if e.errno == errno.ENOENT:
 
251
                raise UserError('Parent of "%s" does not exist.' %
 
252
                                      to_location)
 
253
            else:
 
254
                raise
 
255
        try:
 
256
            copy_branch(br_from, to_location, revision_id, None)
 
257
        except NoSuchRevision:
 
258
            rmtree(to_location)
 
259
            msg = "The branch %s has no revision %s." % (from_location, revision_id)
 
260
            raise UserError(msg)
 
261
    finally:
 
262
        br_from.unlock()
239
263
 
240
 
def get_remaining_revisions(output_dir, version):
 
264
def get_remaining_revisions(output_dir, version, reuse_history_from=[]):
241
265
    last_patch = None
242
266
    old_revno = None
243
 
    if os.path.exists(output_dir):
 
267
    output_exists = os.path.exists(output_dir)
 
268
    if output_exists:
244
269
        # We are starting from an existing directory, figure out what
245
270
        # the current version is
246
271
        branch = Branch.open(output_dir)
252
277
 
253
278
    try:
254
279
        ancestors = version_ancestry(version)
 
280
        if not output_exists and reuse_history_from != []:
 
281
            for ancestor in reversed(ancestors):
 
282
                # try to grab a copy of ancestor
 
283
                # note that is not optimised: we could look for namespace
 
284
                # transitions and only look for the past after the 
 
285
                # transition.
 
286
                for history_root in reuse_history_from:
 
287
                    possible_source = os.path.join(history_root,
 
288
                        map_namespace(ancestor.version))
 
289
                    try:
 
290
                        source = Branch.open(possible_source)
 
291
                        rev_id = revision_id(ancestor)
 
292
                        if rev_id in source.revision_history():
 
293
                            do_branch(source, output_dir, rev_id)
 
294
                            last_patch = ancestor
 
295
                            break
 
296
                    except NotBranchError:
 
297
                        pass
255
298
    except NoSuchVersion, e:
256
299
        raise UserError(str(e))
257
300
 
270
313
        ancestors = ancestors[i+1:]
271
314
    return ancestors, old_revno
272
315
 
 
316
 
 
317
###class Importer(object):
 
318
###    """An importer.
 
319
###    
 
320
###    Currently this is used as a parameter object, though more behaviour is
 
321
###    possible later.
 
322
###    """
 
323
###
 
324
###    def __init__(self, output_dir, version, printer, fancy=True, fast=False,
 
325
###                 verbose=False, dry_run=False, max_count=None, 
 
326
###                   reuse_history_from=[]):
 
327
###        self.output_dir = output_dir
 
328
###        self.version = version
 
329
###        self.
 
330
 
 
331
 
273
332
def import_version(output_dir, version, printer, fancy=True, fast=False,
274
 
                   verbose=False, dry_run=False, max_count=None):
 
333
                   verbose=False, dry_run=False, max_count=None,
 
334
                   reuse_history_from=[]):
275
335
    """
276
336
    >>> q = test_environ()
277
337
    >>> result_path = os.path.join(q, "result")
306
366
    >>> teardown_environ(q)
307
367
    """
308
368
    try:
309
 
        ancestors, old_revno = get_remaining_revisions(output_dir, version)
 
369
        ancestors, old_revno = get_remaining_revisions(output_dir, version,
 
370
                                                       reuse_history_from)
310
371
    except NotBranchError, e:
311
372
        raise UserError("%s exists, but is not a bzr branch." % output_dir)
312
373
    if old_revno is None and len(ancestors) == 0:
504
565
        log_description = log.description
505
566
        is_continuation = log.continuation_of is not None
506
567
        log_creator = log.creator
507
 
        direct_merges = get_direct_merges(revdir, revision)
 
568
        direct_merges = get_direct_merges(revdir, revision, log)
508
569
 
509
570
        timestamp = email.Utils.mktime_tz(log_date + (0,))
510
571
        if log_summary is None:
520
581
                # if we want it to be in revision-history, do that here.
521
582
                branch.add_pending_merge(revision_id(missing_ancestor))
522
583
                missing_ancestor = None
523
 
            for merge in direct_merges:
524
 
                branch.add_pending_merge(revision_id(merge.revision))
 
584
            for merged_rev in direct_merges:
 
585
                branch.add_pending_merge(revision_id(merged_rev))
525
586
            branch.set_inventory(baz_inv)
526
587
            commitobj = Commit(reporter=ImportCommitReporter(pb))
527
588
            commitobj.commit(branch, log_message.decode('ascii', 'replace'), 
532
593
    yield Progress("revisions", len(ancestors), len(ancestors))
533
594
    unlink_unversioned(branch, revdir)
534
595
 
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)
 
596
def get_direct_merges(revdir, revision, log):
 
597
    continuation = log.continuation_of
 
598
    previous_version = revision.version
 
599
    if pybaz.WorkingTree(revdir).tree_version != previous_version:
 
600
        pybaz.WorkingTree(revdir).set_tree_version(previous_version)
538
601
    log_path = "%s/{arch}/%s/%s/%s/%s/patch-log/%s" % (revdir, 
539
602
        revision.category.nonarch, revision.branch.nonarch, 
540
603
        revision.version.nonarch, revision.archive, revision.patchlevel)
541
604
    temp_path = tempfile.mktemp(dir=os.path.dirname(revdir))
542
605
    os.rename(log_path, temp_path)
543
606
    merges = list(iter_new_merges(revdir, revision.version))
544
 
    direct = direct_merges (merges)
 
607
    direct = direct_merges(merges, [continuation])
545
608
    os.rename(temp_path, log_path)
546
609
    return direct
547
610