~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_push.py

  • Committer: mbp at sourcefrog
  • Date: 2007-02-13 05:22:39 UTC
  • mfrom: (2279 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2283.
  • Revision ID: mbp@sourcefrog.net-20070213052239-09atqsahwth6zdm1
(merge) trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 Canonical Ltd
 
2
# -*- coding: utf-8 -*-
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; either version 2 of the License, or
 
7
# (at your option) any later version.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU General Public License
 
15
# along with this program; if not, write to the Free Software
 
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 
 
18
 
 
19
"""Black-box tests for bzr push."""
 
20
 
 
21
import os
 
22
 
 
23
from bzrlib import (
 
24
    errors,
 
25
    )
 
26
import bzrlib
 
27
from bzrlib.branch import Branch
 
28
from bzrlib.bzrdir import BzrDirMetaFormat1
 
29
from bzrlib.osutils import abspath
 
30
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
 
31
from bzrlib.tests.blackbox import ExternalBase
 
32
from bzrlib.uncommit import uncommit
 
33
from bzrlib.urlutils import local_path_from_url
 
34
from bzrlib.workingtree import WorkingTree
 
35
 
 
36
 
 
37
class TestPush(ExternalBase):
 
38
 
 
39
    def test_push_remember(self):
 
40
        """Push changes from one branch to another and test push location."""
 
41
        transport = self.get_transport()
 
42
        tree_a = self.make_branch_and_tree('branch_a')
 
43
        branch_a = tree_a.branch
 
44
        self.build_tree(['branch_a/a'])
 
45
        tree_a.add('a')
 
46
        tree_a.commit('commit a')
 
47
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
 
48
        branch_b = tree_b.branch
 
49
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
 
50
        branch_c = tree_c.branch
 
51
        self.build_tree(['branch_a/b'])
 
52
        tree_a.add('b')
 
53
        tree_a.commit('commit b')
 
54
        self.build_tree(['branch_b/c'])
 
55
        tree_b.add('c')
 
56
        tree_b.commit('commit c')
 
57
        # initial push location must be empty
 
58
        self.assertEqual(None, branch_b.get_push_location())
 
59
 
 
60
        # test push for failure without push location set
 
61
        os.chdir('branch_a')
 
62
        out = self.runbzr('push', retcode=3)
 
63
        self.assertEquals(out,
 
64
                ('','bzr: ERROR: No push location known or specified.\n'))
 
65
 
 
66
        # test not remembered if cannot actually push
 
67
        self.run_bzr('push', '../path/which/doesnt/exist', retcode=3)
 
68
        out = self.run_bzr('push', retcode=3)
 
69
        self.assertEquals(
 
70
                ('', 'bzr: ERROR: No push location known or specified.\n'),
 
71
                out)
 
72
 
 
73
        # test implicit --remember when no push location set, push fails
 
74
        out = self.run_bzr('push', '../branch_b', retcode=3)
 
75
        self.assertEquals(out,
 
76
                ('','bzr: ERROR: These branches have diverged.  '
 
77
                    'Try using "merge" and then "push".\n'))
 
78
        self.assertEquals(abspath(branch_a.get_push_location()),
 
79
                          abspath(branch_b.bzrdir.root_transport.base))
 
80
 
 
81
        # test implicit --remember after resolving previous failure
 
82
        uncommit(branch=branch_b, tree=tree_b)
 
83
        transport.delete('branch_b/c')
 
84
        out = self.run_bzr('push')
 
85
        path = branch_a.get_push_location()
 
86
        self.assertEquals(('Using saved location: %s\n' 
 
87
                           % (local_path_from_url(path),)
 
88
                          , 'All changes applied successfully.\n'
 
89
                            '1 revision(s) pushed.\n'), out)
 
90
        self.assertEqual(path,
 
91
                         branch_b.bzrdir.root_transport.base)
 
92
        # test explicit --remember
 
93
        self.run_bzr('push', '../branch_c', '--remember')
 
94
        self.assertEquals(branch_a.get_push_location(),
 
95
                          branch_c.bzrdir.root_transport.base)
 
96
    
 
97
    def test_push_without_tree(self):
 
98
        # bzr push from a branch that does not have a checkout should work.
 
99
        b = self.make_branch('.')
 
100
        out, err = self.run_bzr('push', 'pushed-location')
 
101
        self.assertEqual('', out)
 
102
        self.assertEqual('0 revision(s) pushed.\n', err)
 
103
        b2 = bzrlib.branch.Branch.open('pushed-location')
 
104
        self.assertEndsWith(b2.base, 'pushed-location/')
 
105
 
 
106
    def test_push_new_branch_revision_count(self):
 
107
        # bzr push of a branch with revisions to a new location 
 
108
        # should print the number of revisions equal to the length of the 
 
109
        # local branch.
 
110
        t = self.make_branch_and_tree('tree')
 
111
        self.build_tree(['tree/file'])
 
112
        t.add('file')
 
113
        t.commit('commit 1')
 
114
        os.chdir('tree')
 
115
        out, err = self.run_bzr('push', 'pushed-to')
 
116
        os.chdir('..')
 
117
        self.assertEqual('', out)
 
118
        self.assertEqual('1 revision(s) pushed.\n', err)
 
119
 
 
120
    def test_push_only_pushes_history(self):
 
121
        # Knit branches should only push the history for the current revision.
 
122
        format = BzrDirMetaFormat1()
 
123
        format.repository_format = RepositoryFormatKnit1()
 
124
        shared_repo = self.make_repository('repo', format=format, shared=True)
 
125
        shared_repo.set_make_working_trees(True)
 
126
 
 
127
        def make_shared_tree(path):
 
128
            shared_repo.bzrdir.root_transport.mkdir(path)
 
129
            shared_repo.bzrdir.create_branch_convenience('repo/' + path)
 
130
            return WorkingTree.open('repo/' + path)
 
131
        tree_a = make_shared_tree('a')
 
132
        self.build_tree(['repo/a/file'])
 
133
        tree_a.add('file')
 
134
        tree_a.commit('commit a-1', rev_id='a-1')
 
135
        f = open('repo/a/file', 'ab')
 
136
        f.write('more stuff\n')
 
137
        f.close()
 
138
        tree_a.commit('commit a-2', rev_id='a-2')
 
139
 
 
140
        tree_b = make_shared_tree('b')
 
141
        self.build_tree(['repo/b/file'])
 
142
        tree_b.add('file')
 
143
        tree_b.commit('commit b-1', rev_id='b-1')
 
144
 
 
145
        self.assertTrue(shared_repo.has_revision('a-1'))
 
146
        self.assertTrue(shared_repo.has_revision('a-2'))
 
147
        self.assertTrue(shared_repo.has_revision('b-1'))
 
148
 
 
149
        # Now that we have a repository with shared files, make sure
 
150
        # that things aren't copied out by a 'push'
 
151
        os.chdir('repo/b')
 
152
        self.run_bzr('push', '../../push-b')
 
153
        pushed_tree = WorkingTree.open('../../push-b')
 
154
        pushed_repo = pushed_tree.branch.repository
 
155
        self.assertFalse(pushed_repo.has_revision('a-1'))
 
156
        self.assertFalse(pushed_repo.has_revision('a-2'))
 
157
        self.assertTrue(pushed_repo.has_revision('b-1'))
 
158
 
 
159
    def test_push_funky_id(self):
 
160
        t = self.make_branch_and_tree('tree')
 
161
        os.chdir('tree')
 
162
        self.build_tree(['filename'])
 
163
        t.add('filename', 'funky-chars<>%&;"\'')
 
164
        t.commit('commit filename')
 
165
        self.run_bzr('push', '../new-tree')
 
166
 
 
167
    def create_simple_tree(self):
 
168
        tree = self.make_branch_and_tree('tree')
 
169
        self.build_tree(['tree/a'])
 
170
        tree.add(['a'], ['a-id'])
 
171
        tree.commit('one', rev_id='r1')
 
172
        return tree
 
173
 
 
174
    def test_push_create_prefix(self):
 
175
        """'bzr push --create-prefix' will create leading directories."""
 
176
        tree = self.create_simple_tree()
 
177
 
 
178
        self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
 
179
                           'push', '../new/tree',
 
180
                           working_dir='tree')
 
