/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/revisionspec.py

Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
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
21
21
 
22
22
from bzrlib import (
23
23
    errors,
 
24
    osutils,
24
25
    revision,
25
26
    symbol_versioning,
26
27
    trace,
93
94
        return '<bzrlib.revisionspec.RevisionInfo object %s, %s for %r>' % (
94
95
            self.revno, self.rev_id, self.branch)
95
96
 
 
97
    @staticmethod
 
98
    def from_revision_id(branch, revision_id, revs):
 
99
        """Construct a RevisionInfo given just the id.
 
100
 
 
101
        Use this if you don't know or care what the revno is.
 
102
        """
 
103
        try:
 
104
            revno = revs.index(revision_id) + 1
 
105
        except ValueError:
 
106
            revno = None
 
107
        return RevisionInfo(branch, revno, revision_id)
 
108
 
96
109
 
97
110
# classes in this list should have a "prefix" attribute, against which
98
111
# string specs are matched
308
321
        if dotted:
309
322
            branch.lock_read()
310
323
            try:
311
 
                last_rev = branch.last_revision()
312
 
                merge_sorted_revisions = tsort.merge_sort(
313
 
                    branch.repository.get_revision_graph(last_rev),
314
 
                    last_rev,
315
 
                    generate_revno=True)
316
 
                def match(item):
317
 
                    return item[3] == match_revno
318
 
                revisions = filter(match, merge_sorted_revisions)
 
324
                revision_id_to_revno = branch.get_revision_id_to_revno_map()
 
325
                revisions = [revision_id for revision_id, revno
 
326
                             in revision_id_to_revno.iteritems()
 
327
                             if revno == match_revno]
319
328
            finally:
320
329
                branch.unlock()
321
330
            if len(revisions) != 1:
323
332
            else:
324
333
                # there is no traditional 'revno' for dotted-decimal revnos.
325
334
                # so for  API compatability we return None.
326
 
                return RevisionInfo(branch, None, revisions[0][1])
 
335
                return RevisionInfo(branch, None, revisions[0])
327
336
        else:
328
337
            if revno < 0:
 
338
                # if get_rev_id supported negative revnos, there would not be a
 
339
                # need for this special case.
329
340
                if (-revno) >= len(revs):
330
341
                    revno = 1
331
342
                else:
365
376
    prefix = 'revid:'
366
377
 
367
378
    def _match_on(self, branch, revs):
368
 
        try:
369
 
            revno = revs.index(self.spec) + 1
370
 
        except ValueError:
371
 
            revno = None
372
 
        return RevisionInfo(branch, revno, self.spec)
 
379
        # self.spec comes straight from parsing the command line arguments,
 
380
        # so we expect it to be a Unicode string. Switch it to the internal
 
381
        # representation.
 
382
        revision_id = osutils.safe_revision_id(self.spec, warn=False)
 
383
        return RevisionInfo.from_revision_id(branch, revision_id, revs)
373
384
 
374
385
SPEC_TYPES.append(RevisionSpec_revid)
375
386
 
463
474
 
464
475
 
465
476
class RevisionSpec_tag(RevisionSpec):
466
 
    """To be implemented."""
467
 
 
468
 
    help_txt = """To be implemented."""
 
477
    """Select a revision identified by tag name"""
 
478
 
 
479
    help_txt = """Selects a revision identified by a tag name.
 
480
 
 
481
    Tags are stored in the branch and created by the 'tag' command.
 
482
    """
469
483
 
470
484
    prefix = 'tag:'
471
485
 
472
486
    def _match_on(self, branch, revs):
473
 
        raise errors.InvalidRevisionSpec(self.user_spec, branch,
474
 
                                         'tag: namespace registered,'
475
 
                                         ' but not implemented')
 
487
        # Can raise tags not supported, NoSuchTag, etc
 
488
        return RevisionInfo.from_revision_id(branch,
 
489
            branch.tags.lookup_tag(self.spec),
 
490
            revs)
476
491
 
477
492
SPEC_TYPES.append(RevisionSpec_tag)
478
493
 
604
619
    prefix = 'ancestor:'
605
620
 
606
621
    def _match_on(self, branch, revs):
 
622
        trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
 
623
        return self._find_revision_info(branch, self.spec)
 
624
 
 
625
    @staticmethod
 
626
    def _find_revision_info(branch, other_location):
607
627
        from bzrlib.branch import Branch
608
628
 
609
 
        trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
610
 
        other_branch = Branch.open(self.spec)
 
629
        other_branch = Branch.open(other_location)
611
630
        revision_a = branch.last_revision()
612
631
        revision_b = other_branch.last_revision()
613
632
        for r, b in ((revision_a, branch), (revision_b, other_branch)):
622
641
        except errors.NoSuchRevision:
623
642
            revno = None
624
643
        return RevisionInfo(branch, revno, rev_id)
625
 
        
 
644
 
 
645
 
626
646
SPEC_TYPES.append(RevisionSpec_ancestor)
627
647
 
628
648
 
653
673
        return RevisionInfo(branch, revno, revision_b)
654
674
        
655
675
SPEC_TYPES.append(RevisionSpec_branch)
 
676
 
 
677
 
 
678
class RevisionSpec_submit(RevisionSpec_ancestor):
 
679
    """Selects a common ancestor with a submit branch."""
 
680
 
 
681
    help_txt = """Selects a common ancestor with the submit branch.
 
682
 
 
683
    Diffing against this shows all the changes that were made in this branch,
 
684
    and is a good predictor of what merge will do.  The submit branch is
 
685
    used by the bundle and merge directive comands.  If no submit branch
 
686
    is specified, the parent branch is used instead.
 
687
 
 
688
    The common ancestor is the last revision that existed in both
 
689
    branches. Usually this is the branch point, but it could also be
 
690
    a revision that was merged.
 
691
 
 
692
    examples:
 
693
      $ bzr diff -r submit:
 
694
    """
 
695
 
 
696
    prefix = 'submit:'
 
697
 
 
698
    def _match_on(self, branch, revs):
 
699
        trace.mutter('matching ancestor: on: %s, %s', self.spec, branch)
 
700
        submit_location = branch.get_submit_branch()
 
701
        location_type = 'submit branch'
 
702
        if submit_location is None:
 
703
            submit_location = branch.get_parent()
 
704
            location_type = 'parent branch'
 
705
        if submit_location is None:
 
706
            raise errors.NoSubmitBranch(branch)
 
707
        trace.note('Using %s %s', location_type, submit_location)
 
708
        return self._find_revision_info(branch, submit_location)
 
709
 
 
710
 
 
711
SPEC_TYPES.append(RevisionSpec_submit)