57
78
self.assertEqual(None, branch_b.get_push_location())
59
80
# test push for failure without push location set
61
out = self.run_bzr('push', retcode=3)
81
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
62
82
self.assertEquals(out,
63
83
('','bzr: ERROR: No push location known or specified.\n'))
65
85
# test not remembered if cannot actually push
66
self.run_bzr('push ../path/which/doesnt/exist', retcode=3)
67
out = self.run_bzr('push', retcode=3)
86
self.run_bzr('push path/which/doesnt/exist',
87
working_dir='branch_a', retcode=3)
88
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
69
90
('', 'bzr: ERROR: No push location known or specified.\n'),
72
93
# test implicit --remember when no push location set, push fails
73
out = self.run_bzr('push ../branch_b', retcode=3)
94
out = self.run_bzr('push ../branch_b',
95
working_dir='branch_a', retcode=3)
74
96
self.assertEquals(out,
75
97
('','bzr: ERROR: These branches have diverged. '
76
'Try using "merge" and then "push".\n'))
77
self.assertEquals(abspath(branch_a.get_push_location()),
78
abspath(branch_b.bzrdir.root_transport.base))
98
'See "bzr help diverged-branches" for more information.\n'))
99
self.assertEquals(osutils.abspath(branch_a.get_push_location()),
100
osutils.abspath(branch_b.bzrdir.root_transport.base))
80
102
# test implicit --remember after resolving previous failure
81
uncommit(branch=branch_b, tree=tree_b)
103
uncommit.uncommit(branch=branch_b, tree=tree_b)
82
104
transport.delete('branch_b/c')
83
out, err = self.run_bzr('push')
105
out, err = self.run_bzr('push', working_dir='branch_a')
84
106
path = branch_a.get_push_location()
85
107
self.assertEquals(out,
86
'Using saved location: %s\n'
87
'Pushed up to revision 2.\n'
88
% local_path_from_url(path))
108
'Using saved push location: %s\n'
109
% urlutils.local_path_from_url(path))
89
110
self.assertEqual(err,
90
'All changes applied successfully.\n')
111
'All changes applied successfully.\n'
112
'Pushed up to revision 2.\n')
91
113
self.assertEqual(path,
92
114
branch_b.bzrdir.root_transport.base)
93
115
# test explicit --remember
94
self.run_bzr('push ../branch_c --remember')
116
self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
95
117
self.assertEquals(branch_a.get_push_location(),
96
118
branch_c.bzrdir.root_transport.base)
98
120
def test_push_without_tree(self):
99
121
# bzr push from a branch that does not have a checkout should work.
100
122
b = self.make_branch('.')
101
123
out, err = self.run_bzr('push pushed-location')
102
124
self.assertEqual('', out)
103
125
self.assertEqual('Created new branch.\n', err)
104
b2 = Branch.open('pushed-location')
126
b2 = branch.Branch.open('pushed-location')
105
127
self.assertEndsWith(b2.base, 'pushed-location/')
129
def test_push_no_tree(self):
130
# bzr push --no-tree of a branch with working trees
131
b = self.make_branch_and_tree('push-from')
132
self.build_tree(['push-from/file'])
135
out, err = self.run_bzr('push --no-tree -d push-from push-to')
136
self.assertEqual('', out)
137
self.assertEqual('Created new branch.\n', err)
138
self.failIfExists('push-to/file')
107
140
def test_push_new_branch_revision_count(self):
108
# bzr push of a branch with revisions to a new location
109
# should print the number of revisions equal to the length of the
141
# bzr push of a branch with revisions to a new location
142
# should print the number of revisions equal to the length of the
111
144
t = self.make_branch_and_tree('tree')
112
145
self.build_tree(['tree/file'])
114
147
t.commit('commit 1')
116
out, err = self.run_bzr('push pushed-to')
148
out, err = self.run_bzr('push -d tree pushed-to')
118
149
self.assertEqual('', out)
119
150
self.assertEqual('Created new branch.\n', err)
121
152
def test_push_only_pushes_history(self):
122
153
# Knit branches should only push the history for the current revision.
123
format = BzrDirMetaFormat1()
124
format.repository_format = RepositoryFormatKnit1()
154
format = bzrdir.BzrDirMetaFormat1()
155
format.repository_format = knitrepo.RepositoryFormatKnit1()
125
156
shared_repo = self.make_repository('repo', format=format, shared=True)
126
157
shared_repo.set_make_working_trees(True)
128
159
def make_shared_tree(path):
129
160
shared_repo.bzrdir.root_transport.mkdir(path)
130
161
shared_repo.bzrdir.create_branch_convenience('repo/' + path)
131
return WorkingTree.open('repo/' + path)
162
return workingtree.WorkingTree.open('repo/' + path)
132
163
tree_a = make_shared_tree('a')
133
164
self.build_tree(['repo/a/file'])
134
165
tree_a.add('file')
171
200
message='first commit')
172
201
self.run_bzr('push -d from to-one')
173
202
self.failUnlessExists('to-one')
174
self.run_bzr('push -d %s %s'
203
self.run_bzr('push -d %s %s'
175
204
% tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
176
205
self.failUnlessExists('to-two')
207
def test_push_smart_non_stacked_streaming_acceptance(self):
208
self.setup_smart_server_with_call_log()
209
t = self.make_branch_and_tree('from')
210
t.commit(allow_pointless=True, message='first commit')
211
self.reset_smart_call_log()
212
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
213
# This figure represent the amount of work to perform this use case. It
214
# is entirely ok to reduce this number if a test fails due to rpc_count
215
# being too low. If rpc_count increases, more network roundtrips have
216
# become necessary for this use case. Please do not adjust this number
217
# upwards without agreement from bzr's network support maintainers.
218
self.assertLength(9, self.hpss_calls)
220
def test_push_smart_stacked_streaming_acceptance(self):
221
self.setup_smart_server_with_call_log()
222
parent = self.make_branch_and_tree('parent', format='1.9')
223
parent.commit(message='first commit')
224
local = parent.bzrdir.sprout('local').open_workingtree()
225
local.commit(message='local commit')
226
self.reset_smart_call_log()
227
self.run_bzr(['push', '--stacked', '--stacked-on', '../parent',
228
self.get_url('public')], working_dir='local')
229
# This figure represent the amount of work to perform this use case. It
230
# is entirely ok to reduce this number if a test fails due to rpc_count
231
# being too low. If rpc_count increases, more network roundtrips have
232
# become necessary for this use case. Please do not adjust this number
233
# upwards without agreement from bzr's network support maintainers.
234
self.assertLength(13, self.hpss_calls)
235
remote = branch.Branch.open('public')
236
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
238
def test_push_smart_tags_streaming_acceptance(self):
239
self.setup_smart_server_with_call_log()
240
t = self.make_branch_and_tree('from')
241
rev_id = t.commit(allow_pointless=True, message='first commit')
242
t.branch.tags.set_tag('new-tag', rev_id)
243
self.reset_smart_call_log()
244
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
245
# This figure represent the amount of work to perform this use case. It
246
# is entirely ok to reduce this number if a test fails due to rpc_count
247
# being too low. If rpc_count increases, more network roundtrips have
248
# become necessary for this use case. Please do not adjust this number
249
# upwards without agreement from bzr's network support maintainers.
250
self.assertLength(11, self.hpss_calls)
252
def test_push_smart_incremental_acceptance(self):
253
self.setup_smart_server_with_call_log()
254
t = self.make_branch_and_tree('from')
255
rev_id1 = t.commit(allow_pointless=True, message='first commit')
256
rev_id2 = t.commit(allow_pointless=True, message='second commit')
258
['push', self.get_url('to-one'), '-r1'], working_dir='from')
259
self.reset_smart_call_log()
260
self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
261
# This figure represent the amount of work to perform this use case. It
262
# is entirely ok to reduce this number if a test fails due to rpc_count
263
# being too low. If rpc_count increases, more network roundtrips have
264
# become necessary for this use case. Please do not adjust this number
265
# upwards without agreement from bzr's network support maintainers.
266
self.assertLength(11, self.hpss_calls)
268
def test_push_smart_with_default_stacking_url_path_segment(self):
269
# If the default stacked-on location is a path element then branches
270
# we push there over the smart server are stacked and their
271
# stacked_on_url is that exact path segment. Added to nail bug 385132.
272
self.setup_smart_server_with_call_log()
273
self.make_branch('stack-on', format='1.9')
274
self.make_bzrdir('.').get_config().set_default_stack_on(
276
self.make_branch('from', format='1.9')
277
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
278
b = branch.Branch.open(self.get_url('to'))
279
self.assertEqual('/extra/stack-on', b.get_stacked_on_url())
281
def test_push_smart_with_default_stacking_relative_path(self):
282
# If the default stacked-on location is a relative path then branches
283
# we push there over the smart server are stacked and their
284
# stacked_on_url is a relative path. Added to nail bug 385132.
285
self.setup_smart_server_with_call_log()
286
self.make_branch('stack-on', format='1.9')
287
self.make_bzrdir('.').get_config().set_default_stack_on('stack-on')
288
self.make_branch('from', format='1.9')
289
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
290
b = branch.Branch.open(self.get_url('to'))
291
self.assertEqual('../stack-on', b.get_stacked_on_url())
178
293
def create_simple_tree(self):
179
294
tree = self.make_branch_and_tree('tree')
180
295
self.build_tree(['tree/a'])
244
371
self.run_bzr_error(['At ../dir you have a valid .bzr control'],
246
373
working_dir='tree')
375
def test_push_with_revisionspec(self):
376
"""We should be able to push a revision older than the tip."""
377
tree_from = self.make_branch_and_tree('from')
378
tree_from.commit("One.", rev_id="from-1")
379
tree_from.commit("Two.", rev_id="from-2")
381
self.run_bzr('push -r1 ../to', working_dir='from')
383
tree_to = workingtree.WorkingTree.open('to')
384
repo_to = tree_to.branch.repository
385
self.assertTrue(repo_to.has_revision('from-1'))
386
self.assertFalse(repo_to.has_revision('from-2'))
387
self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
390
['bzr: ERROR: bzr push --revision '
391
'takes exactly one revision identifier\n'],
392
'push -r0..2 ../to', working_dir='from')
394
def create_trunk_and_feature_branch(self):
396
trunk_tree = self.make_branch_and_tree('target',
398
trunk_tree.commit('mainline')
399
# and a branch from it
400
branch_tree = self.make_branch_and_tree('branch',
402
branch_tree.pull(trunk_tree.branch)
403
branch_tree.branch.set_parent(trunk_tree.branch.base)
404
# with some work on it
405
branch_tree.commit('moar work plz')
406
return trunk_tree, branch_tree
408
def assertPublished(self, branch_revid, stacked_on):
409
"""Assert that the branch 'published' has been published correctly."""
410
published_branch = branch.Branch.open('published')
411
# The published branch refers to the mainline
412
self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
413
# and the branch's work was pushed
414
self.assertTrue(published_branch.repository.has_revision(branch_revid))
416
def test_push_new_branch_stacked_on(self):
417
"""Pushing a new branch with --stacked-on creates a stacked branch."""
418
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
419
# we publish branch_tree with a reference to the mainline.
420
out, err = self.run_bzr(['push', '--stacked-on', trunk_tree.branch.base,
421
self.get_url('published')], working_dir='branch')
422
self.assertEqual('', out)
423
self.assertEqual('Created new stacked branch referring to %s.\n' %
424
trunk_tree.branch.base, err)
425
self.assertPublished(branch_tree.last_revision(),
426
trunk_tree.branch.base)
428
def test_push_new_branch_stacked_uses_parent_when_no_public_url(self):
429
"""When the parent has no public url the parent is used as-is."""
430
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
431
# now we do a stacked push, which should determine the public location
433
out, err = self.run_bzr(['push', '--stacked',
434
self.get_url('published')], working_dir='branch')
435
self.assertEqual('', out)
436
self.assertEqual('Created new stacked branch referring to %s.\n' %
437
trunk_tree.branch.base, err)
438
self.assertPublished(branch_tree.last_revision(),
439
trunk_tree.branch.base)
441
def test_push_new_branch_stacked_uses_parent_public(self):
442
"""Pushing a new branch with --stacked creates a stacked branch."""
443
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
444
# the trunk is published on a web server
445
self.transport_readonly_server = http_server.HttpServer
446
trunk_public = self.make_branch('public_trunk', format='1.9')
447
trunk_public.pull(trunk_tree.branch)
448
trunk_public_url = self.get_readonly_url('public_trunk')
449
trunk_tree.branch.set_public_branch(trunk_public_url)
450
# now we do a stacked push, which should determine the public location
452
out, err = self.run_bzr(['push', '--stacked',
453
self.get_url('published')], working_dir='branch')
454
self.assertEqual('', out)
455
self.assertEqual('Created new stacked branch referring to %s.\n' %
456
trunk_public_url, err)
457
self.assertPublished(branch_tree.last_revision(), trunk_public_url)
459
def test_push_new_branch_stacked_no_parent(self):
460
"""Pushing with --stacked and no parent branch errors."""
461
branch = self.make_branch_and_tree('branch', format='1.9')
462
# now we do a stacked push, which should fail as the place to refer too
463
# cannot be determined.
464
out, err = self.run_bzr_error(
465
['Could not determine branch to refer to\\.'], ['push', '--stacked',
466
self.get_url('published')], working_dir='branch')
467
self.assertEqual('', out)
468
self.assertFalse(self.get_transport('published').has('.'))
470
def test_push_notifies_default_stacking(self):
471
self.make_branch('stack_on', format='1.6')
472
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
473
self.make_branch('from', format='1.6')
474
out, err = self.run_bzr('push -d from to')
475
self.assertContainsRe(err,
476
'Using default stacking branch stack_on at .*')
478
def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
479
self.make_branch('stack_on', format='1.6')
480
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
481
self.make_branch('from', format='pack-0.92')
482
out, err = self.run_bzr('push -d from to')
483
b = branch.Branch.open('to')
484
self.assertEqual('../stack_on', b.get_stacked_on_url())
486
def test_push_does_not_change_format_with_default_if_target_cannot(self):
487
self.make_branch('stack_on', format='pack-0.92')
488
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
489
self.make_branch('from', format='pack-0.92')
490
out, err = self.run_bzr('push -d from to')
491
b = branch.Branch.open('to')
492
self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
494
def test_push_doesnt_create_broken_branch(self):
495
"""Pushing a new standalone branch works even when there's a default
496
stacking policy at the destination.
498
The new branch will preserve the repo format (even if it isn't the
499
default for the branch), and will be stacked when the repo format
500
allows (which means that the branch format isn't necessarly preserved).
502
self.make_repository('repo', shared=True, format='1.6')
503
builder = self.make_branch_builder('repo/local', format='pack-0.92')
504
builder.start_series()
505
builder.build_snapshot('rev-1', None, [
506
('add', ('', 'root-id', 'directory', '')),
507
('add', ('filename', 'f-id', 'file', 'content\n'))])
508
builder.build_snapshot('rev-2', ['rev-1'], [])
509
builder.build_snapshot('rev-3', ['rev-2'],
510
[('modify', ('f-id', 'new-content\n'))])
511
builder.finish_series()
512
branch = builder.get_branch()
513
# Push rev-1 to "trunk", so that we can stack on it.
514
self.run_bzr('push -d repo/local trunk -r 1')
515
# Set a default stacking policy so that new branches will automatically
517
self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
518
# Push rev-2 to a new branch "remote". It will be stacked on "trunk".
519
out, err = self.run_bzr('push -d repo/local remote -r 2')
520
self.assertContainsRe(
521
err, 'Using default stacking branch trunk at .*')
522
# Push rev-3 onto "remote". If "remote" not stacked and is missing the
523
# fulltext record for f-id @ rev-1, then this will fail.
524
out, err = self.run_bzr('push -d repo/local remote -r 3')
526
def test_push_verbose_shows_log(self):
527
tree = self.make_branch_and_tree('source')
529
out, err = self.run_bzr('push -v -d source target')
530
# initial push contains log
531
self.assertContainsRe(out, 'rev1')
533
out, err = self.run_bzr('push -v -d source target')
534
# subsequent push contains log
535
self.assertContainsRe(out, 'rev2')
536
# subsequent log is accurate
537
self.assertNotContainsRe(out, 'rev1')
539
def test_push_from_subdir(self):
540
t = self.make_branch_and_tree('tree')
541
self.build_tree(['tree/dir/', 'tree/dir/file'])
542
t.add('dir', 'dir/file')
544
out, err = self.run_bzr('push ../../pushloc', working_dir='tree/dir')
545
self.assertEqual('', out)
546
self.assertEqual('Created new branch.\n', err)
549
class RedirectingMemoryTransport(memory.MemoryTransport):
551
def mkdir(self, relpath, mode=None):
552
if self._cwd == '/source/':
553
raise errors.RedirectRequested(self.abspath(relpath),
554
self.abspath('../target'),
556
elif self._cwd == '/infinite-loop/':
557
raise errors.RedirectRequested(self.abspath(relpath),
558
self.abspath('../infinite-loop'),
561
return super(RedirectingMemoryTransport, self).mkdir(
564
def get(self, relpath):
565
if self.clone(relpath)._cwd == '/infinite-loop/':
566
raise errors.RedirectRequested(self.abspath(relpath),
567
self.abspath('../infinite-loop'),
570
return super(RedirectingMemoryTransport, self).get(relpath)
572
def _redirected_to(self, source, target):
573
# We do accept redirections
574
return transport.get_transport(target)
577
class RedirectingMemoryServer(memory.MemoryServer):
579
def start_server(self):
580
self._dirs = {'/': None}
583
self._scheme = 'redirecting-memory+%s:///' % id(self)
584
transport.register_transport(self._scheme, self._memory_factory)
586
def _memory_factory(self, url):
587
result = RedirectingMemoryTransport(url)
588
result._dirs = self._dirs
589
result._files = self._files
590
result._locks = self._locks
593
def stop_server(self):
594
transport.unregister_transport(self._scheme, self._memory_factory)
597
class TestPushRedirect(tests.TestCaseWithTransport):
600
tests.TestCaseWithTransport.setUp(self)
601
self.memory_server = RedirectingMemoryServer()
602
self.start_server(self.memory_server)
603
# Make the branch and tree that we'll be pushing.
604
t = self.make_branch_and_tree('tree')
605
self.build_tree(['tree/file'])
609
def test_push_redirects_on_mkdir(self):
610
"""If the push requires a mkdir, push respects redirect requests.
612
This is added primarily to handle lp:/ URI support, so that users can
613
push to new branches by specifying lp:/ URIs.
615
destination_url = self.memory_server.get_url() + 'source'
616
self.run_bzr(['push', '-d', 'tree', destination_url])
618
local_revision = branch.Branch.open('tree').last_revision()
619
remote_revision = branch.Branch.open(
620
self.memory_server.get_url() + 'target').last_revision()
621
self.assertEqual(remote_revision, local_revision)
623
def test_push_gracefully_handles_too_many_redirects(self):
624
"""Push fails gracefully if the mkdir generates a large number of
627
destination_url = self.memory_server.get_url() + 'infinite-loop'
628
out, err = self.run_bzr_error(
629
['Too many redirections trying to make %s\\.\n'
630
% re.escape(destination_url)],
631
['push', '-d', 'tree', destination_url], retcode=3)
632
self.assertEqual('', out)
635
class TestPushStrictMixin(object):
637
def make_local_branch_and_tree(self):
638
self.tree = self.make_branch_and_tree('local')
639
self.build_tree_contents([('local/file', 'initial')])
640
self.tree.add('file')
641
self.tree.commit('adding file', rev_id='added')
642
self.build_tree_contents([('local/file', 'modified')])
643
self.tree.commit('modify file', rev_id='modified')
645
def set_config_push_strict(self, value):
646
# set config var (any of bazaar.conf, locations.conf, branch.conf
648
conf = self.tree.branch.get_config()
649
conf.set_user_option('push_strict', value)
651
_default_command = ['push', '../to']
652
_default_wd = 'local'
653
_default_errors = ['Working tree ".*/local/" has uncommitted '
654
'changes \(See bzr status\)\.',]
655
_default_additional_error = 'Use --no-strict to force the push.\n'
656
_default_additional_warning = 'Uncommitted changes will not be pushed.'
659
def assertPushFails(self, args):
660
out, err = self.run_bzr_error(self._default_errors,
661
self._default_command + args,
662
working_dir=self._default_wd, retcode=3)
663
self.assertContainsRe(err, self._default_additional_error)
665
def assertPushSucceeds(self, args, with_warning=False, revid_to_push=None):
667
error_regexes = self._default_errors
670
out, err = self.run_bzr(self._default_command + args,
671
working_dir=self._default_wd,
672
error_regexes=error_regexes)
674
self.assertContainsRe(err, self._default_additional_warning)
676
self.assertNotContainsRe(err, self._default_additional_warning)
677
branch_from = branch.Branch.open(self._default_wd)
678
if revid_to_push is None:
679
revid_to_push = branch_from.last_revision()
680
branch_to = branch.Branch.open('to')
681
repo_to = branch_to.repository
682
self.assertTrue(repo_to.has_revision(revid_to_push))
683
self.assertEqual(revid_to_push, branch_to.last_revision())
687
class TestPushStrictWithoutChanges(tests.TestCaseWithTransport,
688
TestPushStrictMixin):
691
super(TestPushStrictWithoutChanges, self).setUp()
692
self.make_local_branch_and_tree()
694
def test_push_default(self):
695
self.assertPushSucceeds([])
697
def test_push_strict(self):
698
self.assertPushSucceeds(['--strict'])
700
def test_push_no_strict(self):
701
self.assertPushSucceeds(['--no-strict'])
703
def test_push_config_var_strict(self):
704
self.set_config_push_strict('true')
705
self.assertPushSucceeds([])
707
def test_push_config_var_no_strict(self):
708
self.set_config_push_strict('false')
709
self.assertPushSucceeds([])
712
strict_push_change_scenarios = [
714
dict(_changes_type= '_uncommitted_changes')),
716
dict(_changes_type= '_pending_merges')),
717
('out-of-sync-trees',
718
dict(_changes_type= '_out_of_sync_trees')),
722
class TestPushStrictWithChanges(tests.TestCaseWithTransport,
723
TestPushStrictMixin):
725
scenarios = strict_push_change_scenarios
726
_changes_type = None # Set by load_tests
729
super(TestPushStrictWithChanges, self).setUp()
730
# Apply the changes defined in load_tests: one of _uncommitted_changes,
731
# _pending_merges or _out_of_sync_trees
732
getattr(self, self._changes_type)()
734
def _uncommitted_changes(self):
735
self.make_local_branch_and_tree()
736
# Make a change without committing it
737
self.build_tree_contents([('local/file', 'in progress')])
739
def _pending_merges(self):
740
self.make_local_branch_and_tree()
741
# Create 'other' branch containing a new file
742
other_bzrdir = self.tree.bzrdir.sprout('other')
743
other_tree = other_bzrdir.open_workingtree()
744
self.build_tree_contents([('other/other-file', 'other')])
745
other_tree.add('other-file')
746
other_tree.commit('other commit', rev_id='other')
747
# Merge and revert, leaving a pending merge
748
self.tree.merge_from_branch(other_tree.branch)
749
self.tree.revert(filenames=['other-file'], backups=False)
751
def _out_of_sync_trees(self):
752
self.make_local_branch_and_tree()
753
self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
754
# Make a change and commit it
755
self.build_tree_contents([('local/file', 'modified in local')])
756
self.tree.commit('modify file', rev_id='modified-in-local')
757
# Exercise commands from the checkout directory
758
self._default_wd = 'checkout'
759
self._default_errors = ["Working tree is out of date, please run"
762
def test_push_default(self):
763
self.assertPushSucceeds([], with_warning=True)
765
def test_push_with_revision(self):
766
self.assertPushSucceeds(['-r', 'revid:added'], revid_to_push='added')
768
def test_push_no_strict(self):
769
self.assertPushSucceeds(['--no-strict'])
771
def test_push_strict_with_changes(self):
772
self.assertPushFails(['--strict'])
774
def test_push_respect_config_var_strict(self):
775
self.set_config_push_strict('true')
776
self.assertPushFails([])
778
def test_push_bogus_config_var_ignored(self):
779
self.set_config_push_strict("I don't want you to be strict")
780
self.assertPushSucceeds([], with_warning=True)
782
def test_push_no_strict_command_line_override_config(self):
783
self.set_config_push_strict('yES')
784
self.assertPushFails([])
785
self.assertPushSucceeds(['--no-strict'])
787
def test_push_strict_command_line_override_config(self):
788
self.set_config_push_strict('oFF')
789
self.assertPushFails(['--strict'])
790
self.assertPushSucceeds([])
793
class TestPushForeign(tests.TestCaseWithTransport):
796
super(TestPushForeign, self).setUp()
797
test_foreign.register_dummy_foreign_for_test(self)
799
def make_dummy_builder(self, relpath):
800
builder = self.make_branch_builder(
801
relpath, format=test_foreign.DummyForeignVcsDirFormat())
802
builder.build_snapshot('revid', None,
803
[('add', ('', 'TREE_ROOT', 'directory', None)),
804
('add', ('foo', 'fooid', 'file', 'bar'))])
807
def test_no_roundtripping(self):
808
target_branch = self.make_dummy_builder('dp').get_branch()
809
source_tree = self.make_branch_and_tree("dc")
810
output, error = self.run_bzr("push -d dc dp", retcode=3)
811
self.assertEquals("", output)
812
self.assertEquals(error, "bzr: ERROR: It is not possible to losslessly"
813
" push to dummy. You may want to use dpush instead.\n")