181
        self.run_bzr('push', '../new/tree', '--create-prefix',
 
182
                     working_dir='tree')
 
183
        new_tree = WorkingTree.open('new/tree')
 
184
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
 
185
        self.failUnlessExists('new/tree/a')
 
186
 
 
187
    def test_push_use_existing(self):
 
188
        """'bzr push --use-existing-dir' can push into an existing dir.
 
189
 
 
190
        By default, 'bzr push' will not use an existing, non-versioned dir.
 
191
        """
 
192
        tree = self.create_simple_tree()
 
193
        self.build_tree(['target/'])
 
194
 
 
195
        self.run_bzr_error(['Target directory ../target already exists',
 
196
                            'Supply --use-existing-dir',
 
197
                           ], 'push', '../target',
 
198
                           working_dir='tree')
 
199
 
 
200
        self.run_bzr('push', '--use-existing-dir', '../target',
 
201
                     working_dir='tree')
 
202
 
 
203
        new_tree = WorkingTree.open('target')
 
204
        self.assertEqual(tree.last_revision(), new_tree.last_revision())
 
205
        # The push should have created target/a
 
206
        self.failUnlessExists('target/a')
 
207
 
 
208
    def test_push_onto_repo(self):
 
209
        """We should be able to 'bzr push' into an existing bzrdir."""
 
210
        tree = self.create_simple_tree()
 
211
        repo = self.make_repository('repo', shared=True)
 
212
 
 
213
        self.run_bzr('push', '../repo',
 
214
                     working_dir='tree')
 
215
 
 
216
        # Pushing onto an existing bzrdir will create a repository and
 
217
        # branch as needed, but will only create a working tree if there was
 
218
        # no BzrDir before.
 
219
        self.assertRaises(errors.NoWorkingTree, WorkingTree.open, 'repo')
 
220
        new_branch = Branch.open('repo')
 
221
        self.assertEqual(tree.last_revision(), new_branch.last_revision())
 
222
 
 
223
    def test_push_onto_just_bzrdir(self):
 
224
        """We don't handle when the target is just a bzrdir.
 
225
 
 
226
        Because you shouldn't be able to create *just* a bzrdir in the wild.
 
227
        """
 
228
        # TODO: jam 20070109 Maybe it would be better to create the repository
 
229
        #       if at this point
 
230
        tree = self.create_simple_tree()
 
231
        a_bzrdir = self.make_bzrdir('dir')
 
232
 
 
233
        self.run_bzr_error(['At ../dir you have a valid .bzr control'],
 
234
                'push', '../dir',
 
235
                working_dir='tree')