47
49
mine = parent.bzrdir.sprout('mine').open_workingtree()
48
50
mine.commit('my change', rev_id='M1', allow_pointless=True)
49
51
other = parent.bzrdir.sprout('other').open_workingtree()
50
self.merge(mine.branch, other)
52
other.merge_from_branch(mine.branch)
51
53
other.commit('merge my change', rev_id='O2')
52
self.merge(other.branch, parent)
54
parent.merge_from_branch(other.branch)
53
55
parent.commit('merge other', rev_id='P2')
54
56
mine.pull(parent.branch)
55
57
self.assertEqual(['P1', 'P2'], mine.branch.revision_history())
59
def test_pull_updates_checkout_and_master(self):
60
"""Pulling into a checkout updates the checkout and the master branch"""
61
master_tree = self.make_branch_and_tree('master')
62
rev1 = master_tree.commit('master')
63
checkout = master_tree.branch.create_checkout('checkout')
65
other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
66
rev2 = other.commit('other commit')
67
# now pull, which should update both checkout and master.
68
checkout.branch.pull(other.branch)
69
self.assertEqual([rev1, rev2], checkout.branch.revision_history())
70
self.assertEqual([rev1, rev2], master_tree.branch.revision_history())
72
def test_pull_raises_specific_error_on_master_connection_error(self):
73
master_tree = self.make_branch_and_tree('master')
74
checkout = master_tree.branch.create_checkout('checkout')
75
other = master_tree.branch.bzrdir.sprout('other').open_workingtree()
76
# move the branch out of the way on disk to cause a connection
78
os.rename('master', 'master_gone')
79
# try to pull, which should raise a BoundBranchConnectionFailure.
80
self.assertRaises(errors.BoundBranchConnectionFailure,
81
checkout.branch.pull, other.branch)
83
def test_pull_overwrite(self):
84
tree_a = self.make_branch_and_tree('tree_a')
85
tree_a.commit('message 1')
86
tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
87
tree_a.commit('message 2', rev_id='rev2a')
88
tree_b.commit('message 2', rev_id='rev2b')
89
self.assertRaises(errors.DivergedBranches, tree_a.pull, tree_b.branch)
90
tree_a.branch.pull(tree_a.branch, overwrite=True,
91
stop_revision='rev2b')
92
self.assertEqual('rev2b', tree_a.branch.last_revision())
93
self.assertEqual(tree_b.branch.revision_history(),
94
tree_a.branch.revision_history())
97
class TestPullHook(TestCaseWithBranch):
101
TestCaseWithBranch.setUp(self)
103
def capture_post_pull_hook(self, result):
104
"""Capture post pull hook calls to self.hook_calls.
106
The call is logged, as is some state of the two branches.
108
if result.local_branch:
109
local_locked = result.local_branch.is_locked()
110
local_base = result.local_branch.base
114
self.hook_calls.append(
115
('post_pull', result.source_branch, local_base,
116
result.master_branch.base, result.old_revno,
118
result.new_revno, result.new_revid,
119
result.source_branch.is_locked(), local_locked,
120
result.master_branch.is_locked()))
122
def test_post_pull_empty_history(self):
123
target = self.make_branch('target')
124
source = self.make_branch('source')
125
Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
127
# with nothing there we should still get a notification, and
128
# have both branches locked at the notification time.
130
('post_pull', source, None, target.base, 0, NULL_REVISION,
131
0, NULL_REVISION, True, None, True)
135
def test_post_pull_bound_branch(self):
136
# pulling to a bound branch should pass in the master branch to the
137
# hook, allowing the correct number of emails to be sent, while still
138
# allowing hooks that want to modify the target to do so to both
140
target = self.make_branch('target')
141
local = self.make_branch('local')
144
except errors.UpgradeRequired:
145
# cant bind this format, the test is irrelevant.
147
source = self.make_branch('source')
148
Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
150
# with nothing there we should still get a notification, and
151
# have both branches locked at the notification time.
153
('post_pull', source, local.base, target.base, 0, NULL_REVISION,
154
0, NULL_REVISION, True, True, True)
158
def test_post_pull_nonempty_history(self):
159
target = self.make_branch_and_memory_tree('target')
162
rev1 = target.commit('rev 1')
164
sourcedir = target.bzrdir.clone(self.get_url('source'))
165
source = MemoryTree.create_on_branch(sourcedir.open_branch())
166
rev2 = source.commit('rev 2')
167
Branch.hooks.install_hook('post_pull', self.capture_post_pull_hook)
168
target.branch.pull(source.branch)
169
# with nothing there we should still get a notification, and
170
# have both branches locked at the notification time.
172
('post_pull', source.branch, None, target.branch.base, 1, rev1,
173
2, rev2, True, None, True)