/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

[merge] bzr.dev 2255

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
 
18
from cStringIO import StringIO
 
19
 
 
20
from bzrlib.lazy_import import lazy_import
 
21
lazy_import(globals(), """
18
22
from copy import deepcopy
19
 
from cStringIO import StringIO
20
23
from unittest import TestSuite
21
24
from warnings import warn
22
25
 
24
27
from bzrlib import (
25
28
        bzrdir,
26
29
        cache_utf8,
 
30
        config as _mod_config,
27
31
        errors,
28
32
        lockdir,
 
33
        lockable_files,
29
34
        osutils,
30
 
        revision,
 
35
        revision as _mod_revision,
31
36
        transport,
32
37
        tree,
33
38
        ui,
34
39
        urlutils,
35
40
        )
36
 
from bzrlib.config import TreeConfig
 
41
from bzrlib.config import BranchConfig, TreeConfig
 
42
from bzrlib.lockable_files import LockableFiles, TransportLock
 
43
""")
 
44
 
37
45
from bzrlib.decorators import needs_read_lock, needs_write_lock
38
 
import bzrlib.errors as errors
39
 
from bzrlib.errors import (BzrError, BzrCheckError, DivergedBranches, 
40
 
                           HistoryMissing, InvalidRevisionId, 
41
 
                           InvalidRevisionNumber, LockError, NoSuchFile, 
 
46
from bzrlib.errors import (BzrError, BzrCheckError, DivergedBranches,
 
47
                           HistoryMissing, InvalidRevisionId,
 
48
                           InvalidRevisionNumber, LockError, NoSuchFile,
42
49
                           NoSuchRevision, NoWorkingTree, NotVersionedError,
43
 
                           NotBranchError, UninitializableFormat, 
44
 
                           UnlistableStore, UnlistableBranch, 
 
50
                           NotBranchError, UninitializableFormat,
 
51
                           UnlistableStore, UnlistableBranch,
45
52
                           )
46
 
from bzrlib.lockable_files import LockableFiles, TransportLock
47
53
from bzrlib.symbol_versioning import (deprecated_function,
48
54
                                      deprecated_method,
49
55
                                      DEPRECATED_PARAMETER,
75
81
 
76
82
    base
77
83
        Base directory/url of the branch.
 
84
 
 
85
    hooks: An instance of BranchHooks.
78
86
    """
79
87
    # this is really an instance variable - FIXME move it there
80
88
    # - RBC 20060112
148
156
        pass
149
157
 
150
158
    def get_config(self):
151
 
        return bzrlib.config.BranchConfig(self)
 
159
        return BranchConfig(self)
152
160
 
153
161
    def _get_nick(self):
154
162
        return self.get_config().get_nickname()
222
230
                    last_revision = from_history[-1]
223
231
                else:
224
232
                    # no history in the source branch
225
 
                    last_revision = revision.NULL_REVISION
 
233
                    last_revision = _mod_revision.NULL_REVISION
226
234
            return self.repository.fetch(from_branch.repository,
227
235
                                         revision_id=last_revision,
228
236
                                         pb=nested_pb)
369
377
        return history[revno - 1]
370
378
 
371
379
    def pull(self, source, overwrite=False, stop_revision=None):
 
380
        """Mirror source into this branch.
 
381
 
 
382
        This branch is considered to be 'local', having low latency.
 
383
        """
372
384
        raise NotImplementedError(self.pull)
373
385
 
 
386
    def push(self, target, overwrite=False, stop_revision=None):
 
387
        """Mirror this branch into target.
 
388
 
 
389
        This branch is considered to be 'local', having low latency.
 
390
        """
 
391
        raise NotImplementedError(self.push)
 
392
 
374
393
    def basis_tree(self):
375
394
        """Return `Tree` object for last revision."""
376
395
        return self.repository.revision_tree(self.last_revision())
593
612
            format = self.repository.bzrdir.cloning_metadir()
594
613
        return format
595
614
 
596
 
    def create_checkout(self, to_location, revision_id=None, 
 
615
    def create_checkout(self, to_location, revision_id=None,
597
616
                        lightweight=False):
598
617
        """Create a checkout of a branch.
599
618
        
710
729
        return self.get_format_string().rstrip()
711
730
 
712
731
 
 
732
class BranchHooks(dict):
 
733
    """A dictionary mapping hook name to a list of callables for branch hooks.
 
734
    
 
735
    e.g. ['set_rh'] Is the list of items to be called when the
 
736
    set_revision_history function is invoked.
 
737
    """
 
738
 
 
739
    def __init__(self):
 
740
        """Create the default hooks.
 
741
 
 
742
        These are all empty initially, because by default nothing should get
 
743
        notified.
 
744
        """
 
745
        dict.__init__(self)
 
746
        # invoked whenever the revision history has been set
 
747
        # with set_revision_history. The api signature is
 
748
        # (branch, revision_history), and the branch will
 
749
        # be write-locked. Introduced in 0.15.
 
750
        self['set_rh'] = []
 
751
 
 
752
    def install_hook(self, hook_name, a_callable):
 
753
        """Install a_callable in to the hook hook_name.
 
754
 
 
755
        :param hook_name: A hook name. See the __init__ method of BranchHooks
 
756
            for the complete list of hooks.
 
757
        :param a_callable: The callable to be invoked when the hook triggers.
 
758
            The exact signature will depend on the hook - see the __init__ 
 
759
            method of BranchHooks for details on each hook.
 
760
        """
 
761
        try:
 
762
            self[hook_name].append(a_callable)
 
763
        except KeyError:
 
764
            raise errors.UnknownHook('branch', hook_name)
 
765
 
 
766
 
 
767
# install the default hooks into the Branch class.
 
768
Branch.hooks = BranchHooks()
 
769
 
 
770
 
713
771
class BzrBranchFormat4(BranchFormat):
714
772
    """Bzr branch format 4.
715
773
 
729
787
        utf8_files = [('revision-history', ''),
730
788
                      ('branch-name', ''),
731
789
                      ]
732
 
        control_files = LockableFiles(branch_transport, 'branch-lock',
733
 
                                      TransportLock)
 
790
        control_files = lockable_files.LockableFiles(branch_transport,
 
791
                             'branch-lock', lockable_files.TransportLock)
734
792
        control_files.create_lock()
735
793
        control_files.lock_write()
736
794
        try:
790
848
        utf8_files = [('revision-history', ''),
791
849
                      ('branch-name', ''),
792
850
                      ]
793
 
        control_files = LockableFiles(branch_transport, 'lock', lockdir.LockDir)
 
851
        control_files = lockable_files.LockableFiles(branch_transport, 'lock',
 
852
                                                     lockdir.LockDir)
794
853
        control_files.create_lock()
795
854
        control_files.lock_write()
796
855
        control_files.put_utf8('format', self.get_format_string())
815
874
            format = BranchFormat.find_format(a_bzrdir)
816
875
            assert format.__class__ == self.__class__
817
876
        transport = a_bzrdir.get_branch_transport(None)
818
 
        control_files = LockableFiles(transport, 'lock', lockdir.LockDir)
 
877
        control_files = lockable_files.LockableFiles(transport, 'lock',
 
878
                                                     lockdir.LockDir)
819
879
        return BzrBranch5(_format=self,
820
880
                          _control_files=control_files,
821
881
                          a_bzrdir=a_bzrdir,
1069
1129
    def append_revision(self, *revision_ids):
1070
1130
        """See Branch.append_revision."""
1071
1131
        for revision_id in revision_ids:
 
1132
            _mod_revision.check_not_reserved_id(revision_id)
1072
1133
            mutter("add {%s} to revision-history" % revision_id)
1073
1134
        rev_history = self.revision_history()
1074
1135
        rev_history.extend(revision_ids)
1092
1153
            # this call is disabled because revision_history is 
1093
1154
            # not really an object yet, and the transaction is for objects.
1094
1155
            # transaction.register_clean(history)
 
1156
        for hook in Branch.hooks['set_rh']:
 
1157
            hook(self, rev_history)
1095
1158
 
1096
1159
    @needs_read_lock
1097
1160
    def revision_history(self):
1129
1192
        # make a new revision history from the graph
1130
1193
        current_rev_id = revision_id
1131
1194
        new_history = []
1132
 
        while current_rev_id not in (None, revision.NULL_REVISION):
 
1195
        while current_rev_id not in (None, _mod_revision.NULL_REVISION):
1133
1196
            new_history.append(current_rev_id)
1134
1197
            current_rev_id_parents = stop_graph[current_rev_id]
1135
1198
            try:
1196
1259
        finally:
1197
1260
            source.unlock()
1198
1261
 
 
1262
    @needs_read_lock
 
1263
    def push(self, target, overwrite=False, stop_revision=None):
 
1264
        """See Branch.push."""
 
1265
        target.lock_write()
 
1266
        try:
 
1267
            old_count = len(target.revision_history())
 
1268
            try:
 
1269
                target.update_revisions(self, stop_revision)
 
1270
            except DivergedBranches:
 
1271
                if not overwrite:
 
1272
                    raise
 
1273
            if overwrite:
 
1274
                target.set_revision_history(self.revision_history())
 
1275
            new_count = len(target.revision_history())
 
1276
            return new_count - old_count
 
1277
        finally:
 
1278
            target.unlock()
 
1279
 
1199
1280
    def get_parent(self):
1200
1281
        """See Branch.get_parent."""
1201
1282
 
1223
1304
 
1224
1305
    def set_push_location(self, location):
1225
1306
        """See Branch.set_push_location."""
1226
 
        self.get_config().set_user_option('push_location', location, 
1227
 
                                          local=True)
 
1307
        self.get_config().set_user_option(
 
1308
            'push_location', location,
 
1309
            store=_mod_config.STORE_LOCATION_NORECURSE)
1228
1310
 
1229
1311
    @needs_write_lock
1230
1312
    def set_parent(self, url):
1273
1355
        
1274
1356
    @needs_write_lock
1275
1357
    def pull(self, source, overwrite=False, stop_revision=None):
1276
 
        """Updates branch.pull to be bound branch aware."""
 
1358
        """Extends branch.pull to be bound branch aware."""
1277
1359
        bound_location = self.get_bound_location()
1278
1360
        if source.base != bound_location:
1279
1361
            # not pulling from master, so we need to update master.
1283
1365
                source = master_branch
1284
1366
        return super(BzrBranch5, self).pull(source, overwrite, stop_revision)
1285
1367
 
 
1368
    @needs_write_lock
 
1369
    def push(self, target, overwrite=False, stop_revision=None):
 
1370
        """Updates branch.push to be bound branch aware."""
 
1371
        bound_location = target.get_bound_location()
 
1372
        if target.base != bound_location:
 
1373
            # not pushing to master, so we need to update master.
 
1374
            master_branch = target.get_master_branch()
 
1375
            if master_branch:
 
1376
                # push into the master from this branch.
 
1377
                super(BzrBranch5, self).push(master_branch, overwrite,
 
1378
                    stop_revision)
 
1379
        # and push into the target branch from this. Note that we push from
 
1380
        # this branch again, because its considered the highest bandwidth
 
1381
        # repository.
 
1382
        return super(BzrBranch5, self).push(target, overwrite, stop_revision)
 
1383
 
1286
1384
    def get_bound_location(self):
1287
1385
        try:
1288
1386
            return self.control_files.get_utf8('bound').read()[:-1]
1445
1543
@deprecated_function(zero_eight)
1446
1544
def is_control_file(*args, **kwargs):
1447
1545
    """See bzrlib.workingtree.is_control_file."""
1448
 
    return bzrlib.workingtree.is_control_file(*args, **kwargs)
 
1546
    from bzrlib import workingtree
 
1547
    return workingtree.is_control_file(*args, **kwargs)