1
# Copyright (C) 2005 Canonical Ltd
2
# -*- coding: utf-8 -*-
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.
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.
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
19
"""Black-box tests for bzr push."""
26
from bzrlib.branch import Branch
27
from bzrlib.bzrdir import BzrDir, BzrDirMetaFormat1
28
from bzrlib.osutils import abspath
29
from bzrlib.repository import RepositoryFormatKnit1
30
from bzrlib.tests.blackbox import ExternalBase
31
from bzrlib.uncommit import uncommit
32
from bzrlib.urlutils import local_path_from_url
33
from bzrlib.workingtree import WorkingTree
36
class TestPush(ExternalBase):
38
def test_push_remember(self):
39
"""Push changes from one branch to another and test push location."""
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'])
45
tree_a.commit('commit a')
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
50
self.build_tree(['branch_a/b'])
52
tree_a.commit('commit b')
53
self.build_tree(['branch_b/c'])
55
tree_b.commit('commit c')
56
# initial push location must be empty
57
self.assertEqual(None, branch_b.get_push_location())
59
# test push for failure without push location set
61
out = self.runbzr('push', retcode=3)
62
self.assertEquals(out,
63
('','bzr: ERROR: No push location known or specified.\n'))
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)
69
('', 'bzr: ERROR: No push location known or specified.\n'),
72
# test implicit --remember when no push location set, push fails
73
out = self.run_bzr('push', '../branch_b', retcode=3)
74
self.assertEquals(out,
75
('','bzr: ERROR: These branches have diverged. '
76
'Try using "merge" and then "push".\n'))
77
self.assertEquals(abspath(branch_a.get_push_location()),
78
abspath(branch_b.bzrdir.root_transport.base))
80
# test implicit --remember after resolving previous failure
81
uncommit(branch=branch_b, tree=tree_b)
82
transport.delete('branch_b/c')
83
out = self.run_bzr('push')
84
path = branch_a.get_push_location()
85
self.assertEquals(('Using saved location: %s\n'
86
% (local_path_from_url(path),)
87
, 'All changes applied successfully.\n'
88
'1 revision(s) pushed.\n'), out)
89
self.assertEqual(path,
90
branch_b.bzrdir.root_transport.base)
91
# test explicit --remember
92
self.run_bzr('push', '../branch_c', '--remember')
93
self.assertEquals(branch_a.get_push_location(),
94
branch_c.bzrdir.root_transport.base)
96
def test_push_without_tree(self):
97
# bzr push from a branch that does not have a checkout should work.
98
b = self.make_branch('.')
99
out, err = self.run_bzr('push', 'pushed-location')
100
self.assertEqual('', out)
101
self.assertEqual('0 revision(s) pushed.\n', err)
102
b2 = Branch.open('pushed-location')
103
self.assertEndsWith(b2.base, 'pushed-location/')
105
def test_push_new_branch_revision_count(self):
106
# bzr push of a branch with revisions to a new location
107
# should print the number of revisions equal to the length of the
109
t = self.make_branch_and_tree('tree')
110
self.build_tree(['tree/file'])
114
out, err = self.run_bzr('push', 'pushed-to')
116
self.assertEqual('', out)
117
self.assertEqual('1 revision(s) pushed.\n', err)
119
def test_push_only_pushes_history(self):
120
# Knit branches should only push the history for the current revision.
121
format = BzrDirMetaFormat1()
122
format.repository_format = RepositoryFormatKnit1()
123
shared_repo = self.make_repository('repo', format=format, shared=True)
124
shared_repo.set_make_working_trees(True)
126
def make_shared_tree(path):
127
shared_repo.bzrdir.root_transport.mkdir(path)
128
shared_repo.bzrdir.create_branch_convenience('repo/' + path)
129
return WorkingTree.open('repo/' + path)
130
tree_a = make_shared_tree('a')
131
self.build_tree(['repo/a/file'])
133
tree_a.commit('commit a-1', rev_id='a-1')
134
f = open('repo/a/file', 'ab')
135
f.write('more stuff\n')
137
tree_a.commit('commit a-2', rev_id='a-2')
139
tree_b = make_shared_tree('b')
140
self.build_tree(['repo/b/file'])
142
tree_b.commit('commit b-1', rev_id='b-1')
144
self.assertTrue(shared_repo.has_revision('a-1'))
145
self.assertTrue(shared_repo.has_revision('a-2'))
146
self.assertTrue(shared_repo.has_revision('b-1'))
148
# Now that we have a repository with shared files, make sure
149
# that things aren't copied out by a 'push'
151
self.run_bzr('push', '../../push-b')
152
pushed_tree = WorkingTree.open('../../push-b')
153
pushed_repo = pushed_tree.branch.repository
154
self.assertFalse(pushed_repo.has_revision('a-1'))
155
self.assertFalse(pushed_repo.has_revision('a-2'))
156
self.assertTrue(pushed_repo.has_revision('b-1'))
158
def test_push_funky_id(self):
159
t = self.make_branch_and_tree('tree')
161
self.build_tree(['filename'])
162
t.add('filename', 'funky-chars<>%&;"\'')
163
t.commit('commit filename')
164
self.run_bzr('push', '../new-tree')
166
def create_simple_tree(self):
167
tree = self.make_branch_and_tree('tree')
168
self.build_tree(['tree/a'])
169
tree.add(['a'], ['a-id'])
170
tree.commit('one', rev_id='r1')
173
def test_push_create_prefix(self):
174
"""'bzr push --create-prefix' will create leading directories."""
175
tree = self.create_simple_tree()
177
self.run_bzr_error(['Parent directory of ../new/tree does not exist'],
178
'push', '../new/tree',
180
self.run_bzr('push', '../new/tree', '--create-prefix',
182
new_tree = WorkingTree.open('new/tree')
183
self.assertEqual(tree.last_revision(), new_tree.last_revision())
184
self.failUnlessExists('new/tree/a')
186
def test_push_use_existing(self):
187
"""'bzr push --use-existing-dir' can push into an existing dir.
189
By default, 'bzr push' will not use an existing, non-versioned dir.
191
tree = self.create_simple_tree()
192
self.build_tree(['target/'])
194
self.run_bzr_error(['Target directory ../target already exists',
195
'Supply --use-existing-dir',
196
], 'push', '../target',
199
self.run_bzr('push', '--use-existing-dir', '../target',
202
new_tree = WorkingTree.open('target')
203
self.assertEqual(tree.last_revision(), new_tree.last_revision())
204
# The push should have created target/a
205
self.failUnlessExists('target/a')
207
def test_push_onto_repo(self):
208
"""We should be able to 'bzr push' into an existing bzrdir."""
209
tree = self.create_simple_tree()
210
repo = self.make_repository('repo', shared=True)
212
self.run_bzr('push', '../repo',
215
# Pushing onto an existing bzrdir will create a repository and
216
# branch as needed, but will only create a working tree if there was
218
self.assertRaises(errors.NoWorkingTree, WorkingTree.open, 'repo')
219
new_branch = Branch.open('repo')
220
self.assertEqual(tree.last_revision(), new_branch.last_revision())
222
def test_push_onto_just_bzrdir(self):
223
"""We don't handle when the target is just a bzrdir.
225
Because you shouldn't be able to create *just* a bzrdir in the wild.
227
# TODO: jam 20070109 Maybe it would be better to create the repository
229
tree = self.create_simple_tree()
230
a_bzrdir = self.make_bzrdir('dir')
232
self.run_bzr_error(['At ../dir you have a valid .bzr control'],
236
def test_push_inside_repository(self):
237
"""Push from one branch to another inside the same repository."""
238
repo = self.make_repository('repo', shared=True)
239
# This is a little bit trickier because make_branch_and_tree will not
240
# re-use a shared repository.
241
a_branch = BzrDir.create_branch_convenience('repo/tree')
242
tree = a_branch.bzrdir.open_workingtree()
243
self.build_tree(['repo/tree/a'])
247
to_branch = BzrDir.create_branch_convenience('repo/branch')
248
tree.branch.push(to_branch)