18
18
"""Black-box tests for bzr push."""
23
22
from bzrlib import (
28
from bzrlib.branch import Branch
29
from bzrlib.bzrdir import BzrDirMetaFormat1
30
from bzrlib.osutils import abspath
31
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
32
from bzrlib.smart import client, server
33
from bzrlib.tests.blackbox import ExternalBase
34
from bzrlib.tests.http_server import HttpServer
35
from bzrlib.transport.memory import MemoryServer, MemoryTransport
36
from bzrlib.uncommit import uncommit
37
from bzrlib.urlutils import local_path_from_url
38
from bzrlib.workingtree import WorkingTree
41
class TestPush(ExternalBase):
33
from bzrlib.repofmt import knitrepo
34
from bzrlib.tests import http_server
35
from bzrlib.transport import memory
38
class TestPush(tests.TestCaseWithTransport):
43
40
def test_push_error_on_vfs_http(self):
44
41
""" pushing a branch to a HTTP server fails cleanly. """
45
42
# the trunk is published on a web server
46
self.transport_readonly_server = HttpServer
43
self.transport_readonly_server = http_server.HttpServer
47
44
self.make_branch('source')
48
45
public_url = self.get_readonly_url('target')
49
46
self.run_bzr_error(['http does not support mkdir'],
72
69
self.assertEqual(None, branch_b.get_push_location())
74
71
# test push for failure without push location set
76
out = self.run_bzr('push', retcode=3)
72
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
77
73
self.assertEquals(out,
78
74
('','bzr: ERROR: No push location known or specified.\n'))
80
76
# test not remembered if cannot actually push
81
self.run_bzr('push ../path/which/doesnt/exist', retcode=3)
82
out = self.run_bzr('push', retcode=3)
77
self.run_bzr('push path/which/doesnt/exist',
78
working_dir='branch_a', retcode=3)
79
out = self.run_bzr('push', working_dir='branch_a', retcode=3)
84
81
('', 'bzr: ERROR: No push location known or specified.\n'),
87
84
# test implicit --remember when no push location set, push fails
88
out = self.run_bzr('push ../branch_b', retcode=3)
85
out = self.run_bzr('push ../branch_b',
86
working_dir='branch_a', retcode=3)
89
87
self.assertEquals(out,
90
88
('','bzr: ERROR: These branches have diverged. '
91
89
'Try using "merge" and then "push".\n'))
92
self.assertEquals(abspath(branch_a.get_push_location()),
93
abspath(branch_b.bzrdir.root_transport.base))
90
self.assertEquals(osutils.abspath(branch_a.get_push_location()),
91
osutils.abspath(branch_b.bzrdir.root_transport.base))
95
93
# test implicit --remember after resolving previous failure
96
uncommit(branch=branch_b, tree=tree_b)
94
uncommit.uncommit(branch=branch_b, tree=tree_b)
97
95
transport.delete('branch_b/c')
98
out, err = self.run_bzr('push')
96
out, err = self.run_bzr('push', working_dir='branch_a')
99
97
path = branch_a.get_push_location()
100
98
self.assertEquals(out,
101
99
'Using saved push location: %s\n'
102
% local_path_from_url(path))
100
% urlutils.local_path_from_url(path))
103
101
self.assertEqual(err,
104
102
'All changes applied successfully.\n'
105
103
'Pushed up to revision 2.\n')
106
104
self.assertEqual(path,
107
105
branch_b.bzrdir.root_transport.base)
108
106
# test explicit --remember
109
self.run_bzr('push ../branch_c --remember')
107
self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
110
108
self.assertEquals(branch_a.get_push_location(),
111
109
branch_c.bzrdir.root_transport.base)
116
114
out, err = self.run_bzr('push pushed-location')
117
115
self.assertEqual('', out)
118
116
self.assertEqual('Created new branch.\n', err)
119
b2 = Branch.open('pushed-location')
117
b2 = branch.Branch.open('pushed-location')
120
118
self.assertEndsWith(b2.base, 'pushed-location/')
122
120
def test_push_new_branch_revision_count(self):
127
125
self.build_tree(['tree/file'])
129
127
t.commit('commit 1')
131
out, err = self.run_bzr('push pushed-to')
128
out, err = self.run_bzr('push -d tree pushed-to')
133
129
self.assertEqual('', out)
134
130
self.assertEqual('Created new branch.\n', err)
136
132
def test_push_only_pushes_history(self):
137
133
# Knit branches should only push the history for the current revision.
138
format = BzrDirMetaFormat1()
139
format.repository_format = RepositoryFormatKnit1()
134
format = bzrdir.BzrDirMetaFormat1()
135
format.repository_format = knitrepo.RepositoryFormatKnit1()
140
136
shared_repo = self.make_repository('repo', format=format, shared=True)
141
137
shared_repo.set_make_working_trees(True)
143
139
def make_shared_tree(path):
144
140
shared_repo.bzrdir.root_transport.mkdir(path)
145
141
shared_repo.bzrdir.create_branch_convenience('repo/' + path)
146
return WorkingTree.open('repo/' + path)
142
return workingtree.WorkingTree.open('repo/' + path)
147
143
tree_a = make_shared_tree('a')
148
144
self.build_tree(['repo/a/file'])
149
145
tree_a.add('file')
165
161
# Now that we have a repository with shared files, make sure
166
162
# that things aren't copied out by a 'push'
168
self.run_bzr('push ../../push-b')
169
pushed_tree = WorkingTree.open('../../push-b')
163
self.run_bzr('push ../../push-b', working_dir='repo/b')
164
pushed_tree = workingtree.WorkingTree.open('push-b')
170
165
pushed_repo = pushed_tree.branch.repository
171
166
self.assertFalse(pushed_repo.has_revision('a-1'))
172
167
self.assertFalse(pushed_repo.has_revision('a-2'))
175
170
def test_push_funky_id(self):
176
171
t = self.make_branch_and_tree('tree')
178
self.build_tree(['filename'])
172
self.build_tree(['tree/filename'])
179
173
t.add('filename', 'funky-chars<>%&;"\'')
180
174
t.commit('commit filename')
181
self.run_bzr('push ../new-tree')
175
self.run_bzr('push -d tree new-tree')
183
177
def test_push_dash_d(self):
184
178
t = self.make_branch_and_tree('from')
218
212
# become necessary for this use case. Please do not adjust this number
219
213
# upwards without agreement from bzr's network support maintainers.
220
214
self.assertLength(14, self.hpss_calls)
221
remote = Branch.open('public')
215
remote = branch.Branch.open('public')
222
216
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
224
218
def create_simple_tree(self):
273
267
# Pushing onto an existing bzrdir will create a repository and
274
268
# branch as needed, but will only create a working tree if there was
275
269
# no BzrDir before.
276
self.assertRaises(errors.NoWorkingTree, WorkingTree.open, 'repo')
277
new_branch = Branch.open('repo')
270
self.assertRaises(errors.NoWorkingTree,
271
workingtree.WorkingTree.open, 'repo')
272
new_branch = branch.Branch.open('repo')
278
273
self.assertEqual(tree.last_revision(), new_branch.last_revision())
280
275
def test_push_onto_just_bzrdir(self):
327
322
def assertPublished(self, branch_revid, stacked_on):
328
323
"""Assert that the branch 'published' has been published correctly."""
329
published_branch = Branch.open('published')
324
published_branch = branch.Branch.open('published')
330
325
# The published branch refers to the mainline
331
326
self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
332
327
# and the branch's work was pushed
354
349
self.assertEqual('', out)
355
350
self.assertEqual('Created new stacked branch referring to %s.\n' %
356
351
trunk_tree.branch.base, err)
357
self.assertPublished(branch_tree.last_revision(), trunk_tree.branch.base)
352
self.assertPublished(branch_tree.last_revision(),
353
trunk_tree.branch.base)
359
355
def test_push_new_branch_stacked_uses_parent_public(self):
360
356
"""Pushing a new branch with --stacked creates a stacked branch."""
361
357
trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
362
358
# the trunk is published on a web server
363
self.transport_readonly_server = HttpServer
359
self.transport_readonly_server = http_server.HttpServer
364
360
trunk_public = self.make_branch('public_trunk', format='1.9')
365
361
trunk_public.pull(trunk_tree.branch)
366
362
trunk_public_url = self.get_readonly_url('public_trunk')
398
394
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
399
395
self.make_branch('from', format='pack-0.92')
400
396
out, err = self.run_bzr('push -d from to')
401
branch = Branch.open('to')
402
self.assertEqual('../stack_on', branch.get_stacked_on_url())
397
b = branch.Branch.open('to')
398
self.assertEqual('../stack_on', b.get_stacked_on_url())
404
400
def test_push_does_not_change_format_with_default_if_target_cannot(self):
405
401
self.make_branch('stack_on', format='pack-0.92')
406
402
self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
407
403
self.make_branch('from', format='pack-0.92')
408
404
out, err = self.run_bzr('push -d from to')
409
branch = Branch.open('to')
410
self.assertRaises(errors.UnstackableBranchFormat,
411
branch.get_stacked_on_url)
405
b = branch.Branch.open('to')
406
self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
413
408
def test_push_doesnt_create_broken_branch(self):
414
409
"""Pushing a new standalone branch works even when there's a default
456
451
self.assertNotContainsRe(out, 'rev1')
459
class RedirectingMemoryTransport(MemoryTransport):
454
class RedirectingMemoryTransport(memory.MemoryTransport):
461
456
def mkdir(self, relpath, mode=None):
462
457
from bzrlib.trace import mutter
463
mutter('cwd: %r, rel: %r, abs: %r' % (self._cwd, relpath, abspath))
464
458
if self._cwd == '/source/':
465
459
raise errors.RedirectRequested(self.abspath(relpath),
466
460
self.abspath('../target'),
498
492
transport.unregister_transport(self._scheme, self._memory_factory)
501
class TestPushRedirect(ExternalBase):
495
class TestPushRedirect(tests.TestCaseWithTransport):
504
ExternalBase.setUp(self)
498
tests.TestCaseWithTransport.setUp(self)
505
499
self.memory_server = RedirectingMemoryServer()
506
500
self.memory_server.setUp()
507
501
self.addCleanup(self.memory_server.tearDown)
521
515
destination_url = self.memory_server.get_url() + 'source'
522
516
self.run_bzr(['push', '-d', 'tree', destination_url])
524
local_revision = Branch.open('tree').last_revision()
525
remote_revision = Branch.open(
518
local_revision = branch.Branch.open('tree').last_revision()
519
remote_revision = branch.Branch.open(
526
520
self.memory_server.get_url() + 'target').last_revision()
527
521
self.assertEqual(remote_revision, local_revision)