24
23
from bzrlib.branch import Branch
24
from bzrlib.directory_service import directories
25
from bzrlib.osutils import pathjoin
25
26
from bzrlib.tests.blackbox import ExternalBase
26
27
from bzrlib.uncommit import uncommit
28
from bzrlib.workingtree import WorkingTree
29
from bzrlib import urlutils
29
32
class TestPull(ExternalBase):
31
def example_branch(test):
33
file('hello', 'wt').write('foo')
34
test.runbzr('add hello')
35
test.runbzr('commit -m setup hello')
36
file('goodbye', 'wt').write('baz')
37
test.runbzr('add goodbye')
38
test.runbzr('commit -m setup goodbye')
34
def example_branch(self, path='.'):
35
tree = self.make_branch_and_tree(path)
36
self.build_tree_contents([
37
(pathjoin(path, 'hello'), 'foo'),
38
(pathjoin(path, 'goodbye'), 'baz')])
40
tree.commit(message='setup')
42
tree.commit(message='setup')
40
45
def test_pull(self):
41
46
"""Pull changes from one branch to another."""
47
a_tree = self.example_branch('a')
46
self.runbzr('pull', retcode=3)
47
self.runbzr('missing', retcode=3)
48
self.runbzr('missing .')
49
self.runbzr('missing')
49
self.run_bzr('pull', retcode=3)
50
self.run_bzr('missing', retcode=3)
51
self.run_bzr('missing .')
52
self.run_bzr('missing')
50
53
# this will work on windows because we check for the same branch
51
54
# in pull - if it fails, it is a regression
53
self.runbzr('pull /', retcode=3)
56
self.run_bzr('pull /', retcode=3)
54
57
if sys.platform not in ('win32', 'cygwin'):
58
self.runbzr('branch a b')
61
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
62
self.runbzr('add subdir')
63
self.runbzr('commit -m blah --unchanged')
66
b = Branch.open('../b')
67
self.assertEquals(a.revision_history(), b.revision_history()[:-1])
68
self.runbzr('pull ../b')
69
self.assertEquals(a.revision_history(), b.revision_history())
70
self.runbzr('commit -m blah2 --unchanged')
72
self.runbzr('commit -m blah3 --unchanged')
66
b_tree.commit(message='blah', allow_pointless=True)
71
self.assertEqual(a.revision_history(), b.revision_history()[:-1])
74
self.run_bzr('pull ../b')
75
self.assertEqual(a.revision_history(), b.revision_history())
76
a_tree.commit(message='blah2', allow_pointless=True)
77
b_tree.commit(message='blah3', allow_pointless=True)
74
self.runbzr('pull ../a', retcode=3)
80
self.run_bzr('pull ../a', retcode=3)
76
self.runbzr('branch b overwriteme')
82
b_tree.bzrdir.sprout('overwriteme')
77
83
os.chdir('overwriteme')
78
self.runbzr('pull --overwrite ../a')
84
self.run_bzr('pull --overwrite ../a')
79
85
overwritten = Branch.open('.')
80
86
self.assertEqual(overwritten.revision_history(),
81
87
a.revision_history())
83
self.runbzr('merge ../b')
84
self.runbzr('commit -m blah4 --unchanged')
88
a_tree.merge_from_branch(b_tree.branch)
89
a_tree.commit(message="blah4", allow_pointless=True)
85
90
os.chdir('../b/subdir')
86
self.runbzr('pull ../../a')
87
self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
88
self.runbzr('commit -m blah5 --unchanged')
89
self.runbzr('commit -m blah6 --unchanged')
91
self.run_bzr('pull ../../a')
92
self.assertEqual(a.revision_history()[-1], b.revision_history()[-1])
93
sub_tree = WorkingTree.open_containing('.')[0]
94
sub_tree.commit(message="blah5", allow_pointless=True)
95
sub_tree.commit(message="blah6", allow_pointless=True)
91
self.runbzr('pull ../a')
97
self.run_bzr('pull ../a')
93
self.runbzr('commit -m blah7 --unchanged')
94
self.runbzr('merge ../b')
95
self.runbzr('commit -m blah8 --unchanged')
96
self.runbzr('pull ../b')
97
self.runbzr('pull ../b')
99
a_tree.commit(message="blah7", allow_pointless=True)
100
a_tree.merge_from_branch(b_tree.branch)
101
a_tree.commit(message="blah8", allow_pointless=True)
102
self.run_bzr('pull ../b')
103
self.run_bzr('pull ../b')
105
def test_pull_dash_d(self):
106
self.example_branch('a')
107
self.make_branch_and_tree('b')
108
self.make_branch_and_tree('c')
109
# pull into that branch
110
self.run_bzr('pull -d b a')
111
# pull into a branch specified by a url
112
c_url = urlutils.local_path_to_url('c')
113
self.assertStartsWith(c_url, 'file://')
114
self.run_bzr(['pull', '-d', c_url, 'a'])
99
116
def test_pull_revision(self):
100
117
"""Pull some changes from one branch to another."""
104
self.example_branch()
105
file('hello2', 'wt').write('foo')
106
self.runbzr('add hello2')
107
self.runbzr('commit -m setup hello2')
108
file('goodbye2', 'wt').write('baz')
109
self.runbzr('add goodbye2')
110
self.runbzr('commit -m setup goodbye2')
113
self.runbzr('branch -r 1 a b')
118
a_tree = self.example_branch('a')
119
self.build_tree_contents([
121
('a/goodbye2', 'baz')])
123
a_tree.commit(message="setup")
124
a_tree.add('goodbye2')
125
a_tree.commit(message="setup")
127
b_tree = a_tree.bzrdir.sprout('b',
128
revision_id=a_tree.branch.get_rev_id(1)).open_workingtree()
115
self.runbzr('pull -r 2')
130
self.run_bzr('pull -r 2')
116
131
a = Branch.open('../a')
117
132
b = Branch.open('.')
118
self.assertEquals(a.revno(),4)
119
self.assertEquals(b.revno(),2)
120
self.runbzr('pull -r 3')
121
self.assertEquals(b.revno(),3)
122
self.runbzr('pull -r 4')
123
self.assertEquals(a.revision_history(), b.revision_history())
133
self.assertEqual(a.revno(),4)
134
self.assertEqual(b.revno(),2)
135
self.run_bzr('pull -r 3')
136
self.assertEqual(b.revno(),3)
137
self.run_bzr('pull -r 4')
138
self.assertEqual(a.revision_history(), b.revision_history())
126
141
def test_overwrite_uptodate(self):
127
142
# Make sure pull --overwrite overwrites
128
143
# even if the target branch has merged
129
144
# everything already.
132
def get_rh(expected_len):
133
rh = self.capture('revision-history')
134
# Make sure we don't have trailing empty revisions
135
rh = rh.strip().split('\n')
136
self.assertEqual(len(rh), expected_len)
142
open('foo', 'wb').write('original\n')
144
bzr('commit', '-m', 'initial commit')
147
bzr('branch', 'a', 'b')
150
open('foo', 'wb').write('changed\n')
151
bzr('commit', '-m', 'later change')
153
open('foo', 'wb').write('another\n')
154
bzr('commit', '-m', 'a third change')
156
rev_history_a = get_rh(3)
160
bzr('commit', '-m', 'merge')
162
rev_history_b = get_rh(2)
164
bzr('pull', '--overwrite', '../a')
165
rev_history_b = get_rh(3)
145
a_tree = self.make_branch_and_tree('a')
146
self.build_tree_contents([('a/foo', 'original\n')])
148
a_tree.commit(message='initial commit')
150
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
152
self.build_tree_contents([('a/foo', 'changed\n')])
153
a_tree.commit(message='later change')
155
self.build_tree_contents([('a/foo', 'a third change')])
156
a_tree.commit(message='a third change')
158
rev_history_a = a_tree.branch.revision_history()
159
self.assertEqual(len(rev_history_a), 3)
161
b_tree.merge_from_branch(a_tree.branch)
162
b_tree.commit(message='merge')
164
self.assertEqual(len(b_tree.branch.revision_history()), 2)
167
self.run_bzr('pull --overwrite ../a')
168
rev_history_b = b_tree.branch.revision_history()
169
self.assertEqual(len(rev_history_b), 3)
167
171
self.assertEqual(rev_history_b, rev_history_a)
169
173
def test_overwrite_children(self):
170
174
# Make sure pull --overwrite sets the revision-history
171
175
# to be identical to the pull source, even if we have convergence
174
def get_rh(expected_len):
175
rh = self.capture('revision-history')
176
# Make sure we don't have trailing empty revisions
177
rh = rh.strip().split('\n')
178
self.assertEqual(len(rh), expected_len)
184
open('foo', 'wb').write('original\n')
186
bzr('commit', '-m', 'initial commit')
189
bzr('branch', 'a', 'b')
192
open('foo', 'wb').write('changed\n')
193
bzr('commit', '-m', 'later change')
195
open('foo', 'wb').write('another\n')
196
bzr('commit', '-m', 'a third change')
198
rev_history_a = get_rh(3)
202
bzr('commit', '-m', 'merge')
204
rev_history_b = get_rh(2)
207
open('foo', 'wb').write('a fourth change\n')
208
bzr('commit', '-m', 'a fourth change')
210
rev_history_a = get_rh(4)
176
a_tree = self.make_branch_and_tree('a')
177
self.build_tree_contents([('a/foo', 'original\n')])
179
a_tree.commit(message='initial commit')
181
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
183
self.build_tree_contents([('a/foo', 'changed\n')])
184
a_tree.commit(message='later change')
186
self.build_tree_contents([('a/foo', 'a third change')])
187
a_tree.commit(message='a third change')
189
self.assertEqual(len(a_tree.branch.revision_history()), 3)
191
b_tree.merge_from_branch(a_tree.branch)
192
b_tree.commit(message='merge')
194
self.assertEqual(len(b_tree.branch.revision_history()), 2)
196
self.build_tree_contents([('a/foo', 'a fourth change\n')])
197
a_tree.commit(message='a fourth change')
199
rev_history_a = a_tree.branch.revision_history()
200
self.assertEqual(len(rev_history_a), 4)
212
202
# With convergence, we could just pull over the
213
203
# new change, but with --overwrite, we want to switch our history
215
bzr('pull', '--overwrite', '../a')
216
rev_history_b = get_rh(4)
205
self.run_bzr('pull --overwrite ../a')
206
rev_history_b = b_tree.branch.revision_history()
207
self.assertEqual(len(rev_history_b), 4)
218
209
self.assertEqual(rev_history_b, rev_history_a)
280
272
# Create the bundle for 'b' to pull
281
273
os.chdir('branch_a')
282
bundle_file = open('../bundle', 'wb')
283
bundle_file.write(self.run_bzr('bundle', '../branch_b')[0])
274
self.run_bzr('bundle ../branch_b -o ../bundle')
286
276
os.chdir('../branch_b')
287
output = self.run_bzr('pull', '../bundle')
288
self.assertEqual('', output[0])
289
self.assertEqual('All changes applied successfully.\n'
290
'1 revision(s) pulled.\n', output[1])
277
out, err = self.run_bzr('pull ../bundle')
278
self.assertEqual(out,
279
'Now on revision 2.\n')
280
self.assertEqual(err,
281
' M a\nAll changes applied successfully.\n')
292
283
self.assertEqualDiff(tree_a.branch.revision_history(),
293
284
tree_b.branch.revision_history())
295
testament_a = Testament.from_revision(tree_a.branch.repository,
296
tree_a.last_revision())
286
testament_a = Testament.from_revision(tree_a.branch.repository,
287
tree_a.get_parent_ids()[0])
297
288
testament_b = Testament.from_revision(tree_b.branch.repository,
298
tree_b.last_revision())
289
tree_b.get_parent_ids()[0])
299
290
self.assertEqualDiff(testament_a.as_text(),
300
291
testament_b.as_text())
302
293
# it is legal to attempt to pull an already-merged bundle
303
output = self.run_bzr('pull', '../bundle')
304
self.assertEqual('', output[0])
305
self.assertEqual('0 revision(s) pulled.\n', output[1])
294
out, err = self.run_bzr('pull ../bundle')
295
self.assertEqual(err, '')
296
self.assertEqual(out, 'No revisions to pull.\n')
298
def test_pull_verbose_no_files(self):
299
"""Pull --verbose should not list modified files"""
300
tree_a = self.make_branch_and_tree('tree_a')
301
self.build_tree(['tree_a/foo'])
304
tree_b = self.make_branch_and_tree('tree_b')
305
out = self.run_bzr('pull --verbose -d tree_b tree_a')[0]
306
self.assertContainsRe(out, 'bar')
307
self.assertNotContainsRe(out, 'added:')
308
self.assertNotContainsRe(out, 'foo')
310
def test_pull_quiet(self):
311
"""Check that bzr pull --quiet does not print anything"""
312
tree_a = self.make_branch_and_tree('tree_a')
313
self.build_tree(['tree_a/foo'])
315
revision_id = tree_a.commit('bar')
316
tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
317
out, err = self.run_bzr('pull --quiet -d tree_b')
318
self.assertEqual(out, '')
319
self.assertEqual(err, '')
320
self.assertEqual(tree_b.last_revision(), revision_id)
321
self.build_tree(['tree_a/moo'])
323
revision_id = tree_a.commit('quack')
324
out, err = self.run_bzr('pull --quiet -d tree_b')
325
self.assertEqual(out, '')
326
self.assertEqual(err, '')
327
self.assertEqual(tree_b.last_revision(), revision_id)
329
def test_pull_from_directory_service(self):
330
source = self.make_branch_and_tree('source')
331
source.commit('commit 1')
332
target = source.bzrdir.sprout('target').open_workingtree()
333
source_last = source.commit('commit 2')
334
class FooService(object):
335
"""A directory service that always returns source"""
337
def look_up(self, name, url):
339
directories.register('foo:', FooService, 'Testing directory service')
340
self.addCleanup(lambda: directories.remove('foo:'))
341
self.run_bzr('pull foo:bar -d target')
342
self.assertEqual(source_last, target.last_revision())