~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 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
259
259
        if config is None:
260
260
            config = self.get_config()
261
261
        
262
 
        return self.repository.get_commit_builder(self, parents, config, 
 
262
        return self.repository.get_commit_builder(self, parents, config,
263
263
            timestamp, timezone, committer, revprops, revision_id)
264
264
 
265
265
    def get_master_branch(self):
750
750
        notified.
751
751
        """
752
752
        dict.__init__(self)
 
753
        # Introduced in 0.15:
753
754
        # invoked whenever the revision history has been set
754
755
        # with set_revision_history. The api signature is
755
756
        # (branch, revision_history), and the branch will
756
 
        # be write-locked. Introduced in 0.15.
 
757
        # be write-locked.
757
758
        self['set_rh'] = []
 
759
        # invoked after a push operation completes.
 
760
        # the api signature is
 
761
        # (source, local, master, old_revno, old_revid, new_revno, new_revid)
 
762
        # where local is the local branch or None, master is the target 
 
763
        # master branch, and the rest should be self explanatory. The source
 
764
        # is read locked and the target branches write locked. Source will
 
765
        # be the local low-latency branch.
 
766
        self['post_push'] = []
 
767
        # invoked after a pull operation completes.
 
768
        # the api signature is
 
769
        # (source, local, master, old_revno, old_revid, new_revno, new_revid)
 
770
        # where local is the local branch or None, master is the target 
 
771
        # master branch, and the rest should be self explanatory. The source
 
772
        # is read locked and the target branches write locked. The local
 
773
        # branch is the low-latency branch.
 
774
        self['post_pull'] = []
 
775
        # invoked after a commit operation completes.
 
776
        # the api signature is 
 
777
        # (local, master, old_revno, old_revid, new_revno, new_revid)
 
778
        # old_revid is NULL_REVISION for the first commit to a branch.
 
779
        self['post_commit'] = []
 
780
        # invoked after a uncommit operation completes.
 
781
        # the api signature is
 
782
        # (local, master, old_revno, old_revid, new_revno, new_revid) where
 
783
        # local is the local branch or None, master is the target branch,
 
784
        # and an empty branch recieves new_revno of 0, new_revid of None.
 
785
        self['post_uncommit'] = []
758
786
 
759
787
    def install_hook(self, hook_name, a_callable):
760
788
        """Install a_callable in to the hook hook_name.
1249
1277
        return self.bzrdir.open_workingtree()
1250
1278
 
1251
1279
    @needs_write_lock
1252
 
    def pull(self, source, overwrite=False, stop_revision=None):
1253
 
        """See Branch.pull."""
 
1280
    def pull(self, source, overwrite=False, stop_revision=None,
 
1281
        _hook_master=None, _run_hooks=True):
 
1282
        """See Branch.pull.
 
1283
 
 
1284
        :param _hook_master: Private parameter - set the branch to 
 
1285
            be supplied as the master to push hooks.
 
1286
        :param _run_hooks: Private parameter - allow disabling of
 
1287
            hooks, used when pushing to a master branch.
 
1288
        """
1254
1289
        source.lock_read()
1255
1290
        try:
1256
 
            old_count = self.last_revision_info()[0]
 
1291
            old_count, old_tip = self.last_revision_info()
1257
1292
            try:
1258
1293
                self.update_revisions(source, stop_revision)
1259
1294
            except DivergedBranches:
1261
1296
                    raise
1262
1297
            if overwrite:
1263
1298
                self.set_revision_history(source.revision_history())
1264
 
            new_count = self.last_revision_info()[0]
 
1299
            new_count, new_tip = self.last_revision_info()
 
1300
            if _run_hooks:
 
1301
                if _hook_master:
 
1302
                    _hook_local = self
 
1303
                else:
 
1304
                    _hook_master = self
 
1305
                    _hook_local = None
 
1306
                for hook in Branch.hooks['post_pull']:
 
1307
                    hook(source, _hook_local, _hook_master, old_count, old_tip,
 
1308
                        new_count, new_tip)
1265
1309
            return new_count - old_count
1266
1310
        finally:
1267
1311
            source.unlock()
1268
1312
 
1269
1313
    @needs_read_lock
1270
 
    def push(self, target, overwrite=False, stop_revision=None):
1271
 
        """See Branch.push."""
 
1314
    def push(self, target, overwrite=False, stop_revision=None,
 
1315
        _hook_master=None, _run_hooks=True):
 
1316
        """See Branch.push.
 
1317
        
 
1318
        :param _hook_master: Private parameter - set the branch to 
 
1319
            be supplied as the master to push hooks.
 
1320
        :param _run_hooks: Private parameter - allow disabling of
 
1321
            hooks, used when pushing to a master branch.
 
1322
        """
1272
1323
        target.lock_write()
1273
1324
        try:
1274
 
            old_count = len(target.revision_history())
 
1325
            old_count, old_tip = target.last_revision_info()
1275
1326
            try:
1276
1327
                target.update_revisions(self, stop_revision)
1277
1328
            except DivergedBranches:
1279
1330
                    raise
1280
1331
            if overwrite:
1281
1332
                target.set_revision_history(self.revision_history())
1282
 
            new_count = len(target.revision_history())
 
1333
            new_count, new_tip = target.last_revision_info()
 
1334
            if _run_hooks:
 
1335
                if _hook_master:
 
1336
                    _hook_local = target
 
1337
                else:
 
1338
                    _hook_master = target
 
1339
                    _hook_local = None
 
1340
                for hook in Branch.hooks['post_push']:
 
1341
                    hook(self, _hook_local, _hook_master, old_count, old_tip,
 
1342
                        new_count, new_tip)
1283
1343
            return new_count - old_count
1284
1344
        finally:
1285
1345
            target.unlock()
1361
1421
                                         _repository=_repository)
