13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
18
"""Black-box tests for bzr push."""
23
22
from bzrlib import (
27
from bzrlib.branch import Branch
28
from bzrlib.bzrdir import BzrDirMetaFormat1
29
from bzrlib.osutils import abspath
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
31
from bzrlib.tests.blackbox import ExternalBase
32
from bzrlib.transport import register_transport, unregister_transport
33
from bzrlib.transport.memory import MemoryServer, MemoryTransport
34
from bzrlib.uncommit import uncommit
35
from bzrlib.urlutils import local_path_from_url
36
from bzrlib.workingtree import WorkingTree
39
class TestPush(ExternalBase):
33
from bzrlib.repofmt import knitrepo
34
from bzrlib.tests import http_server
35
from bzrlib.transport import memory
38
def load_tests(standard_tests, module, loader):
39
"""Multiply tests for the push command."""
40
result = loader.suiteClass()
42
# one for each king of change
43
changes_tests, remaining_tests = tests.split_suite_by_condition(
44
standard_tests, tests.condition_isinstance((
45
TestPushStrictWithChanges,
49
dict(_changes_type= '_uncommitted_changes')),
51
dict(_changes_type= '_pending_merges')),
53
dict(_changes_type= '_out_of_sync_trees')),
55
tests.multiply_tests(changes_tests, changes_scenarios, result)
56
# No parametrization for the remaining tests
57
result.addTests(remaining_tests)
62
class TestPush(tests.TestCaseWithTransport):
64
def test_push_error_on_vfs_http(self):
65
""" pushing a branch to a HTTP server fails cleanly. """
66
# the trunk is published on a web server
67
self.transport_readonly_server = http_server.HttpServer
68
self.make_branch('source')
69
public_url = self.get_readonly_url('target')
70
self.run_bzr_error(['http does not support mkdir'],
41
74
def test_push_remember(self):
42
75
"""Push changes from one branch to another and test push location."""
60
93
self.assertEqual(None, branch_b.get_push_location())
62
95
# test push for failure without push location set
64
out = self.run_bzr('push', retcode=3)
96
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
65
97
self.assertEquals(out,
66
98
('','bzr: ERROR: No push location known or specified.\n'))
68
100
# test not remembered if cannot actually push
69
self.run_bzr('push ../path/which/doesnt/exist', retcode=3)
70
out = self.run_bzr('push', retcode=3)
101
self.run_bzr('push path/which/doesnt/exist',
102
working_dir='branch_a', retcode=3)
103
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
71
104
self.assertEquals(
72
105
('', 'bzr: ERROR: No push location known or specified.\n'),
75
108
# test implicit --remember when no push location set, push fails
76
out = self.run_bzr('push ../branch_b', retcode=3)
109
out = self.run_bzr('push ../branch_b',
110
working_dir='branch_a', retcode=3)
77
111
self.assertEquals(out,
78
112
('','bzr: ERROR: These branches have diverged. '
79
'Try using "merge" and then "push".\n'))
80
self.assertEquals(abspath(branch_a.get_push_location()),
81
abspath(branch_b.bzrdir.root_transport.base))
113
'See "bzr help diverged-branches" for more information.\n'))
114
self.assertEquals(osutils.abspath(branch_a.get_push_location()),
115
osutils.abspath(branch_b.bzrdir.root_transport.base))
83
117
# test implicit --remember after resolving previous failure
84
uncommit(branch=branch_b, tree=tree_b)
118
uncommit.uncommit(branch=branch_b, tree=tree_b)
85
119
transport.delete('branch_b/c')
86
out, err = self.run_bzr('push')
120
out, err = self.run_bzr('push', working_dir='branch_a')
87
121
path = branch_a.get_push_location()
88
122
self.assertEquals(out,
89
'Using saved location: %s\n'
90
'Pushed up to revision 2.\n'
91
% local_path_from_url(path))
123
'Using saved push location: %s\n'
124
% urlutils.local_path_from_url(path))
92
125
self.assertEqual(err,
93
'All changes applied successfully.\n')
126
'All changes applied successfully.\n'
127
'Pushed up to revision 2.\n')
94
128
self.assertEqual(path,
95
129
branch_b.bzrdir.root_transport.base)
96
130
# test explicit --remember
97
self.run_bzr('push ../branch_c --remember')
131
self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
98
132
self.assertEquals(branch_a.get_push_location(),
99
133
branch_c.bzrdir.root_transport.base)
101
135
def test_push_without_tree(self):
102
136
# bzr push from a branch that does not have a checkout should work.
103
137
b = self.make_branch('.')
104
138
out, err = self.run_bzr('push pushed-location')
105
139
self.assertEqual('', out)
106
140
self.assertEqual('Created new branch.\n', err)
107
b2 = Branch.open('pushed-location')
141
b2 = branch.Branch.open('pushed-location')
108
142
self.assertEndsWith(b2.base, 'pushed-location/')
110
144
def test_push_new_branch_revision_count(self):
111
# bzr push of a branch with revisions to a new location
112
# should print the number of revisions equal to the length of the
145
# bzr push of a branch with revisions to a new location
146
# should print the number of revisions equal to the length of the
114
148
t = self.make_branch_and_tree('tree')
115
149
self.build_tree(['tree/file'])
117
151
t.commit('commit 1')
119
out, err = self.run_bzr('push pushed-to')
152
out, err = self.run_bzr('push -d tree pushed-to')
121
153
self.assertEqual('', out)
122
154
self.assertEqual('Created new branch.\n', err)
124
156
def test_push_only_pushes_history(self):
125
157
# Knit branches should only push the history for the current revision.
126
format = BzrDirMetaFormat1()
127
format.repository_format = RepositoryFormatKnit1()
158
format = bzrdir.BzrDirMetaFormat1()
159
format.repository_format = knitrepo.RepositoryFormatKnit1()
128
160
shared_repo = self.make_repository('repo', format=format, shared=True)
129
161
shared_repo.set_make_working_trees(True)
131
163
def make_shared_tree(path):
132
164
shared_repo.bzrdir.root_transport.mkdir(path)
133
165
shared_repo.bzrdir.create_branch_convenience('repo/' + path)
134
return WorkingTree.open('repo/' + path)
166
return workingtree.WorkingTree.open('repo/' + path)
135
167
tree_a = make_shared_tree('a')
136
168
self.build_tree(['repo/a/file'])
137
169
tree_a.add('file')
174
204
message='first commit')
175
205
self.run_bzr('push -d from to-one')
176
206
self.failUnlessExists('to-one')
177
self.run_bzr('push -d %s %s'
207
self.run_bzr('push -d %s %s'
178
208
% tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
179
209
self.failUnlessExists('to-two')
211
def test_push_smart_non_stacked_streaming_acceptance(self):
212
self.setup_smart_server_with_call_log()
213
t = self.make_branch_and_tree('from')
214
t.commit(allow_pointless=True, message='first commit')
215
self.reset_smart_call_log()
216
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
217
# This figure represent the amount of work to perform this use case. It
218
# is entirely ok to reduce this number if a test fails due to rpc_count
219
# being too low. If rpc_count increases, more network roundtrips have
220
# become necessary for this use case. Please do not adjust this number
221
# upwards without agreement from bzr's network support maintainers.
222
self.assertLength(9, self.hpss_calls)
224
def test_push_smart_stacked_streaming_acceptance(self):
225
self.setup_smart_server_with_call_log()
226
parent = self.make_branch_and_tree('parent', format='1.9')
227
parent.commit(message='first commit')
228
local = parent.bzrdir.sprout('local').open_workingtree()
229
local.commit(message='local commit')
230
self.reset_smart_call_log()
231
self.run_bzr(['push', '--stacked', '--stacked-on', '../parent',
232
self.get_url('public')], working_dir='local')
233
# This figure represent the amount of work to perform this use case. It
234
# is entirely ok to reduce this number if a test fails due to rpc_count
235
# being too low. If rpc_count increases, more network roundtrips have
236
# become necessary for this use case. Please do not adjust this number
237
# upwards without agreement from bzr's network support maintainers.
238
self.assertLength(14, self.hpss_calls)
239
remote = branch.Branch.open('public')
240
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
242
def test_push_smart_tags_streaming_acceptance(self):
243
self.setup_smart_server_with_call_log()
244
t = self.make_branch_and_tree('from')
245
rev_id = t.commit(allow_pointless=True, message='first commit')
246
t.branch.tags.set_tag('new-tag', rev_id)
247
self.reset_smart_call_log()
248
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
249
# This figure represent the amount of work to perform this use case. It
250
# is entirely ok to reduce this number if a test fails due to rpc_count
251
# being too low. If rpc_count increases, more network roundtrips have
252
# become necessary for this use case. Please do not adjust this number
253
# upwards without agreement from bzr's network support maintainers.
254
self.assertLength(11, self.hpss_calls)
256
def test_push_smart_incremental_acceptance(self):
257
self.setup_smart_server_with_call_log()
258
t = self.make_branch_and_tree('from')
259
rev_id1 = t.commit(allow_pointless=True, message='first commit')
260
rev_id2 = t.commit(allow_pointless=True, message='second commit')
262
['push', self.get_url('to-one'), '-r1'], working_dir='from')
263
self.reset_smart_call_log()
264
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
265
# This figure represent the amount of work to perform this use case. It
266
# is entirely ok to reduce this number if a test fails due to rpc_count
267
# being too low. If rpc_count increases, more network roundtrips have
268
# become necessary for this use case. Please do not adjust this number
269
# upwards without agreement from bzr's network support maintainers.
270
self.assertLength(11, self.hpss_calls)
272
def test_push_smart_with_default_stacking_url_path_segment(self):
273
# If the default stacked-on location is a path element then branches
274
# we push there over the smart server are stacked and their
275
# stacked_on_url is that exact path segment. Added to nail bug 385132.
276
self.setup_smart_server_with_call_log()
277
self.make_branch('stack-on', format='1.9')
278
self.make_bzrdir('.').get_config().set_default_stack_on(
280
self.make_branch('from', format='1.9')
281
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
282
b = branch.Branch.open(self.get_url('to'))
283
self.assertEqual('/extra/stack-on', b.get_stacked_on_url())
285
def test_push_smart_with_default_stacking_relative_path(self):
286
# If the default stacked-on location is a relative path then branches
287
# we push there over the smart server are stacked and their
288
# stacked_on_url is a relative path. Added to nail bug 385132.
289
self.setup_smart_server_with_call_log()
290
self.make_branch('stack-on', format='1.9')
291
self.make_bzrdir('.').get_config().set_default_stack_on('stack-on')
292
self.make_branch('from', format='1.9')
293
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
294
b = branch.Branch.open(self.get_url('to'))
295
self.assertEqual('../stack-on', b.get_stacked_on_url())
181
297
def create_simple_tree(self):
182
298
tree = self.make_branch_and_tree('tree')
183
299
self.build_tree(['tree/a'])
257
385
self.run_bzr('push -r1 ../to', working_dir='from')
259
tree_to = WorkingTree.open('to')
387
tree_to = workingtree.WorkingTree.open('to')
260
388
repo_to = tree_to.branch.repository
261
389
self.assertTrue(repo_to.has_revision('from-1'))
262
390
self.assertFalse(repo_to.has_revision('from-2'))
263
391
self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
265
393
self.run_bzr_error(
266
"bzr: ERROR: bzr push --revision takes one value.\n",
394
['bzr: ERROR: bzr push --revision '
395
'takes exactly one revision identifier\n'],
267
396
'push -r0..2 ../to', working_dir='from')
270
class RedirectingMemoryTransport(MemoryTransport):
272
def mkdir(self, path, mode=None):
273
path = self.abspath(path)[len(self._scheme):]
274
if path == '/source':
275
raise errors.RedirectRequested(
276
path, self._scheme + '/target', is_permanent=True)
277
elif path == '/infinite-loop':
278
raise errors.RedirectRequested(
279
path, self._scheme + '/infinite-loop', is_permanent=True)
398
def create_trunk_and_feature_branch(self):
400
trunk_tree = self.make_branch_and_tree('target',
402
trunk_tree.commit('mainline')
403
# and a branch from it
404
branch_tree = self.make_branch_and_tree('branch',
406
branch_tree.pull(trunk_tree.branch)
407
branch_tree.branch.set_parent(trunk_tree.branch.base)
408
# with some work on it
409
branch_tree.commit('moar work plz')
410
return trunk_tree, branch_tree
412
def assertPublished(self, branch_revid, stacked_on):
413
"""Assert that the branch 'published' has been published correctly."""
414
published_branch = branch.Branch.open('published')
415
# The published branch refers to the mainline
416
self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
417
# and the branch's work was pushed
418
self.assertTrue(published_branch.repository.has_revision(branch_revid))
420
def test_push_new_branch_stacked_on(self):
421
"""Pushing a new branch with --stacked-on creates a stacked branch."""
422
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
423
# we publish branch_tree with a reference to the mainline.
424
out, err = self.run_bzr(['push', '--stacked-on', trunk_tree.branch.base,
425
self.get_url('published')], working_dir='branch')
426
self.assertEqual('', out)
427
self.assertEqual('Created new stacked branch referring to %s.\n' %
428
trunk_tree.branch.base, err)
429
self.assertPublished(branch_tree.last_revision(),
430
trunk_tree.branch.base)
432
def test_push_new_branch_stacked_uses_parent_when_no_public_url(self):
433
"""When the parent has no public url the parent is used as-is."""
434
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
435
# now we do a stacked push, which should determine the public location
437
out, err = self.run_bzr(['push', '--stacked',
438
self.get_url('published')], working_dir='branch')
439
self.assertEqual('', out)
440
self.assertEqual('Created new stacked branch referring to %s.\n' %
441
trunk_tree.branch.base, err)
442
self.assertPublished(branch_tree.last_revision(),
443
trunk_tree.branch.base)
445
def test_push_new_branch_stacked_uses_parent_public(self):
446
"""Pushing a new branch with --stacked creates a stacked branch."""
447
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
448
# the trunk is published on a web server
449
self.transport_readonly_server = http_server.HttpServer
450
trunk_public = self.make_branch('public_trunk', format='1.9')
451
trunk_public.pull(trunk_tree.branch)
452
trunk_public_url = self.get_readonly_url('public_trunk')
453
trunk_tree.branch.set_public_branch(trunk_public_url)
454
# now we do a stacked push, which should determine the public location
456
out, err = self.run_bzr(['push', '--stacked',
457
self.get_url('published')], working_dir='branch')
458
self.assertEqual('', out)
459
self.assertEqual('Created new stacked branch referring to %s.\n' %
460
trunk_public_url, err)
461
self.assertPublished(branch_tree.last_revision(), trunk_public_url)
463
def test_push_new_branch_stacked_no_parent(self):
464
"""Pushing with --stacked and no parent branch errors."""
465
branch = self.make_branch_and_tree('branch', format='1.9')
466
# now we do a stacked push, which should fail as the place to refer too
467
# cannot be determined.
468
out, err = self.run_bzr_error(
469
['Could not determine branch to refer to\\.'], ['push', '--stacked',
470
self.get_url('published')], working_dir='branch')
471
self.assertEqual('', out)
472
self.assertFalse(self.get_transport('published').has('.'))
474
def test_push_notifies_default_stacking(self):
475
self.make_branch('stack_on', format='1.6')
476
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
477
self.make_branch('from', format='1.6')
478
out, err = self.run_bzr('push -d from to')
479
self.assertContainsRe(err,
480
'Using default stacking branch stack_on at .*')
482
def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
483
self.make_branch('stack_on', format='1.6')
484
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
485
self.make_branch('from', format='pack-0.92')
486
out, err = self.run_bzr('push -d from to')
487
b = branch.Branch.open('to')
488
self.assertEqual('../stack_on', b.get_stacked_on_url())
490
def test_push_does_not_change_format_with_default_if_target_cannot(self):
491
self.make_branch('stack_on', format='pack-0.92')
492
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
493
self.make_branch('from', format='pack-0.92')
494
out, err = self.run_bzr('push -d from to')
495
b = branch.Branch.open('to')
496
self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
498
def test_push_doesnt_create_broken_branch(self):
499
"""Pushing a new standalone branch works even when there's a default
500
stacking policy at the destination.
502
The new branch will preserve the repo format (even if it isn't the
503
default for the branch), and will be stacked when the repo format
504
allows (which means that the branch format isn't necessarly preserved).
506
self.make_repository('repo', shared=True, format='1.6')
507
builder = self.make_branch_builder('repo/local', format='pack-0.92')
508
builder.start_series()
509
builder.build_snapshot('rev-1', None, [
510
('add', ('', 'root-id', 'directory', '')),
511
('add', ('filename', 'f-id', 'file', 'content\n'))])
512
builder.build_snapshot('rev-2', ['rev-1'], [])
513
builder.build_snapshot('rev-3', ['rev-2'],
514
[('modify', ('f-id', 'new-content\n'))])
515
builder.finish_series()
516
branch = builder.get_branch()
517
# Push rev-1 to "trunk", so that we can stack on it.
518
self.run_bzr('push -d repo/local trunk -r 1')
519
# Set a default stacking policy so that new branches will automatically
521
self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
522
# Push rev-2 to a new branch "remote". It will be stacked on "trunk".
523
out, err = self.run_bzr('push -d repo/local remote -r 2')
524
self.assertContainsRe(
525
err, 'Using default stacking branch trunk at .*')
526
# Push rev-3 onto "remote". If "remote" not stacked and is missing the
527
# fulltext record for f-id @ rev-1, then this will fail.
528
out, err = self.run_bzr('push -d repo/local remote -r 3')
530
def test_push_verbose_shows_log(self):
531
tree = self.make_branch_and_tree('source')
533
out, err = self.run_bzr('push -v -d source target')
534
# initial push contains log
535
self.assertContainsRe(out, 'rev1')
537
out, err = self.run_bzr('push -v -d source target')
538
# subsequent push contains log
539
self.assertContainsRe(out, 'rev2')
540
# subsequent log is accurate
541
self.assertNotContainsRe(out, 'rev1')
543
def test_push_from_subdir(self):
544
t = self.make_branch_and_tree('tree')
545
self.build_tree(['tree/dir/', 'tree/dir/file'])
546
t.add('dir', 'dir/file')
548
out, err = self.run_bzr('push ../../pushloc', working_dir='tree/dir')
549
self.assertEqual('', out)
550
self.assertEqual('Created new branch.\n', err)
553
class RedirectingMemoryTransport(memory.MemoryTransport):
555
def mkdir(self, relpath, mode=None):
556
if self._cwd == '/source/':
557
raise errors.RedirectRequested(self.abspath(relpath),
558
self.abspath('../target'),
560
elif self._cwd == '/infinite-loop/':
561
raise errors.RedirectRequested(self.abspath(relpath),
562
self.abspath('../infinite-loop'),
281
565
return super(RedirectingMemoryTransport, self).mkdir(
285
class RedirectingMemoryServer(MemoryServer):
568
def get(self, relpath):
569
if self.clone(relpath)._cwd == '/infinite-loop/':
570
raise errors.RedirectRequested(self.abspath(relpath),
571
self.abspath('../infinite-loop'),
574
return super(RedirectingMemoryTransport, self).get(relpath)
576
def _redirected_to(self, source, target):
577
# We do accept redirections
578
return transport.get_transport(target)
581
class RedirectingMemoryServer(memory.MemoryServer):
288
584
self._dirs = {'/': None}
291
587
self._scheme = 'redirecting-memory+%s:///' % id(self)
292
register_transport(self._scheme, self._memory_factory)
588
transport.register_transport(self._scheme, self._memory_factory)
294
590
def _memory_factory(self, url):
295
591
result = RedirectingMemoryTransport(url)
336
628
"""Push fails gracefully if the mkdir generates a large number of
340
631
destination_url = self.memory_server.get_url() + 'infinite-loop'
341
632
out, err = self.run_bzr_error(
342
633
['Too many redirections trying to make %s\\.\n'
343
634
% re.escape(destination_url)],
344
'push %s' % destination_url, retcode=3)
635
['push', '-d', 'tree', destination_url], retcode=3)
346
636
self.assertEqual('', out)
639
class TestPushStrictMixin(object):
641
def make_local_branch_and_tree(self):
642
self.tree = self.make_branch_and_tree('local')
643
self.build_tree_contents([('local/file', 'initial')])
644
self.tree.add('file')
645
self.tree.commit('adding file', rev_id='added')
646
self.build_tree_contents([('local/file', 'modified')])
647
self.tree.commit('modify file', rev_id='modified')
649
def set_config_push_strict(self, value):
650
# set config var (any of bazaar.conf, locations.conf, branch.conf
652
conf = self.tree.branch.get_config()
653
conf.set_user_option('push_strict', value)
655
_default_command = ['push', '../to']
656
_default_wd = 'local'
657
_default_errors = ['Working tree ".*/local/" has uncommitted '
658
'changes \(See bzr status\)\.',]
659
_default_pushed_revid = 'modified'
661
def assertPushFails(self, args):
662
self.run_bzr_error(self._default_errors, self._default_command + args,
663
working_dir=self._default_wd, retcode=3)
665
def assertPushSucceeds(self, args, pushed_revid=None):
666
self.run_bzr(self._default_command + args,
667
working_dir=self._default_wd)
668
if pushed_revid is None:
669
pushed_revid = self._default_pushed_revid
670
tree_to = workingtree.WorkingTree.open('to')
671
repo_to = tree_to.branch.repository
672
self.assertTrue(repo_to.has_revision(pushed_revid))
673
self.assertEqual(tree_to.branch.last_revision_info()[1], pushed_revid)
677
class TestPushStrictWithoutChanges(tests.TestCaseWithTransport,
678
TestPushStrictMixin):
681
super(TestPushStrictWithoutChanges, self).setUp()
682
self.make_local_branch_and_tree()
684
def test_push_default(self):
685
self.assertPushSucceeds([])
687
def test_push_strict(self):
688
self.assertPushSucceeds(['--strict'])
690
def test_push_no_strict(self):
691
self.assertPushSucceeds(['--no-strict'])
693
def test_push_config_var_strict(self):
694
self.set_config_push_strict('true')
695
self.assertPushSucceeds([])
697
def test_push_config_var_no_strict(self):
698
self.set_config_push_strict('false')
699
self.assertPushSucceeds([])
702
class TestPushStrictWithChanges(tests.TestCaseWithTransport,
703
TestPushStrictMixin):
705
_changes_type = None # Set by load_tests
708
super(TestPushStrictWithChanges, self).setUp()
709
# Apply the changes defined in load_tests: one of _uncommitted_changes,
710
# _pending_merges or _out_of_sync_trees
711
getattr(self, self._changes_type)()
713
def _uncommitted_changes(self):
714
self.make_local_branch_and_tree()
715
# Make a change without committing it
716
self.build_tree_contents([('local/file', 'in progress')])
718
def _pending_merges(self):
719
self.make_local_branch_and_tree()
720
# Create 'other' branch containing a new file
721
other_bzrdir = self.tree.bzrdir.sprout('other')
722
other_tree = other_bzrdir.open_workingtree()
723
self.build_tree_contents([('other/other-file', 'other')])
724
other_tree.add('other-file')
725
other_tree.commit('other commit', rev_id='other')
726
# Merge and revert, leaving a pending merge
727
self.tree.merge_from_branch(other_tree.branch)
728
self.tree.revert(filenames=['other-file'], backups=False)
730
def _out_of_sync_trees(self):
731
self.make_local_branch_and_tree()
732
self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
733
# Make a change and commit it
734
self.build_tree_contents([('local/file', 'modified in local')])
735
self.tree.commit('modify file', rev_id='modified-in-local')
736
# Exercise commands from the checkout directory
737
self._default_wd = 'checkout'
738
self._default_errors = ["Working tree is out of date, please run"
740
self._default_pushed_revid = 'modified-in-local'
742
def test_push_default(self):
743
self.assertPushFails([])
745
def test_push_with_revision(self):
746
self.assertPushSucceeds(['-r', 'revid:added'], pushed_revid='added')
748
def test_push_no_strict(self):
749
self.assertPushSucceeds(['--no-strict'])
751
def test_push_strict_with_changes(self):
752
self.assertPushFails(['--strict'])
754
def test_push_respect_config_var_strict(self):
755
self.set_config_push_strict('true')
756
self.assertPushFails([])
758
def test_push_bogus_config_var_ignored(self):
759
self.set_config_push_strict("I don't want you to be strict")
760
self.assertPushFails([])
762
def test_push_no_strict_command_line_override_config(self):
763
self.set_config_push_strict('yES')
764
self.assertPushFails([])
765
self.assertPushSucceeds(['--no-strict'])
767
def test_push_strict_command_line_override_config(self):
768
self.set_config_push_strict('oFF')
769
self.assertPushFails(['--strict'])
770
self.assertPushSucceeds([])