/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/branch.py

  • Committer: Martin Pool
  • Date: 2006-06-20 03:30:14 UTC
  • mfrom: (1793 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1797.
  • Revision ID: mbp@sourcefrog.net-20060620033014-e19ce470e2ce6561
[merge] bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
import bzrlib.bzrdir as bzrdir
29
29
from bzrlib.config import TreeConfig
30
30
from bzrlib.decorators import needs_read_lock, needs_write_lock
31
 
from bzrlib.delta import compare_trees
32
31
import bzrlib.errors as errors
33
 
from bzrlib.errors import (BzrError, InvalidRevisionNumber, InvalidRevisionId,
34
 
                           NoSuchRevision, NotBranchError,
35
 
                           DivergedBranches, LockError,
36
 
                           UninitializableFormat,
37
 
                           UnlistableStore,
38
 
                           UnlistableBranch, NoSuchFile, NotVersionedError,
39
 
                           NoWorkingTree)
 
32
from bzrlib.errors import (BzrError, BzrCheckError, DivergedBranches, 
 
33
                           HistoryMissing, InvalidRevisionId, 
 
34
                           InvalidRevisionNumber, LockError, NoSuchFile, 
 
35
                           NoSuchRevision, NoWorkingTree, NotVersionedError,
 
36
                           NotBranchError, UninitializableFormat, 
 
37
                           UnlistableStore, UnlistableBranch, 
 
38
                           )
40
39
import bzrlib.inventory as inventory
41
40
from bzrlib.inventory import Inventory
42
41
from bzrlib.lockable_files import LockableFiles, TransportLock
47
46
                            safe_unicode,
48
47
                            rmtree,
49
48
                            )
50
 
from bzrlib.textui import show_status
51
 
from bzrlib.trace import mutter, note
52
 
from bzrlib.tree import EmptyTree, RevisionTree
53
49
from bzrlib.repository import Repository
54
50
from bzrlib.revision import (
55
51
                             is_ancestor,
58
54
                             )
59
55
from bzrlib.store import copy_all
60
56
from bzrlib.symbol_versioning import *
 
57
from bzrlib.textui import show_status
 
58
from bzrlib.trace import mutter, note
61
59
import bzrlib.transactions as transactions
62
60
from bzrlib.transport import Transport, get_transport
63
 
from bzrlib.tree import EmptyTree, RevisionTree
64
61
import bzrlib.ui
 
62
import bzrlib.urlutils as urlutils
65
63
import bzrlib.xml5
66
64
 
67
65
 
249
247
        branch.
250
248
        """
251
249
        return None
 
250
    
 
251
    def get_commit_builder(self, parents, config=None, timestamp=None, 
 
252
                           timezone=None, committer=None, revprops=None, 
 
253
                           revision_id=None):
 
254
        """Obtain a CommitBuilder for this branch.
 
255
        
 
256
        :param parents: Revision ids of the parents of the new revision.
 
257
        :param config: Optional configuration to use.
 
258
        :param timestamp: Optional timestamp recorded for commit.
 
259
        :param timezone: Optional timezone for timestamp.
 
260
        :param committer: Optional committer to set for commit.
 
261
        :param revprops: Optional dictionary of revision properties.
 
262
        :param revision_id: Optional revision id.
 
263
        """
 
264
 
 
265
        if config is None:
 
266
            config = bzrlib.config.BranchConfig(self)
 
267
        
 
268
        return self.repository.get_commit_builder(self, parents, config, 
 
269
            timestamp, timezone, committer, revprops, revision_id)
252
270
 
253
271
    def get_master_branch(self):
254
272
        """Return the branch we are bound to.
257
275
        """
258
276
        return None
259
277
 
 
278
    def get_revision_delta(self, revno):
 
279
        """Return the delta for one revision.
 
280
 
 
281
        The delta is relative to its mainline predecessor, or the
 
282
        empty tree for revision 1.
 
283
        """
 
284
        assert isinstance(revno, int)
 
285
        rh = self.revision_history()
 
286
        if not (1 <= revno <= len(rh)):
 
287
            raise InvalidRevisionNumber(revno)
 
288
        return self.repository.get_revision_delta(rh[revno-1])
 
289
 
260
290
    def get_root_id(self):
261
291
        """Return the id of this branches root"""
262
292
        raise NotImplementedError('get_root_id is abstract')
431
461
        revision_id: if not None, the revision history in the new branch will
432
462
                     be truncated to end with revision_id.
433
463
        """
434
 
        # for API compatability, until 0.8 releases we provide the old api:
 
464
        # for API compatibility, until 0.8 releases we provide the old api:
435
465
        # def clone(self, to_location, revision=None, basis_branch=None, to_branch_format=None):
436
466
        # after 0.8 releases, the *args and **kwargs should be changed:
437
467
        # def clone(self, to_bzrdir, revision_id=None):
439
469
            kwargs.get('revision', None) or
440
470
            kwargs.get('basis_branch', None) or
441
471
            (len(args) and isinstance(args[0], basestring))):
442
 
            # backwards compatability api:
 
472
            # backwards compatibility api:
443
473
            warn("Branch.clone() has been deprecated for BzrDir.clone() from"
444
474
                 " bzrlib 0.8.", DeprecationWarning, stacklevel=3)
445
475
            # get basis_branch
511
541
        if parent:
512
542
            destination.set_parent(parent)
513
543
 
 
544
    @needs_read_lock
 
545
    def check(self):
 
546
        """Check consistency of the branch.
 
547
 
 
548
        In particular this checks that revisions given in the revision-history
 
549
        do actually match up in the revision graph, and that they're all 
 
550
        present in the repository.
 
551
 
 
552
        :return: A BranchCheckResult.
 
553
        """
 
