1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
1
# Copyright (C) 2005 by Canonical Ltd
2
# -*- coding: utf-8 -*-
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
5
6
# the Free Software Foundation; either version 2 of the License, or
6
7
# (at your option) any later version.
8
9
# This program is distributed in the hope that it will be useful,
9
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
12
# GNU General Public License for more details.
13
14
# You should have received a copy of the GNU General Public License
14
15
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
"""Black-box tests for brz pull."""
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
"""Black-box tests for bzr pull."""
32
from breezy.bzr import (
36
from breezy.directory_service import directories
37
from breezy.tests import (
43
class TestPull(tests.TestCaseWithTransport):
45
def example_branch(self, path='.'):
46
tree = self.make_branch_and_tree(path)
47
self.build_tree_contents([
48
(osutils.pathjoin(path, 'hello'), b'foo'),
49
(osutils.pathjoin(path, 'goodbye'), b'baz')])
51
tree.commit(message='setup')
53
tree.commit(message='setup')
24
from bzrlib.branch import Branch
25
from bzrlib.osutils import abspath
26
from bzrlib.tests.blackbox import ExternalBase
27
from bzrlib.uncommit import uncommit
30
class TestPull(ExternalBase):
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')
56
41
def test_pull(self):
57
42
"""Pull changes from one branch to another."""
58
a_tree = self.example_branch('a')
59
base_rev = a_tree.branch.last_revision()
60
self.run_bzr('pull', retcode=3, working_dir='a')
61
self.run_bzr('missing', retcode=3, working_dir='a')
62
self.run_bzr('missing .', working_dir='a')
63
self.run_bzr('missing', working_dir='a')
47
self.runbzr('pull', retcode=3)
48
self.runbzr('missing', retcode=3)
49
self.runbzr('missing .')
50
self.runbzr('missing')
64
51
# this will work on windows because we check for the same branch
65
52
# in pull - if it fails, it is a regression
66
self.run_bzr('pull', working_dir='a')
67
self.run_bzr('pull /', retcode=3, working_dir='a')
54
self.runbzr('pull /', retcode=3)
68
55
if sys.platform not in ('win32', 'cygwin'):
69
self.run_bzr('pull', working_dir='a')
71
b_tree = a_tree.controldir.sprout('b').open_workingtree()
72
self.run_bzr('pull', working_dir='b')
75
new_rev = b_tree.commit(message='blah', allow_pointless=True)
77
a = branch.Branch.open('a')
78
b = branch.Branch.open('b')
79
self.assertEqual(a.last_revision(), base_rev)
80
self.assertEqual(b.last_revision(), new_rev)
82
self.run_bzr('pull ../b', working_dir='a')
83
self.assertEqual(a.last_revision(), b.last_revision())
84
a_tree.commit(message='blah2', allow_pointless=True)
85
b_tree.commit(message='blah3', allow_pointless=True)
59
self.runbzr('branch a b')
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')
87
self.run_bzr('pull ../a', retcode=3, working_dir='b')
88
b_tree.controldir.sprout('overwriteme')
89
self.run_bzr('pull --overwrite ../a', working_dir='overwriteme')
90
overwritten = branch.Branch.open('overwriteme')
91
self.assertEqual(overwritten.last_revision(),
93
a_tree.merge_from_branch(b_tree.branch)
94
a_tree.commit(message="blah4", allow_pointless=True)
96
self.run_bzr('pull ../../a', working_dir='b/subdir')
97
self.assertEqual(a.last_revision(), b.last_revision())
98
sub_tree = workingtree.WorkingTree.open_containing('b/subdir')[0]
99
sub_tree.commit(message="blah5", allow_pointless=True)
100
sub_tree.commit(message="blah6", allow_pointless=True)
101
self.run_bzr('pull ../a', working_dir='b')
102
a_tree.commit(message="blah7", allow_pointless=True)
103
a_tree.merge_from_branch(b_tree.branch)
104
a_tree.commit(message="blah8", allow_pointless=True)
105
self.run_bzr('pull ../b', working_dir='a')
106
self.run_bzr('pull ../b', working_dir='a')
108
def test_pull_dash_d(self):
109
self.example_branch('a')
110
self.make_branch_and_tree('b')
111
self.make_branch_and_tree('c')
112
# pull into that branch
113
self.run_bzr('pull -d b a')
114
# pull into a branch specified by a url
115
c_url = urlutils.local_path_to_url('c')
116
self.assertStartsWith(c_url, 'file://')
117
self.run_bzr(['pull', '-d', c_url, 'a'])
75
self.runbzr('pull ../a', retcode=3)
77
self.runbzr('branch b overwriteme')
78
os.chdir('overwriteme')
79
self.runbzr('pull --overwrite ../a')
80
overwritten = Branch.open('.')
81
self.assertEqual(overwritten.revision_history(),
84
self.runbzr('merge ../b')
85
self.runbzr('commit -m blah4 --unchanged')
86
os.chdir('../b/subdir')
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')
92
self.runbzr('pull ../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')
119
100
def test_pull_revision(self):
120
101
"""Pull some changes from one branch to another."""
121
a_tree = self.example_branch('a')
122
self.build_tree_contents([
123
('a/hello2', b'foo'),
124
('a/goodbye2', b'baz')])
126
a_tree.commit(message="setup")
127
a_tree.add('goodbye2')
128
a_tree.commit(message="setup")
130
b_tree = a_tree.controldir.sprout(
131
'b', revision_id=a_tree.branch.get_rev_id(1)).open_workingtree()
132
self.run_bzr('pull -r 2', working_dir='b')
133
a = branch.Branch.open('a')
134
b = branch.Branch.open('b')
135
self.assertEqual(a.revno(), 4)
136
self.assertEqual(b.revno(), 2)
137
self.run_bzr('pull -r 3', working_dir='b')
138
self.assertEqual(b.revno(), 3)
139
self.run_bzr('pull -r 4', working_dir='b')
140
self.assertEqual(a.last_revision(), b.last_revision())
142
def test_pull_tags(self):
143
"""Tags are updated by pull, and revisions named in those tags are
146
# Make a source, sprout a target off it
147
builder = self.make_branch_builder('source')
148
source, rev1, rev2 = fixtures.build_branch_with_non_ancestral_rev(
150
source.get_config_stack().set('branch.fetch_tags', True)
151
target_bzrdir = source.controldir.sprout('target')
152
source.tags.set_tag('tag-a', rev2)
154
self.run_bzr('pull -d target source')
155
target = target_bzrdir.open_branch()
156
# The tag is present, and so is its revision.
157
self.assertEqual(rev2, target.tags.lookup_tag('tag-a'))
158
target.repository.get_revision(rev2)
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')
116
self.runbzr('pull -r 2')
117
a = Branch.open('../a')
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())
160
127
def test_overwrite_uptodate(self):
161
128
# Make sure pull --overwrite overwrites
162
129
# even if the target branch has merged
163
130
# everything already.
164
a_tree = self.make_branch_and_tree('a')
165
self.build_tree_contents([('a/foo', b'original\n')])
167
a_tree.commit(message='initial commit')
169
b_tree = a_tree.controldir.sprout('b').open_workingtree()
171
self.build_tree_contents([('a/foo', b'changed\n')])
172
a_tree.commit(message='later change')
174
self.build_tree_contents([('a/foo', b'a third change')])
175
a_tree.commit(message='a third change')
177
self.assertEqual(a_tree.branch.last_revision_info()[0], 3)
179
b_tree.merge_from_branch(a_tree.branch)
180
b_tree.commit(message='merge')
182
self.assertEqual(b_tree.branch.last_revision_info()[0], 2)
184
self.run_bzr('pull --overwrite ../a', working_dir='b')
185
(last_revinfo_b) = b_tree.branch.last_revision_info()
186
self.assertEqual(last_revinfo_b[0], 3)
187
self.assertEqual(last_revinfo_b[1], a_tree.branch.last_revision())
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)
168
self.assertEqual(rev_history_b, rev_history_a)
189
170
def test_overwrite_children(self):
190
171
# Make sure pull --overwrite sets the revision-history
191
172
# to be identical to the pull source, even if we have convergence
192
a_tree = self.make_branch_and_tree('a')
193
self.build_tree_contents([('a/foo', b'original\n')])
195
a_tree.commit(message='initial commit')
197
b_tree = a_tree.controldir.sprout('b').open_workingtree()
199
self.build_tree_contents([('a/foo', b'changed\n')])
200
a_tree.commit(message='later change')
202
self.build_tree_contents([('a/foo', b'a third change')])
203
a_tree.commit(message='a third change')
205
self.assertEqual(a_tree.branch.last_revision_info()[0], 3)
207
b_tree.merge_from_branch(a_tree.branch)
208
b_tree.commit(message='merge')
210
self.assertEqual(b_tree.branch.last_revision_info()[0], 2)
212
self.build_tree_contents([('a/foo', b'a fourth change\n')])
213
a_tree.commit(message='a fourth change')
215
rev_info_a = a_tree.branch.last_revision_info()
216
self.assertEqual(rev_info_a[0], 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)
218
213
# With convergence, we could just pull over the
219
214
# new change, but with --overwrite, we want to switch our history
220
self.run_bzr('pull --overwrite ../a', working_dir='b')
221
rev_info_b = b_tree.branch.last_revision_info()
222
self.assertEqual(rev_info_b[0], 4)
223
self.assertEqual(rev_info_b, rev_info_a)
216
bzr('pull', '--overwrite', '../a')
217
rev_history_b = get_rh(4)
219
self.assertEqual(rev_history_b, rev_history_a)
225
221
def test_pull_remember(self):
226
222
"""Pull changes from one branch to another and test parent location."""
227
t = self.get_transport()
223
transport = self.get_transport()
228
224
tree_a = self.make_branch_and_tree('branch_a')
229
225
branch_a = tree_a.branch
230
226
self.build_tree(['branch_a/a'])
232
228
tree_a.commit('commit a')
233
tree_b = branch_a.controldir.sprout('branch_b').open_workingtree()
229
tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
234
230
branch_b = tree_b.branch
235
tree_c = branch_a.controldir.sprout('branch_c').open_workingtree()
231
tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
236
232
branch_c = tree_c.branch
237
233
self.build_tree(['branch_a/b'])
239
235
tree_a.commit('commit b')
241
237
parent = branch_b.get_parent()
242
branch_b = branch.Branch.open('branch_b')
243
238
branch_b.set_parent(None)
244
239
self.assertEqual(None, branch_b.get_parent())
245
240
# test pull for failure without parent set
246
out = self.run_bzr('pull', retcode=3, working_dir='branch_b')
247
self.assertEqual(out,
248
('', 'brz: ERROR: No pull location known or specified.\n'))
242
out = self.runbzr('pull', retcode=3)
243
self.assertEquals(out,
244
('','bzr: ERROR: No pull location known or specified.\n'))
249
245
# test implicit --remember when no parent set, this pull conflicts
250
self.build_tree(['branch_b/d'])
246
self.build_tree(['d'])
252
248
tree_b.commit('commit d')
253
out = self.run_bzr('pull ../branch_a', retcode=3,
254
working_dir='branch_b')
255
self.assertEqual(out,
256
('', 'brz: ERROR: These branches have diverged.'
257
' Use the missing command to see how.\n'
258
'Use the merge command to reconcile them.\n'))
259
tree_b = tree_b.controldir.open_workingtree()
260
branch_b = tree_b.branch
261
self.assertEqual(parent, branch_b.get_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))
262
253
# test implicit --remember after resolving previous failure
263
uncommit.uncommit(branch=branch_b, tree=tree_b)
264
t.delete('branch_b/d')
265
self.run_bzr('pull', working_dir='branch_b')
266
# Refresh the branch object as 'pull' modified it
267
branch_b = branch_b.controldir.open_branch()
268
self.assertEqual(branch_b.get_parent(), parent)
254
uncommit(branch=branch_b, tree=tree_b)
255
transport.delete('branch_b/d')
257
self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
269
258
# test explicit --remember
270
self.run_bzr('pull ../branch_c --remember', working_dir='branch_b')
271
# Refresh the branch object as 'pull' modified it
272
branch_b = branch_b.controldir.open_branch()
273
self.assertEqual(branch_c.controldir.root_transport.base,
274
branch_b.get_parent())
276
def test_pull_bundle(self):
277
from breezy.bzr.testament import Testament
278
# Build up 2 trees and prepare for a pull
279
tree_a = self.make_branch_and_tree('branch_a')
280
with open('branch_a/a', 'wb') as f:
283
tree_a.commit('message')
285
tree_b = tree_a.controldir.sprout('branch_b').open_workingtree()
287
# Make a change to 'a' that 'b' can pull
288
with open('branch_a/a', 'wb') as f:
289
f.write(b'hey there')
290
tree_a.commit('message')
292
# Create the bundle for 'b' to pull
293
self.run_bzr('bundle ../branch_b -o ../bundle', working_dir='branch_a')
295
out, err = self.run_bzr('pull ../bundle', working_dir='branch_b')
296
self.assertEqual(out,
297
'Now on revision 2.\n')
298
self.assertEqual(err,
299
' M a\nAll changes applied successfully.\n')
301
self.assertEqualDiff(tree_a.branch.last_revision(),
302
tree_b.branch.last_revision())
304
testament_a = Testament.from_revision(tree_a.branch.repository,
305
tree_a.get_parent_ids()[0])
306
testament_b = Testament.from_revision(tree_b.branch.repository,
307
tree_b.get_parent_ids()[0])
308
self.assertEqualDiff(testament_a.as_text(),
309
testament_b.as_text())
311
# it is legal to attempt to pull an already-merged bundle
312
out, err = self.run_bzr('pull ../bundle', working_dir='branch_b')
313
self.assertEqual(err, '')
314
self.assertEqual(out, 'No revisions or tags to pull.\n')
316
def test_pull_verbose_no_files(self):
317
"""Pull --verbose should not list modified files"""
318
tree_a = self.make_branch_and_tree('tree_a')
319
self.build_tree(['tree_a/foo'])
322
tree_b = self.make_branch_and_tree('tree_b')
323
out = self.run_bzr('pull --verbose -d tree_b tree_a')[0]
324
self.assertContainsRe(out, 'bar')
325
self.assertNotContainsRe(out, 'added:')
326
self.assertNotContainsRe(out, 'foo')
328
def test_pull_quiet(self):
329
"""Check that brz pull --quiet does not print anything"""
330
tree_a = self.make_branch_and_tree('tree_a')
331
self.build_tree(['tree_a/foo'])
333
revision_id = tree_a.commit('bar')
334
tree_b = tree_a.controldir.sprout('tree_b').open_workingtree()
335
out, err = self.run_bzr('pull --quiet -d tree_b')
336
self.assertEqual(out, '')
337
self.assertEqual(err, '')
338
self.assertEqual(tree_b.last_revision(), revision_id)
339
self.build_tree(['tree_a/moo'])
341
revision_id = tree_a.commit('quack')
342
out, err = self.run_bzr('pull --quiet -d tree_b')
343
self.assertEqual(out, '')
344
self.assertEqual(err, '')
345
self.assertEqual(tree_b.last_revision(), revision_id)
347
def test_pull_from_directory_service(self):
348
source = self.make_branch_and_tree('source')
349
source.commit('commit 1')
350
target = source.controldir.sprout('target').open_workingtree()
351
source_last = source.commit('commit 2')
353
class FooService(object):
354
"""A directory service that always returns source"""
356
def look_up(self, name, url, purpose=None):
358
directories.register('foo:', FooService, 'Testing directory service')
359
self.addCleanup(directories.remove, 'foo:')
360
self.run_bzr('pull foo:bar -d target')
361
self.assertEqual(source_last, target.last_revision())
363
def test_pull_verbose_defaults_to_long(self):
364
tree = self.example_branch('source')
365
target = self.make_branch_and_tree('target')
366
out = self.run_bzr('pull -v source -d target')[0]
367
self.assertContainsRe(out,
368
r'revno: 1\ncommitter: .*\nbranch nick: source')
369
self.assertNotContainsRe(out, r'\n {4}1 .*\n {6}setup\n')
371
def test_pull_verbose_uses_default_log(self):
372
tree = self.example_branch('source')
373
target = self.make_branch_and_tree('target')
374
target.branch.get_config_stack().set('log_format', 'short')
375
out = self.run_bzr('pull -v source -d target')[0]
376
self.assertContainsRe(out, r'\n {4}1 .*\n {6}setup\n')
377
self.assertNotContainsRe(
378
out, r'revno: 1\ncommitter: .*\nbranch nick: source')
380
def test_pull_smart_bound_branch(self):
381
self.setup_smart_server_with_call_log()
382
parent = self.make_branch_and_tree('parent')
383
parent.commit(message='first commit')
384
child = parent.controldir.sprout('child').open_workingtree()
385
child.commit(message='second commit')
386
checkout = parent.branch.create_checkout('checkout')
387
self.run_bzr(['pull', self.get_url('child')], working_dir='checkout')
389
def test_pull_smart_stacked_streaming_acceptance(self):
390
"""'brz pull -r 123' works on stacked, smart branches, even when the
391
revision specified by the revno is only present in the fallback
394
See <https://launchpad.net/bugs/380314>
396
self.setup_smart_server_with_call_log()
397
# Make a stacked-on branch with two commits so that the
398
# revision-history can't be determined just by looking at the parent
399
# field in the revision in the stacked repo.
400
parent = self.make_branch_and_tree('parent', format='1.9')
401
parent.commit(message='first commit')
402
parent.commit(message='second commit')
403
local = parent.controldir.sprout('local').open_workingtree()
404
local.commit(message='local commit')
405
local.branch.create_clone_on_transport(
406
self.get_transport('stacked'), stacked_on=self.get_url('parent'))
407
empty = self.make_branch_and_tree('empty', format='1.9')
408
self.reset_smart_call_log()
409
self.run_bzr(['pull', '-r', '1', self.get_url('stacked')],
411
# This figure represent the amount of work to perform this use case. It
412
# is entirely ok to reduce this number if a test fails due to rpc_count
413
# being too low. If rpc_count increases, more network roundtrips have
414
# become necessary for this use case. Please do not adjust this number
415
# upwards without agreement from bzr's network support maintainers.
416
self.assertLength(20, self.hpss_calls)
417
self.assertLength(1, self.hpss_connections)
418
remote = branch.Branch.open('stacked')
419
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
421
def test_pull_cross_format_warning(self):
422
"""You get a warning for probably slow cross-format pulls.
424
# this is assumed to be going through InterDifferingSerializer
425
from_tree = self.make_branch_and_tree('from', format='2a')
426
to_tree = self.make_branch_and_tree('to', format='1.14-rich-root')
427
from_tree.commit(message='first commit')
428
out, err = self.run_bzr(['pull', '-d', 'to', 'from'])
429
self.assertContainsRe(err,
430
"(?m)Doing on-the-fly conversion")
432
def test_pull_cross_format_warning_no_IDS(self):
433
"""You get a warning for probably slow cross-format pulls.
435
# this simulates what would happen across the network, where
436
# interdifferingserializer is not active
438
debug.debug_flags.add('IDS_never')
439
# TestCase take care of restoring them
441
from_tree = self.make_branch_and_tree('from', format='2a')
442
to_tree = self.make_branch_and_tree('to', format='1.14-rich-root')
443
from_tree.commit(message='first commit')
444
out, err = self.run_bzr(['pull', '-d', 'to', 'from'])
445
self.assertContainsRe(err,
446
"(?m)Doing on-the-fly conversion")
448
def test_pull_cross_format_from_network(self):
449
self.setup_smart_server_with_call_log()
450
from_tree = self.make_branch_and_tree('from', format='2a')
451
to_tree = self.make_branch_and_tree('to', format='1.14-rich-root')
452
self.assertIsInstance(from_tree.branch, remote.RemoteBranch)
453
from_tree.commit(message='first commit')
454
out, err = self.run_bzr(['pull', '-d', 'to',
455
from_tree.branch.controldir.root_transport.base])
456
self.assertContainsRe(err,
457
"(?m)Doing on-the-fly conversion")
459
def test_pull_to_experimental_format_warning(self):
460
"""You get a warning for pulling into experimental formats.
462
from_tree = self.make_branch_and_tree(
463
'from', format='development-subtree')
464
to_tree = self.make_branch_and_tree('to', format='development-subtree')
465
from_tree.commit(message='first commit')
466
out, err = self.run_bzr(['pull', '-d', 'to', 'from'])
467
self.assertContainsRe(err,
468
"(?m)Fetching into experimental format")
470
def test_pull_cross_to_experimental_format_warning(self):
471
"""You get a warning for pulling into experimental formats.
473
from_tree = self.make_branch_and_tree('from', format='2a')
474
to_tree = self.make_branch_and_tree('to', format='development-subtree')
475
from_tree.commit(message='first commit')
476
out, err = self.run_bzr(['pull', '-d', 'to', 'from'])
477
self.assertContainsRe(err,
478
"(?m)Fetching into experimental format")
480
def test_pull_show_base(self):
481
"""brz pull supports --show-base
483
see https://bugs.launchpad.net/bzr/+bug/202374"""
484
# create two trees with conflicts, setup conflict, check that
485
# conflicted file looks correct
486
a_tree = self.example_branch('a')
487
b_tree = a_tree.controldir.sprout('b').open_workingtree()
489
with open(osutils.pathjoin('a', 'hello'), 'wt') as f:
493
with open(osutils.pathjoin('b', 'hello'), 'wt') as f:
496
out, err = self.run_bzr(['pull', '-d', 'b', 'a', '--show-base'])
498
# check for message here
501
' M hello\nText conflict in hello\n1 conflicts encountered.\n')
503
self.assertEqualDiff('<<<<<<< TREE\n'
504
'fie||||||| BASE-REVISION\n'
506
'fee>>>>>>> MERGE-SOURCE\n',
507
open(osutils.pathjoin('b', 'hello')).read())
509
def test_pull_warns_about_show_base_when_no_working_tree(self):
510
"""--show-base is useless if there's no working tree
512
see https://bugs.launchpad.net/bzr/+bug/1022160"""
513
self.make_branch('from')
514
self.make_branch('to')
515
out = self.run_bzr(['pull', '-d', 'to', 'from', '--show-base'])
516
self.assertEqual(out, ('No revisions or tags to pull.\n',
517
'No working tree, ignoring --show-base\n'))
519
def test_pull_tag_conflicts(self):
520
"""pulling tags with conflicts will change the exit code"""
521
# create a branch, see that --show-base fails
522
from_tree = self.make_branch_and_tree('from')
523
from_tree.branch.tags.set_tag("mytag", b"somerevid")
524
to_tree = self.make_branch_and_tree('to')
525
to_tree.branch.tags.set_tag("mytag", b"anotherrevid")
526
out = self.run_bzr(['pull', '-d', 'to', 'from'], retcode=1)
527
self.assertEqual(out,
528
('No revisions to pull.\nConflicting tags:\n mytag\n', ''))
530
def test_pull_tag_notification(self):
531
"""pulling tags with conflicts will change the exit code"""
532
# create a branch, see that --show-base fails
533
from_tree = self.make_branch_and_tree('from')
534
from_tree.branch.tags.set_tag("mytag", b"somerevid")
535
to_tree = self.make_branch_and_tree('to')
536
out = self.run_bzr(['pull', '-d', 'to', 'from'])
537
self.assertEqual(out,
538
('1 tag(s) updated.\n', ''))
540
def test_overwrite_tags(self):
541
"""--overwrite-tags only overwrites tags, not revisions."""
542
from_tree = self.make_branch_and_tree('from')
543
from_tree.branch.tags.set_tag("mytag", b"somerevid")
544
to_tree = self.make_branch_and_tree('to')
545
to_tree.branch.tags.set_tag("mytag", b"anotherrevid")
546
revid1 = to_tree.commit('my commit')
547
out = self.run_bzr(['pull', '-d', 'to', 'from'], retcode=1)
548
self.assertEqual(out,
549
('No revisions to pull.\nConflicting tags:\n mytag\n', ''))
550
out = self.run_bzr(['pull', '-d', 'to', '--overwrite-tags', 'from'])
551
self.assertEqual(out, ('1 tag(s) updated.\n', ''))
553
self.assertEqual(to_tree.branch.tags.lookup_tag('mytag'),
555
self.assertEqual(to_tree.branch.last_revision(), revid1)
557
def test_pull_tag_overwrite(self):
558
"""pulling tags with --overwrite only reports changed tags."""
559
# create a branch, see that --show-base fails
560
from_tree = self.make_branch_and_tree('from')
561
from_tree.branch.tags.set_tag("mytag", b"somerevid")
562
to_tree = self.make_branch_and_tree('to')
563
to_tree.branch.tags.set_tag("mytag", b"somerevid")
564
out = self.run_bzr(['pull', '--overwrite', '-d', 'to', 'from'])
565
self.assertEqual(out,
566
('No revisions or tags to pull.\n', ''))
569
class TestPullOutput(script.TestCaseWithTransportAndScript):
571
def test_pull_log_format(self):
574
Created a standalone tree (format: 2a)
579
$ brz commit -m 'we need some foo'
580
2>Committing to:...trunk/
582
2>Committed revision 1.
585
Created a standalone tree (format: 2a)
587
$ brz pull -v ../trunk -Olog_format=line
590
1: jrandom@example.com ...we need some foo
592
2>All changes applied successfully.
259
self.runbzr('pull ../branch_c --remember')
260
self.assertEquals(abspath(branch_b.get_parent()),
261
abspath(branch_c.bzrdir.root_transport.base))