/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3549.1.1 by Martin Pool
rename push --reference to --stacked-on
1
# Copyright (C) 2005, 2007, 2008 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
16
17
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
18
"""Black-box tests for bzr push."""
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
19
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
20
import re
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
21
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
22
from bzrlib import (
4420.1.1 by Vincent Ladeuil
Cleanup imports.
23
    branch,
24
    bzrdir,
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
25
    errors,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
26
    osutils,
27
    tests,
3878.4.4 by Vincent Ladeuil
Cleanup.
28
    transport,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
29
    uncommit,
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
30
    urlutils,
4420.1.1 by Vincent Ladeuil
Cleanup imports.
31
    workingtree
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
32
    )
4420.1.1 by Vincent Ladeuil
Cleanup imports.
33
from bzrlib.repofmt import knitrepo
34
from bzrlib.tests import http_server
35
from bzrlib.transport import memory
36
37
38
class TestPush(tests.TestCaseWithTransport):
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
39
4017.2.3 by Robert Collins
Review feedback.
40
    def test_push_error_on_vfs_http(self):
41
        """ pushing a branch to a HTTP server fails cleanly. """
42
        # the trunk is published on a web server
4420.1.1 by Vincent Ladeuil
Cleanup imports.
43
        self.transport_readonly_server = http_server.HttpServer
4017.2.3 by Robert Collins
Review feedback.
44
        self.make_branch('source')
45
        public_url = self.get_readonly_url('target')
46
        self.run_bzr_error(['http does not support mkdir'],
47
                           ['push', public_url],
48
                           working_dir='source')
49
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
50
    def test_push_remember(self):
51
        """Push changes from one branch to another and test push location."""
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
52
        transport = self.get_transport()
53
        tree_a = self.make_branch_and_tree('branch_a')
54
        branch_a = tree_a.branch
55
        self.build_tree(['branch_a/a'])
56
        tree_a.add('a')
57
        tree_a.commit('commit a')
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
58
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
59
        branch_b = tree_b.branch
60
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
61
        branch_c = tree_c.branch
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
62
        self.build_tree(['branch_a/b'])
63
        tree_a.add('b')
64
        tree_a.commit('commit b')
65
        self.build_tree(['branch_b/c'])
66
        tree_b.add('c')
67
        tree_b.commit('commit c')
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
68
        # initial push location must be empty
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
69
        self.assertEqual(None, branch_b.get_push_location())
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
70
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
71
        # test push for failure without push location set
4420.1.1 by Vincent Ladeuil
Cleanup imports.
72
        out = self.run_bzr('push', working_dir='branch_a', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
73
        self.assertEquals(out,
74
                ('','bzr: ERROR: No push location known or specified.\n'))
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
75
76
        # test not remembered if cannot actually push
4420.1.1 by Vincent Ladeuil
Cleanup imports.
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)
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
80
        self.assertEquals(
81
                ('', 'bzr: ERROR: No push location known or specified.\n'),
82
                out)
83
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
84
        # test implicit --remember when no push location set, push fails
4420.1.1 by Vincent Ladeuil
Cleanup imports.
85
        out = self.run_bzr('push ../branch_b',
86
                           working_dir='branch_a', retcode=3)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
87
        self.assertEquals(out,
88
                ('','bzr: ERROR: These branches have diverged.  '
2063.2.1 by John Arbash Meinel
(Matthieu Moy) cleanup message when pushing to diverged branch
89
                    'Try using "merge" and then "push".\n'))
4420.1.1 by Vincent Ladeuil
Cleanup imports.
90
        self.assertEquals(osutils.abspath(branch_a.get_push_location()),
91
                          osutils.abspath(branch_b.bzrdir.root_transport.base))