554
        mainline_parent_id = None
 
555
        for revision_id in self.revision_history():
 
556
            try:
 
557
                revision = self.repository.get_revision(revision_id)
 
558
            except errors.NoSuchRevision, e:
 
559
                raise BzrCheckError("mainline revision {%s} not in repository"
 
560
                        % revision_id)
 
561
            # In general the first entry on the revision history has no parents.
 
562
            # But it's not illegal for it to have parents listed; this can happen
 
563
            # in imports from Arch when the parents weren't reachable.
 
564
            if mainline_parent_id is not None:
 
565
                if mainline_parent_id not in revision.parent_ids:
 
566
                    raise BzrCheckError("previous revision {%s} not listed among "
 
567
                                        "parents of {%s}"
 
568
                                        % (mainline_parent_id, revision_id))
 
569
            mainline_parent_id = revision_id
 
570
        return BranchCheckResult(self)
 
571
 
514
572
 
515
573
class BranchFormat(object):
516
574
    """An encapsulation of the initialization and open routines for a format.
563
621
 
564
622
    def initialize(self, a_bzrdir):
565
623
        """Create a branch of this format in a_bzrdir."""
566
 
        raise NotImplementedError(self.initialized)
 
624
        raise NotImplementedError(self.initialize)
567
625
 
568
626
    def is_supported(self):
569
627
        """Is this format supported?
991
1049
            # not really an object yet, and the transaction is for objects.
992
1050
            # transaction.register_clean(history)
993
1051
 
994
 
    def get_revision_delta(self, revno):
995
 
        """Return the delta for one revision.
996
 
 
997
 
        The delta is relative to its mainline predecessor, or the
998
 
        empty tree for revision 1.
999
 
        """
1000
 
        assert isinstance(revno, int)
1001
 
        rh = self.revision_history()
1002
 
        if not (1 <= revno <= len(rh)):
1003
 
            raise InvalidRevisionNumber(revno)
1004
 
 
1005
 
        # revno is 1-based; list is 0-based
1006
 
 
1007
 
        new_tree = self.repository.revision_tree(rh[revno-1])
1008
 
        if revno == 1:
1009
 
            old_tree = EmptyTree()
1010
 
        else:
1011
 
            old_tree = self.repository.revision_tree(rh[revno-2])
1012
 
        return compare_trees(old_tree, new_tree)
1013
 
 
1014
1052
    @needs_read_lock
1015
1053
    def revision_history(self):
1016
1054
        """See Branch.revision_history."""
1103
1141
        """See Branch.get_parent."""
1104
1142
        import errno
1105
1143
        _locs = ['parent', 'pull', 'x-pull']
 
1144
        assert self.base[-1] == '/'
1106
1145
        for l in _locs:
1107
1146
            try:
1108
 
                return self.control_files.get_utf8(l).read().strip('\n')
 
1147
                parent = self.control_files.get(l).read().strip('\n')
1109
1148
            except NoSuchFile:
1110
 
                pass
 
1149
                continue
 
1150
            # This is an old-format absolute path to a local branch
 
1151
            # turn it into a url
 
1152
            if parent.startswith('/'):
 
1153
                parent = urlutils.local_path_to_url(parent.decode('utf8'))
 
1154
            return urlutils.join(self.base[:-1], parent)
1111
1155
        return None
1112
1156
 
1113
1157
    def get_push_location(self):
1132
1176
        if url is None:
1133
1177
            self.control_files._transport.delete('parent')
1134
1178
        else:
1135
 
            self.control_files.put_utf8('parent', url + '\n')
 
1179
            if isinstance(url, unicode):
 
1180
                try: 
 
1181
                    url = url.encode('ascii')
 
1182
                except UnicodeEncodeError:
 
1183
                    raise bzrlib.errors.InvalidURL(url,
 
1184
                        "Urls must be 7-bit ascii, "
 
1185
                        "use bzrlib.urlutils.escape")
 
1186
                    
 
1187
            url = urlutils.relative_url(self.base, url)
 
1188
            self.control_files.put('parent', url + '\n')
1136
1189
 
1137
1190
    def tree_config(self):
1138
1191
        return TreeConfig(self)
1180
1233
 
1181
1234
        This could memoise the branch, but if thats done
1182
1235
        it must be revalidated on each new lock.
1183
 
        So for now we just dont memoise it.
 
1236
        So for now we just don't memoise it.
1184
1237
        # RBC 20060304 review this decision.
1185
1238
        """
1186
1239
        bound_loc = self.get_bound_location()
1232
1285
        # There may be a different check you could do here
1233
1286
        # rather than actually trying to install revisions remotely.
1234
1287
        # TODO: capture an exception which indicates the remote branch
1235
 
        #       is not writeable. 
 
1288
        #       is not writable. 
1236
1289
        #       If it is up-to-date, this probably should not be a failure
1237
1290
        
1238
1291
        # lock other for write so the revision-history syncing cannot race
1304
1357
        return result
1305
1358
 
1306
1359
 
 
1360
class BranchCheckResult(object):
 
1361
    """Results of checking branch consistency.
 
1362
 
 
1363
    :see: Branch.check
 
1364
    """
 
1365
 
 
1366
    def __init__(self, branch):
 
1367
        self.branch = branch
 
1368
 
 
1369
    def report_results(self, verbose):
 
1370
        """Report the check results via trace.note.
 
1371
        
 
1372
        :param verbose: Requests more detailed display of what was checked,
 
1373
            if any.
 
1374
        """
 
1375
        note('checked branch %s format %s',
 
1376
             self.branch.base,
 
1377
             self.branch._format)
 
1378
 
 
1379
 
1307
1380
######################################################################
1308
1381
# predicates
1309
1382