1
# Copyright (C) 2005, 2007, 2008 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# 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 bzr push."""
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'],
74
def test_push_remember(self):
75
"""Push changes from one branch to another and test push location."""
76
transport = self.get_transport()
77
tree_a = self.make_branch_and_tree('branch_a')
78
branch_a = tree_a.branch
79
self.build_tree(['branch_a/a'])
81
tree_a.commit('commit a')
82
tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
83
branch_b = tree_b.branch
84
tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
85
branch_c = tree_c.branch
86
self.build_tree(['branch_a/b'])
88
tree_a.commit('commit b')
89
self.build_tree(['branch_b/c'])
91
tree_b.commit('commit c')
92
# initial push location must be empty
93
self.assertEqual(None, branch_b.get_push_location())
95
# test push for failure without push location set
96
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
97
self.assertEquals(out,
98
('','bzr: ERROR: No push location known or specified.\n'))
100
# test not remembered if cannot actually push
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)
105
('', 'bzr: ERROR: No push location known or specified.\n'),
108
# test implicit --remember when no push location set, push fails
109
out = self.run_bzr('push ../branch_b',
110
working_dir='branch_a', retcode=3)
111
self.assertEquals(out,
112
('','bzr: ERROR: These branches have diverged. '
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))
117
# test implicit --remember after resolving previous failure
118
uncommit.uncommit(branch=branch_b, tree=tree_b)
119
transport.delete('branch_b/c')
120
out, err = self.run_bzr('push', working_dir='branch_a')
121
path = branch_a.get_push_location()
122
self.assertEquals(out,
123
'Using saved push location: %s\n'
124
% urlutils.local_path_from_url(path))
125
self.assertEqual(err,
126
'All changes applied successfully.\n'
127
'Pushed up to revision 2.\n')
128
self.assertEqual(path,
129
branch_b.bzrdir.root_transport.base)
130
# test explicit --remember
131
self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
132
self.assertEquals(branch_a.get_push_location(),
133
branch_c.bzrdir.root_transport.base)
135
def test_push_without_tree(self):
136
# bzr push from a branch that does not have a checkout should work.
137
b = self.make_branch('.')
138
out, err = self.run_bzr('push pushed-location')
139
self.assertEqual('', out)
140
self.assertEqual('Created new branch.\n', err)
141
b2 = branch.Branch.open('pushed-location')
142
self.assertEndsWith(b2.base, 'pushed-location/')
144
def test_push_new_branch_revision_count(self):
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
148
t = self.make_branch_and_tree('tree')
149
self.build_tree(['tree/file'])
152
out, err = self.run_bzr('push -d tree pushed-to')
153
self.assertEqual('', out)
154
self.assertEqual('Created new branch.\n', err)
156
def test_push_only_pushes_history(self):
157
# Knit branches should only push the history for the current revision.
158
format = bzrdir.BzrDirMetaFormat1()
159
format.repository_format = knitrepo.RepositoryFormatKnit1()
160
shared_repo = self.make_repository('repo', format=format, shared=True)
161
shared_repo.set_make_working_trees(True)
163
def make_shared_tree(path):
164
shared_repo.bzrdir.root_transport.mkdir(path)
165
shared_repo.bzrdir.create_branch_convenience('repo/' + path)
166
return workingtree.WorkingTree.open('repo/' + path)
167
tree_a = make_shared_tree('a')
168
self.build_tree(['repo/a/file'])
170
tree_a.commit('commit a-1', rev_id='a-1')
171
f = open('repo/a/file', 'ab')
172
f.write('more stuff\n')
174
tree_a.commit('commit a-2', rev_id='a-2')
176
tree_b = make_shared_tree('b')
177
self.build_tree(['repo/b/file'])
179
tree_b.commit('commit b-1', rev_id='b-1')
181
self.assertTrue(shared_repo.has_revision('a-1'))
182
self.assertTrue(shared_repo.has_revision('a-2'))
183
self.assertTrue(shared_repo.has_revision('b-1'))
185
# Now that we have a repository with shared files, make sure
186
# that things aren't copied out by a 'push'
187
self.run_bzr('push ../../push-b', working_dir='repo/b')
188
pushed_tree = workingtree.WorkingTree.open('push-b')
189
pushed_repo = pushed_tree.branch.repository
190
self.assertFalse(pushed_repo.has_revision('a-1'))
191
self.assertFalse(pushed_repo.has_revision('a-2'))
192
self.assertTrue(pushed_repo.has_revision('b-1'))
194
def test_push_funky_id(self):
195
t = self.make_branch_and_tree('tree')
196
self.build_tree(['tree/filename'])
197
t.add('filename', 'funky-chars<>%&;"\'')
198
t.commit('commit filename')
199
self.run_bzr('push -d tree new-tree')
201
def test_push_dash_d(self):
202
t = self.make_branch_and_tree('from')
203
t.commit(allow_pointless=True,
204
message='first commit')
205
self.run_bzr('push -d from to-one')
206
self.failUnlessExists('to-one')
207
self.run_bzr('push -d %s %s'
208
% tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
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_with_default_stacking_url_path_segment(self):
243
# If the default stacked-on location is a path element then branches
244
# we push there over the smart server are stacked and their
245
# stacked_on_url is that exact path segment. Added to nail bug 385132.
246
self.setup_smart_server_with_call_log()
247
self.make_branch('stack-on', format='1.9')
248
self.make_bzrdir('.').get_config().set_default_stack_on(
250
self.make_branch('from', format='1.9')
251
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
252
b = branch.Branch.open(self.get_url('to'))
253
self.assertEqual('/extra/stack-on', b.get_stacked_on_url())
255
def test_push_smart_with_default_stacking_relative_path(self):
256
# If the default stacked-on location is a relative path then branches
257
# we push there over the smart server are stacked and their
258
# stacked_on_url is a relative path. Added to nail bug 385132.
259
self.setup_smart_server_with_call_log()
260
self.make_branch('stack-on', format='1.9')
261
self.make_bzrdir('.').get_config().set_default_stack_on('stack-on')
262
self.make_branch('from', format='1.9')
263
out, err = self.run_bzr(['push', '-d', 'from', self.get_url('to')])
264
b = branch.Branch.open(self.get_url('to'))
265
self.assertEqual('../stack-on', b.get_stacked_on_url())
267
def create_simple_tree(self):
268
tree = self.make_branch_and_tree('tree')
269
self.build_tree(['tree/a'])
270
tree.add(['a'], ['a-id'])
271
tree.commit('one', rev_id='r1')
274
def test_push_create_prefix(self):
275
"""'bzr push --create-prefix' will create leading directories."""
276
tree = self.create_simple_tree()
278
self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
281
self.run_bzr('push ../new/tree --create-prefix',
283
new_tree = workingtree.WorkingTree.open('new/tree')
284
self.assertEqual(tree.last_revision(), new_tree.last_revision())
285
self.failUnlessExists('new/tree/a')
287
def test_push_use_existing(self):
288
"""'bzr push --use-existing-dir' can push into an existing dir.
290
By default, 'bzr push' will not use an existing, non-versioned dir.
292
tree = self.create_simple_tree()
293
self.build_tree(['target/'])
295
self.run_bzr_error(['Target directory ../target already exists',
296
'Supply --use-existing-dir',
298
'push ../target', working_dir='tree')
300
self.run_bzr('push --use-existing-dir ../target',
303
new_tree = workingtree.WorkingTree.open('target')
304
self.assertEqual(tree.last_revision(), new_tree.last_revision())
305
# The push should have created target/a
306
self.failUnlessExists('target/a')
308
def test_push_onto_repo(self):
309
"""We should be able to 'bzr push' into an existing bzrdir."""
310
tree = self.create_simple_tree()
311
repo = self.make_repository('repo', shared=True)
313
self.run_bzr('push ../repo',
316
# Pushing onto an existing bzrdir will create a repository and
317
# branch as needed, but will only create a working tree if there was
319
self.assertRaises(errors.NoWorkingTree,
320
workingtree.WorkingTree.open, 'repo')
321
new_branch = branch.Branch.open('repo')
322
self.assertEqual(tree.last_revision(), new_branch.last_revision())
324
def test_push_onto_just_bzrdir(self):
325
"""We don't handle when the target is just a bzrdir.
327
Because you shouldn't be able to create *just* a bzrdir in the wild.
329
# TODO: jam 20070109 Maybe it would be better to create the repository
331
tree = self.create_simple_tree()
332
a_bzrdir = self.make_bzrdir('dir')
334
self.run_bzr_error(['At ../dir you have a valid .bzr control'],
338
def test_push_with_revisionspec(self):
339
"""We should be able to push a revision older than the tip."""
340
tree_from = self.make_branch_and_tree('from')
341
tree_from.commit("One.", rev_id="from-1")
342
tree_from.commit("Two.", rev_id="from-2")
344
self.run_bzr('push -r1 ../to', working_dir='from')
346
tree_to = workingtree.WorkingTree.open('to')
347
repo_to = tree_to.branch.repository
348
self.assertTrue(repo_to.has_revision('from-1'))
349
self.assertFalse(repo_to.has_revision('from-2'))
350
self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
353
['bzr: ERROR: bzr push --revision '
354
'takes exactly one revision identifier\n'],
355
'push -r0..2 ../to', working_dir='from')
357
def create_trunk_and_feature_branch(self):
359
trunk_tree = self.make_branch_and_tree('target',
361
trunk_tree.commit('mainline')
362
# and a branch from it
363
branch_tree = self.make_branch_and_tree('branch',
365
branch_tree.pull(trunk_tree.branch)
366
branch_tree.branch.set_parent(trunk_tree.branch.base)
367
# with some work on it
368
branch_tree.commit('moar work plz')
369
return trunk_tree, branch_tree
371
def assertPublished(self, branch_revid, stacked_on):
372
"""Assert that the branch 'published' has been published correctly."""
373
published_branch = branch.Branch.open('published')
374
# The published branch refers to the mainline
375
self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
376
# and the branch's work was pushed
377
self.assertTrue(published_branch.repository.has_revision(branch_revid))
379
def test_push_new_branch_stacked_on(self):
380
"""Pushing a new branch with --stacked-on creates a stacked branch."""
381
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
382
# we publish branch_tree with a reference to the mainline.
383
out, err = self.run_bzr(['push', '--stacked-on', trunk_tree.branch.base,
384
self.get_url('published')], working_dir='branch')
385
self.assertEqual('', out)
386
self.assertEqual('Created new stacked branch referring to %s.\n' %
387
trunk_tree.branch.base, err)
388
self.assertPublished(branch_tree.last_revision(),
389
trunk_tree.branch.base)
391
def test_push_new_branch_stacked_uses_parent_when_no_public_url(self):
392
"""When the parent has no public url the parent is used as-is."""
393
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
394
# now we do a stacked push, which should determine the public location
396
out, err = self.run_bzr(['push', '--stacked',
397
self.get_url('published')], working_dir='branch')
398
self.assertEqual('', out)
399
self.assertEqual('Created new stacked branch referring to %s.\n' %
400
trunk_tree.branch.base, err)
401
self.assertPublished(branch_tree.last_revision(),
402
trunk_tree.branch.base)
404
def test_push_new_branch_stacked_uses_parent_public(self):
405
"""Pushing a new branch with --stacked creates a stacked branch."""
406
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
407
# the trunk is published on a web server
408
self.transport_readonly_server = http_server.HttpServer
409
trunk_public = self.make_branch('public_trunk', format='1.9')
410
trunk_public.pull(trunk_tree.branch)
411
trunk_public_url = self.get_readonly_url('public_trunk')
412
trunk_tree.branch.set_public_branch(trunk_public_url)
413
# now we do a stacked push, which should determine the public location
415
out, err = self.run_bzr(['push', '--stacked',
416
self.get_url('published')], working_dir='branch')
417
self.assertEqual('', out)
418
self.assertEqual('Created new stacked branch referring to %s.\n' %
419
trunk_public_url, err)
420
self.assertPublished(branch_tree.last_revision(), trunk_public_url)
422
def test_push_new_branch_stacked_no_parent(self):
423
"""Pushing with --stacked and no parent branch errors."""
424
branch = self.make_branch_and_tree('branch', format='1.9')
425
# now we do a stacked push, which should fail as the place to refer too
426
# cannot be determined.
427
out, err = self.run_bzr_error(
428
['Could not determine branch to refer to\\.'], ['push', '--stacked',
429
self.get_url('published')], working_dir='branch')
430
self.assertEqual('', out)
431
self.assertFalse(self.get_transport('published').has('.'))
433
def test_push_notifies_default_stacking(self):
434
self.make_branch('stack_on', format='1.6')
435
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
436
self.make_branch('from', format='1.6')
437
out, err = self.run_bzr('push -d from to')
438
self.assertContainsRe(err,
439
'Using default stacking branch stack_on at .*')
441
def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
442
self.make_branch('stack_on', format='1.6')
443
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
444
self.make_branch('from', format='pack-0.92')
445
out, err = self.run_bzr('push -d from to')
446
b = branch.Branch.open('to')
447
self.assertEqual('../stack_on', b.get_stacked_on_url())
449
def test_push_does_not_change_format_with_default_if_target_cannot(self):
450
self.make_branch('stack_on', format='pack-0.92')
451
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
452
self.make_branch('from', format='pack-0.92')
453
out, err = self.run_bzr('push -d from to')
454
b = branch.Branch.open('to')
455
self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
457
def test_push_doesnt_create_broken_branch(self):
458
"""Pushing a new standalone branch works even when there's a default
459
stacking policy at the destination.
461
The new branch will preserve the repo format (even if it isn't the
462
default for the branch), and will be stacked when the repo format
463
allows (which means that the branch format isn't necessarly preserved).
465
self.make_repository('repo', shared=True, format='1.6')
466
builder = self.make_branch_builder('repo/local', format='pack-0.92')
467
builder.start_series()
468
builder.build_snapshot('rev-1', None, [
469
('add', ('', 'root-id', 'directory', '')),
470
('add', ('filename', 'f-id', 'file', 'content\n'))])
471
builder.build_snapshot('rev-2', ['rev-1'], [])
472
builder.build_snapshot('rev-3', ['rev-2'],
473
[('modify', ('f-id', 'new-content\n'))])
474
builder.finish_series()
475
branch = builder.get_branch()
476
# Push rev-1 to "trunk", so that we can stack on it.
477
self.run_bzr('push -d repo/local trunk -r 1')
478
# Set a default stacking policy so that new branches will automatically
480
self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
481
# Push rev-2 to a new branch "remote". It will be stacked on "trunk".
482
out, err = self.run_bzr('push -d repo/local remote -r 2')
483
self.assertContainsRe(
484
err, 'Using default stacking branch trunk at .*')
485
# Push rev-3 onto "remote". If "remote" not stacked and is missing the
486
# fulltext record for f-id @ rev-1, then this will fail.
487
out, err = self.run_bzr('push -d repo/local remote -r 3')
489
def test_push_verbose_shows_log(self):
490
tree = self.make_branch_and_tree('source')
492
out, err = self.run_bzr('push -v -d source target')
493
# initial push contains log
494
self.assertContainsRe(out, 'rev1')
496
out, err = self.run_bzr('push -v -d source target')
497
# subsequent push contains log
498
self.assertContainsRe(out, 'rev2')
499
# subsequent log is accurate
500
self.assertNotContainsRe(out, 'rev1')
502
def test_push_from_subdir(self):
503
t = self.make_branch_and_tree('tree')
504
self.build_tree(['tree/dir/', 'tree/dir/file'])
505
t.add('dir', 'dir/file')
507
out, err = self.run_bzr('push ../../pushloc', working_dir='tree/dir')
508
self.assertEqual('', out)
509
self.assertEqual('Created new branch.\n', err)
512
class RedirectingMemoryTransport(memory.MemoryTransport):
514
def mkdir(self, relpath, mode=None):
515
if self._cwd == '/source/':
516
raise errors.RedirectRequested(self.abspath(relpath),
517
self.abspath('../target'),
519
elif self._cwd == '/infinite-loop/':
520
raise errors.RedirectRequested(self.abspath(relpath),
521
self.abspath('../infinite-loop'),
524
return super(RedirectingMemoryTransport, self).mkdir(
527
def get(self, relpath):
528
if self.clone(relpath)._cwd == '/infinite-loop/':
529
raise errors.RedirectRequested(self.abspath(relpath),
530
self.abspath('../infinite-loop'),
533
return super(RedirectingMemoryTransport, self).get(relpath)
535
def _redirected_to(self, source, target):
536
# We do accept redirections
537
return transport.get_transport(target)
540
class RedirectingMemoryServer(memory.MemoryServer):
543
self._dirs = {'/': None}
546
self._scheme = 'redirecting-memory+%s:///' % id(self)
547
transport.register_transport(self._scheme, self._memory_factory)
549
def _memory_factory(self, url):
550
result = RedirectingMemoryTransport(url)
551
result._dirs = self._dirs
552
result._files = self._files
553
result._locks = self._locks
557
transport.unregister_transport(self._scheme, self._memory_factory)
560
class TestPushRedirect(tests.TestCaseWithTransport):
563
tests.TestCaseWithTransport.setUp(self)
564
self.memory_server = RedirectingMemoryServer()
565
self.memory_server.setUp()
566
self.addCleanup(self.memory_server.tearDown)
568
# Make the branch and tree that we'll be pushing.
569
t = self.make_branch_and_tree('tree')
570
self.build_tree(['tree/file'])
574
def test_push_redirects_on_mkdir(self):
575
"""If the push requires a mkdir, push respects redirect requests.
577
This is added primarily to handle lp:/ URI support, so that users can
578
push to new branches by specifying lp:/ URIs.
580
destination_url = self.memory_server.get_url() + 'source'
581
self.run_bzr(['push', '-d', 'tree', destination_url])
583
local_revision = branch.Branch.open('tree').last_revision()
584
remote_revision = branch.Branch.open(
585
self.memory_server.get_url() + 'target').last_revision()
586
self.assertEqual(remote_revision, local_revision)
588
def test_push_gracefully_handles_too_many_redirects(self):
589
"""Push fails gracefully if the mkdir generates a large number of
592
destination_url = self.memory_server.get_url() + 'infinite-loop'
593
out, err = self.run_bzr_error(
594
['Too many redirections trying to make %s\\.\n'
595
% re.escape(destination_url)],
596
['push', '-d', 'tree', destination_url], retcode=3)
597
self.assertEqual('', out)
600
class TestPushStrictMixin(object):
602
def make_local_branch_and_tree(self):
603
self.tree = self.make_branch_and_tree('local')
604
self.build_tree_contents([('local/file', 'initial')])
605
self.tree.add('file')
606
self.tree.commit('adding file', rev_id='added')
607
self.build_tree_contents([('local/file', 'modified')])
608
self.tree.commit('modify file', rev_id='modified')
610
def set_config_push_strict(self, value):
611
# set config var (any of bazaar.conf, locations.conf, branch.conf
613
conf = self.tree.branch.get_config()
614
conf.set_user_option('push_strict', value)
616
_default_command = ['push', '../to']
617
_default_wd = 'local'
618
_default_errors = ['Working tree ".*/local/" has uncommitted '
619
'changes \(See bzr status\)\.',]
620
_default_pushed_revid = 'modified'
622
def assertPushFails(self, args):
623
self.run_bzr_error(self._default_errors, self._default_command + args,
624
working_dir=self._default_wd, retcode=3)
626
def assertPushSucceeds(self, args, pushed_revid=None):
627
self.run_bzr(self._default_command + args,
628
working_dir=self._default_wd)
629
if pushed_revid is None:
630
pushed_revid = self._default_pushed_revid
631
tree_to = workingtree.WorkingTree.open('to')
632
repo_to = tree_to.branch.repository
633
self.assertTrue(repo_to.has_revision(pushed_revid))
634
self.assertEqual(tree_to.branch.last_revision_info()[1], pushed_revid)
638
class TestPushStrictWithoutChanges(tests.TestCaseWithTransport,
639
TestPushStrictMixin):
642
super(TestPushStrictWithoutChanges, self).setUp()
643
self.make_local_branch_and_tree()
645
def test_push_default(self):
646
self.assertPushSucceeds([])
648
def test_push_strict(self):
649
self.assertPushSucceeds(['--strict'])
651
def test_push_no_strict(self):
652
self.assertPushSucceeds(['--no-strict'])
654
def test_push_config_var_strict(self):
655
self.set_config_push_strict('true')
656
self.assertPushSucceeds([])
658
def test_push_config_var_no_strict(self):
659
self.set_config_push_strict('false')
660
self.assertPushSucceeds([])
663
class TestPushStrictWithChanges(tests.TestCaseWithTransport,
664
TestPushStrictMixin):
666
_changes_type = None # Set by load_tests
669
super(TestPushStrictWithChanges, self).setUp()
670
getattr(self, self._changes_type)()
672
def _uncommitted_changes(self):
673
self.make_local_branch_and_tree()
674
# Make a change without committing it
675
self.build_tree_contents([('local/file', 'in progress')])
677
def _pending_merges(self):
678
self.make_local_branch_and_tree()
679
# Create 'other' branch containing a new file
680
other_bzrdir = self.tree.bzrdir.sprout('other')
681
other_tree = other_bzrdir.open_workingtree()
682
self.build_tree_contents([('other/other-file', 'other')])
683
other_tree.add('other-file')
684
other_tree.commit('other commit', rev_id='other')
685
# Merge and revert, leaving a pending merge
686
self.tree.merge_from_branch(other_tree.branch)
687
self.tree.revert(filenames=['other-file'], backups=False)
689
def _out_of_sync_trees(self):
690
self.make_local_branch_and_tree()
691
self.run_bzr(['checkout', '--lightweight', 'local', 'checkout'])
692
# Make a change and commit it
693
self.build_tree_contents([('local/file', 'modified in local')])
694
self.tree.commit('modify file', rev_id='modified-in-local')
695
# Exercise commands from the checkout directory
696
self._default_wd = 'checkout'
697
self._default_errors = ["Working tree is out of date, please run"
699
self._default_pushed_revid = 'modified-in-local'
701
def test_push_default(self):
702
self.assertPushFails([])
704
def test_push_with_revision(self):
705
self.assertPushSucceeds(['-r', 'revid:added'], pushed_revid='added')
707
def test_push_no_strict(self):
708
self.assertPushSucceeds(['--no-strict'])
710
def test_push_strict_with_changes(self):
711
self.assertPushFails(['--strict'])
713
def test_push_respect_config_var_strict(self):
714
self.set_config_push_strict('true')
715
self.assertPushFails([])
717
def test_push_bogus_config_var_ignored(self):
718
self.set_config_push_strict("I don't want you to be strict")
719
self.assertPushFails([])
721
def test_push_no_strict_command_line_override_config(self):
722
self.set_config_push_strict('yES')
723
self.assertPushFails([])
724
self.assertPushSucceeds(['--no-strict'])
726
def test_push_strict_command_line_override_config(self):
727
self.set_config_push_strict('oFF')
728
self.assertPushFails(['--strict'])
729
self.assertPushSucceeds([])