1362
1422
        
1363
1423
    @needs_write_lock
1364
 
    def pull(self, source, overwrite=False, stop_revision=None):
1365
 
        """Extends branch.pull to be bound branch aware."""
 
1424
    def pull(self, source, overwrite=False, stop_revision=None,
 
1425
        _run_hooks=True):
 
1426
        """Extends branch.pull to be bound branch aware.
 
1427
        
 
1428
        :param _run_hooks: Private parameter used to force hook running
 
1429
            off during bound branch double-pushing.
 
1430
        """
1366
1431
        bound_location = self.get_bound_location()
1367
 
        if source.base != bound_location:
 
1432
        master_branch = None
 
1433
        if bound_location and source.base != bound_location:
1368
1434
            # not pulling from master, so we need to update master.
1369
1435
            master_branch = self.get_master_branch()
1370
 
            if master_branch:
1371
 
                master_branch.pull(source)
1372
 
                source = master_branch
1373
 
        return super(BzrBranch5, self).pull(source, overwrite, stop_revision)
 
1436
            master_branch.lock_write()
 
1437
        try:
 
1438
            if master_branch:
 
1439
                # pull from source into master.
 
1440
                master_branch.pull(source, overwrite, stop_revision,
 
1441
                    _run_hooks=False)
 
1442
            return super(BzrBranch5, self).pull(source, overwrite,
 
1443
                stop_revision, _hook_master=master_branch,
 
1444
                _run_hooks=_run_hooks)
 
1445
        finally:
 
1446
            if master_branch:
 
1447
                master_branch.unlock()
1374
1448
 
1375
1449
    @needs_write_lock
1376
1450
    def push(self, target, overwrite=False, stop_revision=None):
1377
1451
        """Updates branch.push to be bound branch aware."""
1378
1452
        bound_location = target.get_bound_location()
1379
 
        if target.base != bound_location:
 
1453
        master_branch = None
 
1454
        if bound_location and target.base != bound_location:
1380
1455
            # not pushing to master, so we need to update master.
1381
1456
            master_branch = target.get_master_branch()
 
1457
            master_branch.lock_write()
 
1458
        try:
1382
1459
            if master_branch:
1383
1460
                # push into the master from this branch.
1384
1461
                super(BzrBranch5, self).push(master_branch, overwrite,
1385
 
                    stop_revision)
1386
 
        # and push into the target branch from this. Note that we push from
1387
 
        # this branch again, because its considered the highest bandwidth
1388
 
        # repository.
1389
 
        return super(BzrBranch5, self).push(target, overwrite, stop_revision)
 
1462
                    stop_revision, _run_hooks=False)
 
1463
            # and push into the target branch from this. Note that we push from
 
1464
            # this branch again, because its considered the highest bandwidth
 
1465
            # repository.
 
1466
            return super(BzrBranch5, self).push(target, overwrite,
 
1467
                stop_revision, _hook_master=master_branch)
 
1468
        finally:
 
1469
            if master_branch:
 
1470
                master_branch.unlock()
1390
1471
 
1391
1472
    def get_bound_location(self):
1392
1473
        try: