~bzr-pqm/bzr/bzr.dev

2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
1
# Copyright (C) 2005, 2007 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
21
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
22
from bzrlib import (
23
    errors,
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
24
    urlutils,
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
25
    )
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
26
from bzrlib.branch import Branch
2279.1.3 by John Arbash Meinel
Switch the test to being a branch_implementation test.
27
from bzrlib.bzrdir import BzrDirMetaFormat1
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
28
from bzrlib.osutils import abspath
2241.1.6 by Martin Pool
Move Knit repositories into the submodule bzrlib.repofmt.knitrepo and
29
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
30
from bzrlib.tests.blackbox import ExternalBase
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
31
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.
32
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???)
33
from bzrlib.workingtree import WorkingTree
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
34
35
36
class TestPush(ExternalBase):
37
38
    def test_push_remember(self):
39
        """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.
40
        transport = self.get_transport()
41
        tree_a = self.make_branch_and_tree('branch_a')
42
        branch_a = tree_a.branch
43
        self.build_tree(['branch_a/a'])
44
        tree_a.add('a')
45
        tree_a.commit('commit a')
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
46
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
47
        branch_b = tree_b.branch
48
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
49
        branch_c = tree_c.branch
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
50
        self.build_tree(['branch_a/b'])
51
        tree_a.add('b')
52
        tree_a.commit('commit b')
53
        self.build_tree(['branch_b/c'])
54
        tree_b.add('c')
55
        tree_b.commit('commit c')
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
56
        # initial push location must be empty
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
57
        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)
58
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
59
        # test push for failure without push location set
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
60
        os.chdir('branch_a')
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
61
        out = self.runbzr('push', retcode=3)
62
        self.assertEquals(out,
63
                ('','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)
64
65
        # test not remembered if cannot actually push
66
        self.run_bzr('push', '../path/which/doesnt/exist', retcode=3)
67
        out = self.run_bzr('push', retcode=3)
68
        self.assertEquals(
69
                ('', 'bzr: ERROR: No push location known or specified.\n'),
70
                out)
71
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
72
        # test implicit --remember when no push location set, push fails
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
73
        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
74
        self.assertEquals(out,
75
                ('','bzr: ERROR: These branches have diverged.  '
2063.2.1 by John Arbash Meinel
(Matthieu Moy) cleanup message when pushing to diverged branch
76
                    'Try using "merge" and then "push".\n'))
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
77
        self.assertEquals(abspath(branch_a.get_push_location()),
78
                          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)
79
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
80
        # test implicit --remember after resolving previous failure
1614.2.16 by Olaf Conradi
Modified blackbox test cases to use bzrlib API.
81
        uncommit(branch=branch_b, tree=tree_b)
82
        transport.delete('branch_b/c')
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
83
        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.
84
        path = branch_a.get_push_location()
2220.2.38 by Martin Pool
Tag conflicts from push go to stdout.
85
        self.assertEquals(out,
86
                          'Using saved location: %s\n' 
87
                          'Pushed up to revision 2.\n'
88
                          % local_path_from_url(path))
89
        self.assertEqual(err,
90
                         '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.
91
        self.assertEqual(path,
92
                         branch_b.bzrdir.root_transport.base)
1614.2.9 by Olaf Conradi
Added testcases for using push with --remember. Moved remember code to
93
        # test explicit --remember
1785.1.1 by John Arbash Meinel
Fix the output of 'bzr push' so that it prints the location correctly.
94
        self.run_bzr('push', '../branch_c', '--remember')
95
        self.assertEquals(branch_a.get_push_location(),
96
                          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.
97
    
98
    def test_push_without_tree(self):
99
        # bzr push from a branch that does not have a checkout should work.
100
        b = self.make_branch('.')
101
        out, err = self.run_bzr('push', 'pushed-location')
102
        self.assertEqual('', out)
2297.1.4 by Martin Pool
Push now returns a PushResult rather than just an integer.
103
        self.assertEqual('Created new branch.\n', err)
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
104
        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.
105
        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).
106
107
    def test_push_new_branch_revision_count(self):
108
        # bzr push of a branch with revisions to a new location 
109
        # should print the number of revisions equal to the length of the 
110
        # local branch.
111
        t = self.make_branch_and_tree('tree')
112
        self.build_tree(['tree/file'])
113
        t.add('file')
114
        t.commit('commit 1')
115
        os.chdir('tree')
116
        out, err = self.run_bzr('push', 'pushed-to')
117
        os.chdir('..')
118
        self.assertEqual('', out)
2297.1.4 by Martin Pool
Push now returns a PushResult rather than just an integer.
119
        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???)
120
121
    def test_push_only_pushes_history(self):
122
        # Knit branches should only push the history for the current revision.
123
        format = BzrDirMetaFormat1()
124
        format.repository_format = RepositoryFormatKnit1()
125
        shared_repo = self.make_repository('repo', format=format, shared=True)
126
        shared_repo.set_make_working_trees(True)
127
128
        def make_shared_tree(path):
129
            shared_repo.bzrdir.root_transport.mkdir(path)
130
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
131
            return WorkingTree.open('repo/' + path)
132
        tree_a = make_shared_tree('a')
133
        self.build_tree(['repo/a/file'])
134
        tree_a.add('file')
135
        tree_a.commit('commit a-1', rev_id='a-1')
136
        f = open('repo/a/file', 'ab')
137
        f.write('more stuff\n')
138
        f.close()
139
        tree_a.commit('commit a-2', rev_id='a-2')
140
141
        tree_b = make_shared_tree('b')
142
        self.build_tree(['repo/b/file'])
143
        tree_b.add('file')
144
        tree_b.commit('commit b-1', rev_id='b-1')
145
146
        self.assertTrue(shared_repo.has_revision('a-1'))
147
        self.assertTrue(shared_repo.has_revision('a-2'))
148
        self.assertTrue(shared_repo.has_revision('b-1'))
149
150
        # Now that we have a repository with shared files, make sure
151
        # that things aren't copied out by a 'push'
152
        os.chdir('repo/b')
153
        self.run_bzr('push', '../../push-b')
154
        pushed_tree = WorkingTree.open('../../push-b')
155
        pushed_repo = pushed_tree.branch.repository
156
        self.assertFalse(pushed_repo.has_revision('a-1'))
157
        self.assertFalse(pushed_repo.has_revision('a-2'))
158
        self.assertTrue(pushed_repo.has_revision('b-1'))
159
1843.2.1 by Aaron Bentley
Add failing tests for funky ids
160
    def test_push_funky_id(self):
161
        t = self.make_branch_and_tree('tree')
162
        os.chdir('tree')
163
        self.build_tree(['filename'])
164
        t.add('filename', 'funky-chars<>%&;"\'')
165
        t.commit('commit filename')
166
        self.run_bzr('push', '../new-tree')
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
167
2220.2.9 by Martin Pool
Add specific tests for push -d and pull -d
168
    def test_push_dash_d(self):
169
        t = self.make_branch_and_tree('from')
170
        t.commit(allow_pointless=True,
171
                message='first commit')
172
        self.runbzr('push -d from to-one')
173
        self.failUnlessExists('to-one')
174
        self.runbzr('push -d %s %s' 
175
            % tuple(map(urlutils.local_path_to_url, ['from', 'to-two'])))
176
        self.failUnlessExists('to-two')
2279.3.1 by mbp at sourcefrog
Add a -d option to push, pull, merge (ported from tags branch)
177
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
178
    def create_simple_tree(self):
179
        tree = self.make_branch_and_tree('tree')
180
        self.build_tree(['tree/a'])
181
        tree.add(['a'], ['a-id'])
182
        tree.commit('one', rev_id='r1')
183
        return tree
184
185
    def test_push_create_prefix(self):
186
        """'bzr push --create-prefix' will create leading directories."""
187
        tree = self.create_simple_tree()
188
189
        self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
190
                           'push', '../new/tree',
191
                           working_dir='tree')
192
        self.run_bzr('push', '../new/tree', '--create-prefix',
193
                     working_dir='tree')
194
        new_tree = WorkingTree.open('new/tree')
195
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
196
        self.failUnlessExists('new/tree/a')
197
198
    def test_push_use_existing(self):
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
199
        """'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
