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