1483
1477
@needs_write_lock
1484
1478
def pull(self, source, overwrite=False, stop_revision=None,
1485
_hook_master=None, run_hooks=True):
1479
_hook_master=None, _run_hooks=True):
1486
1480
"""See Branch.pull.
1488
1482
:param _hook_master: Private parameter - set the branch to
1489
1483
be supplied as the master to push hooks.
1490
:param run_hooks: Private parameter - if false, this branch
1491
is being called because it's the master of the primary branch,
1492
so it should not run its hooks.
1484
:param _run_hooks: Private parameter - allow disabling of
1485
hooks, used when pushing to a master branch.
1494
1487
result = PullResult()
1495
1488
result.source_branch = source
1533
1526
@needs_read_lock
1534
1527
def push(self, target, overwrite=False, stop_revision=None,
1535
_override_hook_source_branch=None):
1528
_hook_master=None, _run_hooks=True):
1536
1529
"""See Branch.push.
1538
This is the basic concrete implementation of push()
1540
:param _override_hook_source_branch: If specified, run
1541
the hooks passing this Branch as the source, rather than self.
1542
This is for use of RemoteBranch, where push is delegated to the
1543
underlying vfs-based Branch.
1545
# TODO: Public option to disable running hooks - should be trivial but
1549
result = self._push_with_bound_branches(target, overwrite,
1551
_override_hook_source_branch=_override_hook_source_branch)
1556
def _push_with_bound_branches(self, target, overwrite,
1558
_override_hook_source_branch=None):
1559
"""Push from self into target, and into target's master if any.
1561
This is on the base BzrBranch class even though it doesn't support
1562
bound branches because the *target* might be bound.
1565
if _override_hook_source_branch:
1566
result.source_branch = _override_hook_source_branch
1567
for hook in Branch.hooks['post_push']:
1570
bound_location = target.get_bound_location()
1571
if bound_location and target.base != bound_location:
1572
# there is a master branch.
1574
# XXX: Why the second check? Is it even supported for a branch to
1575
# be bound to itself? -- mbp 20070507
1576
master_branch = target.get_master_branch()
1577
master_branch.lock_write()
1579
# push into the master from this branch.
1580
self._basic_push(master_branch, overwrite, stop_revision)
1581
# and push into the target branch from this. Note that we push from
1582
# this branch again, because its considered the highest bandwidth
1584
result = self._basic_push(target, overwrite, stop_revision)
1585
result.master_branch = master_branch
1586
result.local_branch = target
1590
master_branch.unlock()
1593
result = self._basic_push(target, overwrite, stop_revision)
1594
# TODO: Why set master_branch and local_branch if there's no
1595
# binding? Maybe cleaner to just leave them unset? -- mbp
1597
result.master_branch = target
1598
result.local_branch = None
1602
def _basic_push(self, target, overwrite, stop_revision):
1603
"""Basic implementation of push without bound branches or hooks.
1605
Must be called with self read locked and target write locked.
1531
:param _hook_master: Private parameter - set the branch to
1532
be supplied as the master to push hooks.
1533
:param _run_hooks: Private parameter - allow disabling of
1534
hooks, used when pushing to a master branch.
1607
1536
result = PushResult()
1608
1537
result.source_branch = self
1609
1538
result.target_branch = target
1610
result.old_revno, result.old_revid = target.last_revision_info()
1612
target.update_revisions(self, stop_revision)
1613
except DivergedBranches:
1617
target.set_revision_history(self.revision_history())
1618
result.tag_conflicts = self.tags.merge_to(target.tags)
1619
result.new_revno, result.new_revid = target.last_revision_info()
1541
result.old_revno, result.old_revid = target.last_revision_info()
1543
target.update_revisions(self, stop_revision)
1544
except DivergedBranches:
1548
target.set_revision_history(self.revision_history())
1549
result.tag_conflicts = self.tags.merge_to(target.tags)
1550
result.new_revno, result.new_revid = target.last_revision_info()
1552
result.master_branch = _hook_master
1553
result.local_branch = target
1555
result.master_branch = target
1556
result.local_branch = None
1558
for hook in Branch.hooks['post_push']:
1622
1564
def get_parent(self):
1693
1635
@needs_write_lock
1694
1636
def pull(self, source, overwrite=False, stop_revision=None,
1696
"""Pull from source into self, updating my master if any.
1638
"""Extends branch.pull to be bound branch aware.
1698
:param run_hooks: Private parameter - if false, this branch
1699
is being called because it's the master of the primary branch,
1700
so it should not run its hooks.
1640
:param _run_hooks: Private parameter used to force hook running
1641
off during bound branch double-pushing.
1702
1643
bound_location = self.get_bound_location()
1703
1644
master_branch = None
1709
1650
if master_branch:
1710
1651
# pull from source into master.
1711
1652
master_branch.pull(source, overwrite, stop_revision,
1713
1654
return super(BzrBranch5, self).pull(source, overwrite,
1714
1655
stop_revision, _hook_master=master_branch,
1715
run_hooks=run_hooks)
1656
_run_hooks=_run_hooks)
1659
master_branch.unlock()
1662
def push(self, target, overwrite=False, stop_revision=None):
1663
"""Updates branch.push to be bound branch aware."""
1664
bound_location = target.get_bound_location()
1665
master_branch = None
1666
if bound_location and target.base != bound_location:
1667
# not pushing to master, so we need to update master.
1668
master_branch = target.get_master_branch()
1669
master_branch.lock_write()
1672
# push into the master from this branch.
1673
super(BzrBranch5, self).push(master_branch, overwrite,
1674
stop_revision, _run_hooks=False)
1675
# and push into the target branch from this. Note that we push from
1676
# this branch again, because its considered the highest bandwidth
1678
return super(BzrBranch5, self).push(target, overwrite,
1679
stop_revision, _hook_master=master_branch)
1717
1681
if master_branch:
1718
1682
master_branch.unlock()
2089
2050
if revision_id is None:
2090
2051
revno, revision_id = self.last_revision_info()
2092
# To figure out the revno for a random revision, we need to build
2093
# the revision history, and count its length.
2094
# We don't care about the order, just how long it is.
2095
# Alternatively, we could start at the current location, and count
2096
# backwards. But there is no guarantee that we will find it since
2097
# it may be a merged revision.
2098
revno = len(list(self.repository.iter_reverse_revision_history(
2053
revno = self.revision_id_to_revno(revision_id)
2100
2054
destination.set_last_revision_info(revno, revision_id)
2102
2056
def _make_tags(self):
2103
2057
return BasicTags(self)
2060
class BranchTestProviderAdapter(object):
2061
"""A tool to generate a suite testing multiple branch formats at once.
2063
This is done by copying the test once for each transport and injecting
2064
the transport_server, transport_readonly_server, and branch_format
2065
classes into each copy. Each copy is also given a new id() to make it
2069
def __init__(self, transport_server, transport_readonly_server, formats,
2070
vfs_transport_factory=None):
2071
self._transport_server = transport_server
2072
self._transport_readonly_server = transport_readonly_server
2073
self._formats = formats
2075
def adapt(self, test):
2076
result = TestSuite()
2077
for branch_format, bzrdir_format in self._formats:
2078
new_test = deepcopy(test)
2079
new_test.transport_server = self._transport_server
2080
new_test.transport_readonly_server = self._transport_readonly_server
2081
new_test.bzrdir_format = bzrdir_format
2082
new_test.branch_format = branch_format
2083
def make_new_test_id():
2084
# the format can be either a class or an instance
2085
name = getattr(branch_format, '__name__',
2086
branch_format.__class__.__name__)
2087
new_id = "%s(%s)" % (new_test.id(), name)
2088
return lambda: new_id
2089
new_test.id = make_new_test_id()
2090
result.addTest(new_test)
2106
2094
######################################################################
2107
2095
# results of operations