200
201
        By default, 'bzr push' will not use an existing, non-versioned dir.
202
        """
203
        tree = self.create_simple_tree()
204
        self.build_tree(['target/'])
205
206
        self.run_bzr_error(['Target directory ../target already exists',
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
207
                            'Supply --use-existing-dir',
2227.3.1 by John Arbash Meinel
Allow push to create Branch when necessary, and add --use-existing
208
                           ], 'push', '../target',
209
                           working_dir='tree')
2227.3.4 by John Arbash Meinel
Switch back to --use-existing-dir
210
211
        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
212
                     working_dir='tree')
213
214
        new_tree = WorkingTree.open('target')
215
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
216
        # The push should have created target/a
217
        self.failUnlessExists('target/a')
218
219
    def test_push_onto_repo(self):
220
        """We should be able to 'bzr push' into an existing bzrdir."""
221
        tree = self.create_simple_tree()
222
        repo = self.make_repository('repo', shared=True)
223
224
        self.run_bzr('push', '../repo',
225
                     working_dir='tree')
226
227
        # Pushing onto an existing bzrdir will create a repository and
228
        # branch as needed, but will only create a working tree if there was
229
        # no BzrDir before.
230
        self.assertRaises(errors.NoWorkingTree, WorkingTree.open, 'repo')
231
        new_branch = Branch.open('repo')
232
        self.assertEqual(tree.last_revision(), new_branch.last_revision())
233
234
    def test_push_onto_just_bzrdir(self):
235
        """We don't handle when the target is just a bzrdir.
236
237
        Because you shouldn't be able to create *just* a bzrdir in the wild.
238
        """
239
        # TODO: jam 20070109 Maybe it would be better to create the repository
240
        #       if at this point
241
        tree = self.create_simple_tree()
242
        a_bzrdir = self.make_bzrdir('dir')
243
244
        self.run_bzr_error(['At ../dir you have a valid .bzr control'],
245
                'push', '../dir',
246
                working_dir='tree')