1785.1.2 by John Arbash Meinel
Push should only save the location if it can actually connect (doesn't need to succeed)
92
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
93
        # test implicit --remember after resolving previous failure
4420.1.1 by Vincent Ladeuil
Cleanup imports.
94
        uncommit.uncommit(branch=branch_b, tree=tree_b)
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
95
        transport.delete('branch_b/c')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
96
        out, err = self.run_bzr('push', working_dir='branch_a')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
97
        path = branch_a.get_push_location()
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
98
        self.assertEquals(out,
3978.2.5 by Jelmer Vernooij
Fix trailing whitespace.
99
                          'Using saved push location: %s\n'
4420.1.1 by Vincent Ladeuil
Cleanup imports.
100
                          % urlutils.local_path_from_url(path))
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
101
        self.assertEqual(err,
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
102
                         'All changes applied successfully.\n'
103
                         'Pushed up to revision 2.\n')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
104
        self.assertEqual(path,
105
                         branch_b.bzrdir.root_transport.base)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
106
        # test explicit --remember
4420.1.1 by Vincent Ladeuil
Cleanup imports.
107
        self.run_bzr('push ../branch_c --remember', working_dir='branch_a')
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
108
        self.assertEquals(branch_a.get_push_location(),
109
                          branch_c.bzrdir.root_transport.base)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
110
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
111
    def test_push_without_tree(self):
112
        # bzr push from a branch that does not have a checkout should work.
113
        b = self.make_branch('.')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
114
        out, err = self.run_bzr('push pushed-location')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
115
        self.assertEqual('', out)
116
        self.assertEqual('Created new branch.\n', err)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
117
        b2 = branch.Branch.open('pushed-location')
1692.3.1 by Robert Collins
Fix push to work with just a branch, no need for a working tree.
118
        self.assertEndsWith(b2.base, 'pushed-location/')
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
119
120
    def test_push_new_branch_revision_count(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
121
        # bzr push of a branch with revisions to a new location
122
        # should print the number of revisions equal to the length of the
1692.3.6 by Robert Collins
Show the correct number of revisions pushed when pushing a new branch (Robert Collins).
123
        # local branch.
124
        t = self.make_branch_and_tree('tree')
125
        self.build_tree(['tree/file'])
126
        t.add('file')
127
        t.commit('commit 1')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
128
        out, err = self.run_bzr('push -d tree pushed-to')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
129
        self.assertEqual('', out)
130
        self.assertEqual('Created new branch.\n', err)
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
131
132
    def test_push_only_pushes_history(self):
133
        # Knit branches should only push the history for the current revision.
4420.1.1 by Vincent Ladeuil
Cleanup imports.
134
        format = bzrdir.BzrDirMetaFormat1()
135
        format.repository_format = knitrepo.RepositoryFormatKnit1()
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
136
        shared_repo = self.make_repository('repo', format=format, shared=True)
137
        shared_repo.set_make_working_trees(True)
138
139
        def make_shared_tree(path):
140
            shared_repo.bzrdir.root_transport.mkdir(path)
141
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
142
            return workingtree.WorkingTree.open('repo/' + path)
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
143
        tree_a = make_shared_tree('a')
144
        self.build_tree(['repo/a/file'])
145
        tree_a.add('file')
146
        tree_a.commit('commit a-1', rev_id='a-1')
147
        f = open('repo/a/file', 'ab')
148
        f.write('more stuff\n')
149
        f.close()
150
        tree_a.commit('commit a-2', rev_id='a-2')
151
152
        tree_b = make_shared_tree('b')
153
        self.build_tree(['repo/b/file'])
154
        tree_b.add('file')
155
        tree_b.commit('commit b-1', rev_id='b-1')
156
157
        self.assertTrue(shared_repo.has_revision('a-1'))
158
        self.assertTrue(shared_repo.has_revision('a-2'))
159
        self.assertTrue(shared_repo.has_revision('b-1'))
160
161
        # Now that we have a repository with shared files, make sure
162
        # that things aren't copied out by a 'push'
4420.1.1 by Vincent Ladeuil
Cleanup imports.
163
        self.run_bzr('push ../../push-b', working_dir='repo/b')
164
        pushed_tree = workingtree.WorkingTree.open('push-b')
1711.2.3 by John Arbash Meinel
Fix push to only push revisions in the current ancestry. (bug???)
165
        pushed_repo = pushed_tree.branch.repository
166
        self.assertFalse(pushed_repo.has_revision('a-1'))
167
        self.assertFalse(pushed_repo.has_revision('a-2'))
168
        self.assertTrue(pushed_repo.has_revision('b-1'))
169
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
170
    def test_push_funky_id(self):
171
        t = self.make_branch_and_tree('tree')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
172
        self.build_tree(['tree/filename'])
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
173
        t.add('filename', 'funky-chars<>%&;"\'')
174
        t.commit('commit filename')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
175
        self.run_bzr('push -d tree new-tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
176
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
177
    def test_push_dash_d(self):
178
        t = self.make_branch_and_tree('from')
179
        t.commit(allow_pointless=True,
180
                message='first commit')
2530.3.1 by Martin Pool
Cleanup old variations on run_bzr in the test suite
181
        self.run_bzr('push -d from to-one')
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
182
        self.failUnlessExists('to-one')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
183
        self.run_bzr('push -d %s %s'
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
184
            % tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
185
        self.failUnlessExists('to-two')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
186
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
187
    def test_push_smart_non_stacked_streaming_acceptance(self):
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
188
        self.setup_smart_server_with_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
189
        t = self.make_branch_and_tree('from')
190
        t.commit(allow_pointless=True, message='first commit')
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
191
        self.reset_smart_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
192
        self.run_bzr(['push', self.get_url('to-one')], working_dir='from')
4011.2.4 by Robert Collins
Make the ratchet aspect of the blackbox smart server push acceptance tests clearer.
193
        # This figure represent the amount of work to perform this use case. It
194
        # is entirely ok to reduce this number if a test fails due to rpc_count
195
        # being too low. If rpc_count increases, more network roundtrips have
196
        # become necessary for this use case. Please do not adjust this number
197
        # upwards without agreement from bzr's network support maintainers.
4307.2.2 by Robert Collins
Lock repositories created by BzrDirFormat.initialize_on_transport_ex.
198
        self.assertLength(9, self.hpss_calls)
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
199
200
    def test_push_smart_stacked_streaming_acceptance(self):
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
201
        self.setup_smart_server_with_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
202
        parent = self.make_branch_and_tree('parent', format='1.9')
203
        parent.commit(message='first commit')
204
        local = parent.bzrdir.sprout('local').open_workingtree()
205
        local.commit(message='local commit')
4017.2.1 by Robert Collins
Add BzrDirFormatMeta1 test for the amount of rpc calls made initializing over the network.
206
        self.reset_smart_call_log()
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
207
        self.run_bzr(['push', '--stacked', '--stacked-on', '../parent',
208
            self.get_url('public')], working_dir='local')
4011.2.4 by Robert Collins
Make the ratchet aspect of the blackbox smart server push acceptance tests clearer.
209
        # This figure represent the amount of work to perform this use case. It
210
        # is entirely ok to reduce this number if a test fails due to rpc_count
211
        # being too low. If rpc_count increases, more network roundtrips have
212
        # become necessary for this use case. Please do not adjust this number
213
        # upwards without agreement from bzr's network support maintainers.
4307.2.5 by Robert Collins
Remove too-early checks for revisions adding unnecessary round trips, at the cost of actually reading revision data when pulling (because we currently don't have a hint as about whats local for fetch).
214
        self.assertLength(14, self.hpss_calls)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
215
        remote = branch.Branch.open('public')
4011.2.1 by Robert Collins
Add ratchet style blackbox effort tests for push over bzr+ssh. (Andrew Bennetts, Robert Collins)
216
        self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
217
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
218
    def create_simple_tree(self):
219
        tree = self.make_branch_and_tree('tree')
220
        self.build_tree(['tree/a'])
221
        tree.add(['a'], ['a-id'])
222
        tree.commit('one', rev_id='r1')
223
        return tree
224
225
    def test_push_create_prefix(self):
226
        """'bzr push --create-prefix' will create leading directories."""
227
        tree = self.create_simple_tree()
228
229
        self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
230
                           'push ../new/tree',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
231
                           working_dir='tree')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
232
        self.run_bzr('push ../new/tree --create-prefix',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
233
                     working_dir='tree')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
234
        new_tree = workingtree.WorkingTree.open('new/tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
235
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
236
        self.failUnlessExists('new/tree/a')
237
238
    def test_push_use_existing(self):
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
239
        """'bzr push --use-existing-dir' can push into an existing dir.
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
240
241
        By default, 'bzr push' will not use an existing, non-versioned dir.
242
        """
243
        tree = self.create_simple_tree()
244
        self.build_tree(['target/'])
245
246
        self.run_bzr_error(['Target directory ../target already exists',
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
247
                            'Supply --use-existing-dir',
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
248
                           ],
249
                           'push ../target', working_dir='tree')
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
250
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
251
        self.run_bzr('push --use-existing-dir ../target',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
252
                     working_dir='tree')
253
4420.1.1 by Vincent Ladeuil
Cleanup imports.
254
        new_tree = workingtree.WorkingTree.open('target')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
255
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
256
        # The push should have created target/a
257
        self.failUnlessExists('target/a')
258
259
    def test_push_onto_repo(self):
260
        """We should be able to 'bzr push' into an existing bzrdir."""
261
        tree = self.create_simple_tree()
262
        repo = self.make_repository('repo', shared=True)
263
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
264
        self.run_bzr('push ../repo',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
265
                     working_dir='tree')
266
267
        # Pushing onto an existing bzrdir will create a repository and
268
        # branch as needed, but will only create a working tree if there was
269
        # no BzrDir before.
4420.1.1 by Vincent Ladeuil
Cleanup imports.
270
        self.assertRaises(errors.NoWorkingTree,
271
                          workingtree.WorkingTree.open, 'repo')
272
        new_branch = branch.Branch.open('repo')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
273
        self.assertEqual(tree.last_revision(), new_branch.last_revision())
274
275
    def test_push_onto_just_bzrdir(self):
276
        """We don't handle when the target is just a bzrdir.
277
278
        Because you shouldn't be able to create *just* a bzrdir in the wild.
279
        """
280
        # TODO: jam 20070109 Maybe it would be better to create the repository
281
        #       if at this point
282
        tree = self.create_simple_tree()
283
        a_bzrdir = self.make_bzrdir('dir')
284
285
        self.run_bzr_error(['At ../dir you have a valid .bzr control'],
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
286
                'push ../dir',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
287
                working_dir='tree')
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
288
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
289
    def test_push_with_revisionspec(self):
3256.1.3 by Daniel Watkins
Clarified test intent.
290
        """We should be able to push a revision older than the tip."""
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
291
        tree_from = self.make_branch_and_tree('from')
292
        tree_from.commit("One.", rev_id="from-1")
293
        tree_from.commit("Two.", rev_id="from-2")
294
295
        self.run_bzr('push -r1 ../to', working_dir='from')
296
4420.1.1 by Vincent Ladeuil
Cleanup imports.
297
        tree_to = workingtree.WorkingTree.open('to')
3256.1.1 by Daniel Watkins
Added test for push with a revspec.
298
        repo_to = tree_to.branch.repository
299
        self.assertTrue(repo_to.has_revision('from-1'))
300
        self.assertFalse(repo_to.has_revision('from-2'))
301
        self.assertEqual(tree_to.branch.last_revision_info()[1], 'from-1')
302
3256.1.4 by Daniel Watkins
Added test to ensure that passing a range of revisions errors.
303
        self.run_bzr_error(
4325.4.6 by Vincent Ladeuil
Fixed as per John's and Markus reviews.
304
            ['bzr: ERROR: bzr push --revision '
305
             'takes exactly one revision identifier\n'],
3256.1.4 by Daniel Watkins
Added test to ensure that passing a range of revisions errors.
306
            'push -r0..2 ../to', working_dir='from')
307
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
308
    def create_trunk_and_feature_branch(self):
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
309
        # We have a mainline
310
        trunk_tree = self.make_branch_and_tree('target',
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
311
            format='1.9')
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
312
        trunk_tree.commit('mainline')
313
        # and a branch from it
314
        branch_tree = self.make_branch_and_tree('branch',
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
315
            format='1.9')
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
316
        branch_tree.pull(trunk_tree.branch)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
317
        branch_tree.branch.set_parent(trunk_tree.branch.base)
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
318
        # with some work on it
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
319
        branch_tree.commit('moar work plz')
320
        return trunk_tree, branch_tree
321
3221.11.14 by Robert Collins
Refactor to reduce duplication.
322
    def assertPublished(self, branch_revid, stacked_on):
323
        """Assert that the branch 'published' has been published correctly."""
4420.1.1 by Vincent Ladeuil
Cleanup imports.
324
        published_branch = branch.Branch.open('published')
3221.11.14 by Robert Collins
Refactor to reduce duplication.
325
        # The published branch refers to the mainline
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
326
        self.assertEqual(stacked_on, published_branch.get_stacked_on_url())
3221.11.14 by Robert Collins
Refactor to reduce duplication.
327
        # and the branch's work was pushed
328
        self.assertTrue(published_branch.repository.has_revision(branch_revid))
329
3549.1.1 by Martin Pool
rename push --reference to --stacked-on
330
    def test_push_new_branch_stacked_on(self):
331
        """Pushing a new branch with --stacked-on creates a stacked branch."""
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
332
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
333
        # we publish branch_tree with a reference to the mainline.
3549.1.1 by Martin Pool
rename push --reference to --stacked-on
334
        out, err = self.run_bzr(['push', '--stacked-on', trunk_tree.branch.base,
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
335
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
336
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
337
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
338
            trunk_tree.branch.base, err)
3221.11.14 by Robert Collins
Refactor to reduce duplication.
339
        self.assertPublished(branch_tree.last_revision(),
340
            trunk_tree.branch.base)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
341
3221.19.4 by Ian Clatworthy
shallow -> stacked
342
    def test_push_new_branch_stacked_uses_parent_when_no_public_url(self):
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
343
        """When the parent has no public url the parent is used as-is."""
344
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
3221.19.4 by Ian Clatworthy
shallow -> stacked
345
        # now we do a stacked push, which should determine the public location
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
346
        # for us.
3221.19.4 by Ian Clatworthy
shallow -> stacked
347
        out, err = self.run_bzr(['push', '--stacked',
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
348
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
349
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
350
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
351
            trunk_tree.branch.base, err)
4420.1.1 by Vincent Ladeuil
Cleanup imports.
352
        self.assertPublished(branch_tree.last_revision(),
353
                             trunk_tree.branch.base)
3221.11.17 by Robert Collins
no public location causes the parent to be used directly with push --shallow.
354
3221.19.4 by Ian Clatworthy
shallow -> stacked
355
    def test_push_new_branch_stacked_uses_parent_public(self):
356
        """Pushing a new branch with --stacked creates a stacked branch."""
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
357
        trunk_tree, branch_tree = self.create_trunk_and_feature_branch()
358
        # the trunk is published on a web server
4420.1.1 by Vincent Ladeuil
Cleanup imports.
359
        self.transport_readonly_server = http_server.HttpServer
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
360
        trunk_public = self.make_branch('public_trunk', format='1.9')
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
361
        trunk_public.pull(trunk_tree.branch)
362
        trunk_public_url = self.get_readonly_url('public_trunk')
363
        trunk_tree.branch.set_public_branch(trunk_public_url)
3221.19.4 by Ian Clatworthy
shallow -> stacked
364
        # now we do a stacked push, which should determine the public location
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
365
        # for us.
3221.19.4 by Ian Clatworthy
shallow -> stacked
366
        out, err = self.run_bzr(['push', '--stacked',
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
367
            self.get_url('published')], working_dir='branch')
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
368
        self.assertEqual('', out)
3221.19.4 by Ian Clatworthy
shallow -> stacked
369
        self.assertEqual('Created new stacked branch referring to %s.\n' %
3978.2.2 by Jelmer Vernooij
Write status messages during push to stderr rather than stdout.
370
            trunk_public_url, err)
3221.11.14 by Robert Collins
Refactor to reduce duplication.
371
        self.assertPublished(branch_tree.last_revision(), trunk_public_url)
3221.11.12 by Robert Collins
Basic push --reference support, requires url, slow.
372
3221.19.4 by Ian Clatworthy
shallow -> stacked
373
    def test_push_new_branch_stacked_no_parent(self):
374
        """Pushing with --stacked and no parent branch errors."""
4241.6.8 by Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil
Add --development6-rich-root, disabling the legacy and unneeded development2 format, and activating the tests for CHK features disabled pending this format. (Robert Collins, John Arbash Meinel, Ian Clatworthy, Vincent Ladeuil)
375
        branch = self.make_branch_and_tree('branch', format='1.9')
3221.19.4 by Ian Clatworthy
shallow -> stacked
376
        # now we do a stacked push, which should fail as the place to refer too
3221.11.15 by Robert Collins
no parent branch causes an error on push --shallow.
377
        # cannot be determined.
378
        out, err = self.run_bzr_error(
3221.19.4 by Ian Clatworthy
shallow -> stacked
379
            ['Could not determine branch to refer to\\.'], ['push', '--stacked',
3221.11.15 by Robert Collins
no parent branch causes an error on push --shallow.
380
            self.get_url('published')], working_dir='branch')
381
        self.assertEqual('', out)
382
        self.assertFalse(self.get_transport('published').has('.'))
383
3606.8.3 by John Arbash Meinel
push doesn't notify because it doesn't notice by default.
384
    def test_push_notifies_default_stacking(self):
3735.1.2 by Robert Collins
Remove 1.5 series dev formats and document development2 a little better.
385
        self.make_branch('stack_on', format='1.6')
3242.3.34 by Aaron Bentley
Add notification of default stacking
386
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
3735.1.2 by Robert Collins
Remove 1.5 series dev formats and document development2 a little better.
387
        self.make_branch('from', format='1.6')
3242.3.34 by Aaron Bentley
Add notification of default stacking
388
        out, err = self.run_bzr('push -d from to')
3641.1.1 by John Arbash Meinel
Merge in 1.6rc5 and revert disabling default stack on policy
389
        self.assertContainsRe(err,
390
                              'Using default stacking branch stack_on at .*')
3242.3.34 by Aaron Bentley
Add notification of default stacking
391
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
392
    def test_push_stacks_with_default_stacking_if_target_is_stackable(self):
393
        self.make_branch('stack_on', format='1.6')
394
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
395
        self.make_branch('from', format='pack-0.92')
396
        out, err = self.run_bzr('push -d from to')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
397
        b = branch.Branch.open('to')
398
        self.assertEqual('../stack_on', b.get_stacked_on_url())
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
399
400
    def test_push_does_not_change_format_with_default_if_target_cannot(self):
401
        self.make_branch('stack_on', format='pack-0.92')
402
        self.make_bzrdir('.').get_config().set_default_stack_on('stack_on')
403
        self.make_branch('from', format='pack-0.92')
404
        out, err = self.run_bzr('push -d from to')
4420.1.1 by Vincent Ladeuil
Cleanup imports.
405
        b = branch.Branch.open('to')
406
        self.assertRaises(errors.UnstackableBranchFormat, b.get_stacked_on_url)
4165.2.1 by Robert Collins
Fix bzr failing to stack when a server requests it and the branch it is pushing from cannot stack but the branch it should stack on can.
407
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
408
    def test_push_doesnt_create_broken_branch(self):
3904.3.7 by Andrew Bennetts
Comment the new tests.
409
        """Pushing a new standalone branch works even when there's a default
410
        stacking policy at the destination.
411
412
        The new branch will preserve the repo format (even if it isn't the
413
        default for the branch), and will be stacked when the repo format
414
        allows (which means that the branch format isn't necessarly preserved).
415
        """
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
416
        self.make_repository('repo', shared=True, format='1.6')
417
        builder = self.make_branch_builder('repo/local', format='pack-0.92')
418
        builder.start_series()
419
        builder.build_snapshot('rev-1', None, [
420
            ('add', ('', 'root-id', 'directory', '')),
3904.3.3 by Andrew Bennetts
Simplify test slightly.
421
            ('add', ('filename', 'f-id', 'file', 'content\n'))])
422
        builder.build_snapshot('rev-2', ['rev-1'], [])
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
423
        builder.build_snapshot('rev-3', ['rev-2'],
3904.3.3 by Andrew Bennetts
Simplify test slightly.
424
            [('modify', ('f-id', 'new-content\n'))])
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
425
        builder.finish_series()
426
        branch = builder.get_branch()
3904.3.7 by Andrew Bennetts
Comment the new tests.
427
        # Push rev-1 to "trunk", so that we can stack on it.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
428
        self.run_bzr('push -d repo/local trunk -r 1')
3904.3.7 by Andrew Bennetts
Comment the new tests.
429
        # Set a default stacking policy so that new branches will automatically
430
        # stack on trunk.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
431
        self.make_bzrdir('.').get_config().set_default_stack_on('trunk')
3904.3.7 by Andrew Bennetts
Comment the new tests.
432
        # Push rev-2 to a new branch "remote".  It will be stacked on "trunk".
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
433
        out, err = self.run_bzr('push -d repo/local remote -r 2')
434
        self.assertContainsRe(
435
            err, 'Using default stacking branch trunk at .*')
3904.3.7 by Andrew Bennetts
Comment the new tests.
436
        # Push rev-3 onto "remote".  If "remote" not stacked and is missing the
437
        # fulltext record for f-id @ rev-1, then this will fail.
3904.3.2 by Andrew Bennetts
Blackbox test that triggers the bug. Should get replaced with a unit test.
438
        out, err = self.run_bzr('push -d repo/local remote -r 3')
439
3848.1.19 by Aaron Bentley
Show log for non-initial push -v
440
    def test_push_verbose_shows_log(self):
441
        tree = self.make_branch_and_tree('source')
442
        tree.commit('rev1')
443
        out, err = self.run_bzr('push -v -d source target')
444
        # initial push contains log
445
        self.assertContainsRe(out, 'rev1')
446
        tree.commit('rev2')
447
        out, err = self.run_bzr('push -v -d source target')
448
        # subsequent push contains log
449
        self.assertContainsRe(out, 'rev2')
450
        # subsequent log is accurate
451
        self.assertNotContainsRe(out, 'rev1')
452
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
453
4420.1.1 by Vincent Ladeuil
Cleanup imports.
454
class RedirectingMemoryTransport(memory.MemoryTransport):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
455
3878.4.4 by Vincent Ladeuil
Cleanup.
456
    def mkdir(self, relpath, mode=None):
457
        from bzrlib.trace import mutter
458
        if self._cwd == '/source/':
459
            raise errors.RedirectRequested(self.abspath(relpath),
460
                                           self.abspath('../target'),
461
                                           is_permanent=True)
462
        elif self._cwd == '/infinite-loop/':
463
            raise errors.RedirectRequested(self.abspath(relpath),
464
                                           self.abspath('../infinite-loop'),
465
                                           is_permanent=True)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
466
        else:
467
            return super(RedirectingMemoryTransport, self).mkdir(
3878.4.4 by Vincent Ladeuil
Cleanup.
468
                relpath, mode)
469
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
470
    def _redirected_to(self, source, target):
3878.4.4 by Vincent Ladeuil
Cleanup.
471
        # We do accept redirections
3878.4.5 by Vincent Ladeuil
Don't use the exception as a parameter for _redirected_to.
472
        return transport.get_transport(target)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
473
474
4420.1.1 by Vincent Ladeuil
Cleanup imports.
475
class RedirectingMemoryServer(memory.MemoryServer):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
476
477
    def setUp(self):
478
        self._dirs = {'/': None}
479
        self._files = {}
480
        self._locks = {}
481
        self._scheme = 'redirecting-memory+%s:///' % id(self)
3878.4.4 by Vincent Ladeuil
Cleanup.
482
        transport.register_transport(self._scheme, self._memory_factory)
3066.3.3 by jml at canonical
Unregister the test transport in order to be clean and to make test_selftest pass.
483
484
    def _memory_factory(self, url):
485
        result = RedirectingMemoryTransport(url)
486
        result._dirs = self._dirs
487
        result._files = self._files
488
        result._locks = self._locks
489
        return result
490
491
    def tearDown(self):
3878.4.4 by Vincent Ladeuil
Cleanup.
492
        transport.unregister_transport(self._scheme, self._memory_factory)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
493
494
4420.1.1 by Vincent Ladeuil
Cleanup imports.
495
class TestPushRedirect(tests.TestCaseWithTransport):
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
496
497
    def setUp(self):
4420.1.1 by Vincent Ladeuil
Cleanup imports.
498
        tests.TestCaseWithTransport.setUp(self)
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
499
        self.memory_server = RedirectingMemoryServer()
500
        self.memory_server.setUp()
501
        self.addCleanup(self.memory_server.tearDown)
502
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
503
        # Make the branch and tree that we'll be pushing.
504
        t = self.make_branch_and_tree('tree')
505
        self.build_tree(['tree/file'])
506
        t.add('file')
507
        t.commit('commit 1')
508
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
509
    def test_push_redirects_on_mkdir(self):
510
        """If the push requires a mkdir, push respects redirect requests.
511
512
        This is added primarily to handle lp:/ URI support, so that users can
513
        push to new branches by specifying lp:/ URIs.
514
        """
515
        destination_url = self.memory_server.get_url() + 'source'
3878.4.4 by Vincent Ladeuil
Cleanup.
516
        self.run_bzr(['push', '-d', 'tree', destination_url])
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
517
4420.1.1 by Vincent Ladeuil
Cleanup imports.
518
        local_revision = branch.Branch.open('tree').last_revision()
519
        remote_revision = branch.Branch.open(
3066.3.1 by jml at canonical
Catch redirects raised by mkdir() in the push command. This is primarily
520
            self.memory_server.get_url() + 'target').last_revision()
521
        self.assertEqual(remote_revision, local_revision)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
522
523
    def test_push_gracefully_handles_too_many_redirects(self):
524
        """Push fails gracefully if the mkdir generates a large number of
525
        redirects.
526
        """
527
        destination_url = self.memory_server.get_url() + 'infinite-loop'
528
        out, err = self.run_bzr_error(
529
            ['Too many redirections trying to make %s\\.\n'
530
             % re.escape(destination_url)],
3878.4.4 by Vincent Ladeuil
Cleanup.
531
            ['push', '-d', 'tree', destination_url], retcode=3)
3066.3.2 by jml at canonical
Add tests to check the handling of TooManyRedirections.
532
        self.assertEqual('', out)