23
24
from bzrlib.branch import Branch
24
from bzrlib.directory_service import directories
25
from bzrlib.osutils import pathjoin
25
from bzrlib.osutils import abspath
26
26
from bzrlib.tests.blackbox import ExternalBase
27
27
from bzrlib.uncommit import uncommit
28
from bzrlib.workingtree import WorkingTree
29
from bzrlib import urlutils
32
30
class TestPull(ExternalBase):
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')
32
def example_branch(test):
34
file('hello', 'wt').write('foo')
35
test.runbzr('add hello')
36
test.runbzr('commit -m setup hello')
37
file('goodbye', 'wt').write('baz')
38
test.runbzr('add goodbye')
39
test.runbzr('commit -m setup goodbye')
45
41
def test_pull(self):
46
42
"""Pull changes from one branch to another."""
47
a_tree = self.example_branch('a')
49
self.run_bzr('pull', retcode=3)
50
self.run_bzr('missing', retcode=3)
51
self.run_bzr('missing .')
52
self.run_bzr('missing')
47
self.runbzr('pull', retcode=3)
48
self.runbzr('missing', retcode=3)
49
self.runbzr('missing .')
50
self.runbzr('missing')
53
51
# this will work on windows because we check for the same branch
54
52
# in pull - if it fails, it is a regression
56
self.run_bzr('pull /', retcode=3)
54
self.runbzr('pull /', retcode=3)
57
55
if sys.platform not in ('win32', 'cygwin'):
61
b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
59
self.runbzr('branch a b')
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)
63
self.runbzr('add subdir')
64
self.runbzr('commit -m blah --unchanged')
67
b = Branch.open('../b')
68
self.assertEquals(a.revision_history(), b.revision_history()[:-1])
69
self.runbzr('pull ../b')
70
self.assertEquals(a.revision_history(), b.revision_history())
71
self.runbzr('commit -m blah2 --unchanged')
73
self.runbzr('commit -m blah3 --unchanged')
80
self.run_bzr('pull ../a', retcode=3)
75
self.runbzr('pull ../a', retcode=3)
82
b_tree.bzrdir.sprout('overwriteme')
77
self.runbzr('branch b overwriteme')
83
78
os.chdir('overwriteme')
84
self.run_bzr('pull --overwrite ../a')
79
self.runbzr('pull --overwrite ../a')
85
80
overwritten = Branch.open('.')
86
81
self.assertEqual(overwritten.revision_history(),
87
82
a.revision_history())
88
a_tree.merge_from_branch(b_tree.branch)
89
a_tree.commit(message="blah4", allow_pointless=True)
84
self.runbzr('merge ../b')
85
self.runbzr('commit -m blah4 --unchanged')
90
86
os.chdir('../b/subdir')
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)
87
self.runbzr('pull ../../a')
88
self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
89
self.runbzr('commit -m blah5 --unchanged')
90
self.runbzr('commit -m blah6 --unchanged')
97
self.run_bzr('pull ../a')
92
self.runbzr('pull ../a')
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'])
94
self.runbzr('commit -m blah7 --unchanged')
95
self.runbzr('merge ../b')
96
self.runbzr('commit -m blah8 --unchanged')
97
self.runbzr('pull ../b')
98
self.runbzr('pull ../b')
116
100
def test_pull_revision(self):
117
101
"""Pull some changes from one branch to another."""
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()
105
self.example_branch()
106
file('hello2', 'wt').write('foo')
107
self.runbzr('add hello2')
108
self.runbzr('commit -m setup hello2')
109
file('goodbye2', 'wt').write('baz')
110
self.runbzr('add goodbye2')
111
self.runbzr('commit -m setup goodbye2')
114
self.runbzr('branch -r 1 a b')
130
self.run_bzr('pull -r 2')
116
self.runbzr('pull -r 2')
131
117
a = Branch.open('../a')
132
118
b = Branch.open('.')
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())
119
self.assertEquals(a.revno(),4)
120
self.assertEquals(b.revno(),2)
121
self.runbzr('pull -r 3')
122
self.assertEquals(b.revno(),3)
123
self.runbzr('pull -r 4')
124
self.assertEquals(a.revision_history(), b.revision_history())
141
127
def test_overwrite_uptodate(self):
142
128
# Make sure pull --overwrite overwrites
143
129
# even if the target branch has merged
144
130
# everything already.
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)
133
def get_rh(expected_len):
134
rh = self.capture('revision-history')
135
# Make sure we don't have trailing empty revisions
136
rh = rh.strip().split('\n')
137
self.assertEqual(len(rh), expected_len)
143
open('foo', 'wb').write('original\n')
145
bzr('commit', '-m', 'initial commit')
148
bzr('branch', 'a', 'b')
151
open('foo', 'wb').write('changed\n')
152
bzr('commit', '-m', 'later change')
154
open('foo', 'wb').write('another\n')
155
bzr('commit', '-m', 'a third change')
157
rev_history_a = get_rh(3)
161
bzr('commit', '-m', 'merge')
163
rev_history_b = get_rh(2)
165
bzr('pull', '--overwrite', '../a')
166
rev_history_b = get_rh(3)
171
168
self.assertEqual(rev_history_b, rev_history_a)
173
170
def test_overwrite_children(self):
174
171
# Make sure pull --overwrite sets the revision-history
175
172
# to be identical to the pull source, even if we have convergence
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)
175
def get_rh(expected_len):
176
rh = self.capture('revision-history')
177
# Make sure we don't have trailing empty revisions
178
rh = rh.strip().split('\n')
179
self.assertEqual(len(rh), expected_len)
185
open('foo', 'wb').write('original\n')
187
bzr('commit', '-m', 'initial commit')
190
bzr('branch', 'a', 'b')
193
open('foo', 'wb').write('changed\n')
194
bzr('commit', '-m', 'later change')
196
open('foo', 'wb').write('another\n')
197
bzr('commit', '-m', 'a third change')
199
rev_history_a = get_rh(3)
203
bzr('commit', '-m', 'merge')
205
rev_history_b = get_rh(2)
208
open('foo', 'wb').write('a fourth change\n')
209
bzr('commit', '-m', 'a fourth change')
211
rev_history_a = get_rh(4)
202
213
# With convergence, we could just pull over the
203
214
# new change, but with --overwrite, we want to switch our history
205
self.run_bzr('pull --overwrite ../a')
206
rev_history_b = b_tree.branch.revision_history()
207
self.assertEqual(len(rev_history_b), 4)
216
bzr('pull', '--overwrite', '../a')
217
rev_history_b = get_rh(4)
209
219
self.assertEqual(rev_history_b, rev_history_a)
229
239
self.assertEqual(None, branch_b.get_parent())
230
240
# test pull for failure without parent set
231
241
os.chdir('branch_b')
232
out = self.run_bzr('pull', retcode=3)
233
self.assertEqual(out,
242
out = self.runbzr('pull', retcode=3)
243
self.assertEquals(out,
234
244
('','bzr: ERROR: No pull location known or specified.\n'))
235
245
# test implicit --remember when no parent set, this pull conflicts
236
246
self.build_tree(['d'])
238
248
tree_b.commit('commit d')
239
out = self.run_bzr('pull ../branch_a', retcode=3)
240
self.assertEqual(out,
241
('','bzr: ERROR: These branches have diverged.'
242
' Use the merge command to reconcile them.\n'))
243
self.assertEqual(branch_b.get_parent(), parent)
249
out = self.runbzr('pull ../branch_a', retcode=3)
250
self.assertEquals(out,
251
('','bzr: ERROR: These branches have diverged. Try merge.\n'))
252
self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
244
253
# test implicit --remember after resolving previous failure
245
254
uncommit(branch=branch_b, tree=tree_b)
246
255
transport.delete('branch_b/d')
248
self.assertEqual(branch_b.get_parent(), parent)
257
self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
249
258
# test explicit --remember
250
self.run_bzr('pull ../branch_c --remember')
251
self.assertEqual(branch_b.get_parent(),
252
branch_c.bzrdir.root_transport.base)
254
def test_pull_bundle(self):
255
from bzrlib.testament import Testament
256
# Build up 2 trees and prepare for a pull
257
tree_a = self.make_branch_and_tree('branch_a')
258
f = open('branch_a/a', 'wb')
262
tree_a.commit('message')
264
tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
266
# Make a change to 'a' that 'b' can pull
267
f = open('branch_a/a', 'wb')
270
tree_a.commit('message')
272
# Create the bundle for 'b' to pull
274
self.run_bzr('bundle ../branch_b -o ../bundle')
276
os.chdir('../branch_b')
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')
283
self.assertEqualDiff(tree_a.branch.revision_history(),
284
tree_b.branch.revision_history())
286
testament_a = Testament.from_revision(tree_a.branch.repository,
287
tree_a.get_parent_ids()[0])
288
testament_b = Testament.from_revision(tree_b.branch.repository,
289
tree_b.get_parent_ids()[0])
290
self.assertEqualDiff(testament_a.as_text(),
291
testament_b.as_text())
293
# it is legal to attempt to pull an already-merged bundle
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())
259
self.runbzr('pull ../branch_c --remember')
260
self.assertEquals(abspath(branch_b.get_parent()),
261
abspath(branch_c.bzrdir.root_transport.base))