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