1
# Copyright (C) 2005 by Canonical Ltd
2
# -*- coding: utf-8 -*-
1
# Copyright (C) 2005, 2006 Canonical Ltd
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
6
5
# the Free Software Foundation; either version 2 of the License, or
7
6
# (at your option) any later version.
9
8
# This program is distributed in the hope that it will be useful,
10
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
11
# GNU General Public License for more details.
14
13
# You should have received a copy of the GNU General Public License
15
14
# along with this program; if not, write to the Free Software
16
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
"""Black-box tests for bzr pull.
18
"""Black-box tests for bzr pull."""
25
23
from bzrlib.branch import Branch
26
24
from bzrlib.tests.blackbox import ExternalBase
25
from bzrlib.uncommit import uncommit
26
from bzrlib import urlutils
28
29
class TestPull(ExternalBase):
30
31
def example_branch(test):
32
33
file('hello', 'wt').write('foo')
33
test.runbzr('add hello')
34
test.runbzr('commit -m setup hello')
34
test.run_bzr('add hello')
35
test.run_bzr('commit -m setup hello')
35
36
file('goodbye', 'wt').write('baz')
36
test.runbzr('add goodbye')
37
test.runbzr('commit -m setup goodbye')
37
test.run_bzr('add goodbye')
38
test.run_bzr('commit -m setup goodbye')
39
40
def test_pull(self):
40
41
"""Pull changes from one branch to another."""
44
45
self.example_branch()
45
self.runbzr('pull', retcode=3)
46
self.runbzr('missing', retcode=3)
47
self.runbzr('missing .')
48
self.runbzr('missing')
49
if sys.platform not in ('win32', 'cygwin'):
50
# This is equivalent to doing "bzr pull ."
51
# Which means that bzr creates 2 branches grabbing
52
# the same location, and tries to pull.
53
# However, 2 branches mean 2 locks on the same file
54
# which ultimately implies a deadlock.
55
# (non windows platforms allow multiple locks on the
56
# same file by the same calling process)
58
self.runbzr('pull /', retcode=3)
59
if sys.platform not in ('win32', 'cygwin'):
46
self.run_bzr('pull', retcode=3)
47
self.run_bzr('missing', retcode=3)
48
self.run_bzr('missing .')
49
self.run_bzr('missing')
50
# this will work on windows because we check for the same branch
51
# in pull - if it fails, it is a regression
53
self.run_bzr('pull /', retcode=3)
54
if sys.platform not in ('win32', 'cygwin'):
63
self.runbzr('branch a b')
58
self.run_bzr('branch a b')
67
self.runbzr('add subdir')
68
self.runbzr('commit -m blah --unchanged')
62
self.run_bzr('add subdir')
63
self.run_bzr('commit -m blah --unchanged')
70
65
a = Branch.open('.')
71
66
b = Branch.open('../b')
72
67
self.assertEquals(a.revision_history(), b.revision_history()[:-1])
73
self.runbzr('pull ../b')
68
self.run_bzr('pull ../b')
74
69
self.assertEquals(a.revision_history(), b.revision_history())
75
self.runbzr('commit -m blah2 --unchanged')
70
self.run_bzr('commit -m blah2 --unchanged')
77
self.runbzr('commit -m blah3 --unchanged')
72
self.run_bzr('commit -m blah3 --unchanged')
79
self.runbzr('pull ../a', retcode=3)
74
self.run_bzr('pull ../a', retcode=3)
81
self.runbzr('branch b overwriteme')
76
self.run_bzr('branch b overwriteme')
82
77
os.chdir('overwriteme')
83
self.runbzr('pull --overwrite ../a')
78
self.run_bzr('pull --overwrite ../a')
84
79
overwritten = Branch.open('.')
85
80
self.assertEqual(overwritten.revision_history(),
86
81
a.revision_history())
88
self.runbzr('merge ../b')
89
self.runbzr('commit -m blah4 --unchanged')
83
self.run_bzr('merge ../b')
84
self.run_bzr('commit -m blah4 --unchanged')
90
85
os.chdir('../b/subdir')
91
self.runbzr('pull ../../a')
86
self.run_bzr('pull ../../a')
92
87
self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
93
self.runbzr('commit -m blah5 --unchanged')
94
self.runbzr('commit -m blah6 --unchanged')
88
self.run_bzr('commit -m blah5 --unchanged')
89
self.run_bzr('commit -m blah6 --unchanged')
96
self.runbzr('pull ../a')
91
self.run_bzr('pull ../a')
98
self.runbzr('commit -m blah7 --unchanged')
99
self.runbzr('merge ../b')
100
self.runbzr('commit -m blah8 --unchanged')
101
self.runbzr('pull ../b')
102
self.runbzr('pull ../b')
93
self.run_bzr('commit -m blah7 --unchanged')
94
self.run_bzr('merge ../b')
95
self.run_bzr('commit -m blah8 --unchanged')
96
self.run_bzr('pull ../b')
97
self.run_bzr('pull ../b')
99
def test_pull_dash_d(self):
102
self.example_branch()
103
self.run_bzr('init ../b')
104
self.run_bzr('init ../c')
105
# pull into that branch
106
self.run_bzr('pull -d ../b .')
107
# pull into a branch specified by a url
108
c_url = urlutils.local_path_to_url('../c')
109
self.assertStartsWith(c_url, 'file://')
110
self.run_bzr('pull -d %s .' % c_url)
112
def test_pull_revision(self):
113
"""Pull some changes from one branch to another."""
117
self.example_branch()
118
file('hello2', 'wt').write('foo')
119
self.run_bzr('add hello2')
120
self.run_bzr('commit -m setup hello2')
121
file('goodbye2', 'wt').write('baz')
122
self.run_bzr('add goodbye2')
123
self.run_bzr('commit -m setup goodbye2')
126
self.run_bzr('branch -r 1 a b')
128
self.run_bzr('pull -r 2')
129
a = Branch.open('../a')
131
self.assertEquals(a.revno(),4)
132
self.assertEquals(b.revno(),2)
133
self.run_bzr('pull -r 3')
134
self.assertEquals(b.revno(),3)
135
self.run_bzr('pull -r 4')
136
self.assertEquals(a.revision_history(), b.revision_history())
104
139
def test_overwrite_uptodate(self):
105
140
# Make sure pull --overwrite overwrites
120
155
open('foo', 'wb').write('original\n')
122
bzr('commit', '-m', 'initial commit')
157
bzr(['commit', '-m', 'initial commit'])
125
bzr('branch', 'a', 'b')
128
163
open('foo', 'wb').write('changed\n')
129
bzr('commit', '-m', 'later change')
164
bzr(['commit', '-m', 'later change'])
131
166
open('foo', 'wb').write('another\n')
132
bzr('commit', '-m', 'a third change')
167
bzr(['commit', '-m', 'a third change'])
134
169
rev_history_a = get_rh(3)
138
bzr('commit', '-m', 'merge')
173
bzr('commit -m merge')
140
175
rev_history_b = get_rh(2)
142
bzr('pull', '--overwrite', '../a')
177
bzr('pull --overwrite ../a')
143
178
rev_history_b = get_rh(3)
145
180
self.assertEqual(rev_history_b, rev_history_a)
162
197
open('foo', 'wb').write('original\n')
164
bzr('commit', '-m', 'initial commit')
199
bzr(['commit', '-m', 'initial commit'])
167
bzr('branch', 'a', 'b')
170
205
open('foo', 'wb').write('changed\n')
171
bzr('commit', '-m', 'later change')
206
bzr(['commit', '-m', 'later change'])
173
208
open('foo', 'wb').write('another\n')
174
bzr('commit', '-m', 'a third change')
209
bzr(['commit', '-m', 'a third change'])
176
211
rev_history_a = get_rh(3)
180
bzr('commit', '-m', 'merge')
215
bzr('commit -m merge')
182
217
rev_history_b = get_rh(2)
185
220
open('foo', 'wb').write('a fourth change\n')
186
bzr('commit', '-m', 'a fourth change')
221
bzr(['commit', '-m', 'a fourth change'])
188
223
rev_history_a = get_rh(4)
190
225
# With convergence, we could just pull over the
191
226
# new change, but with --overwrite, we want to switch our history
193
bzr('pull', '--overwrite', '../a')
228
bzr('pull --overwrite ../a')
194
229
rev_history_b = get_rh(4)
196
231
self.assertEqual(rev_history_b, rev_history_a)
233
def test_pull_remember(self):
234
"""Pull changes from one branch to another and test parent location."""
235
transport = self.get_transport()
236
tree_a = self.make_branch_and_tree('branch_a')
237
branch_a = tree_a.branch
238
self.build_tree(['branch_a/a'])
240
tree_a.commit('commit a')
241
tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
242
branch_b = tree_b.branch
243
tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
244
branch_c = tree_c.branch
245
self.build_tree(['branch_a/b'])
247
tree_a.commit('commit b')
249
parent = branch_b.get_parent()
250
branch_b.set_parent(None)
251
self.assertEqual(None, branch_b.get_parent())
252
# test pull for failure without parent set
254
out = self.run_bzr('pull', retcode=3)
255
self.assertEquals(out,
256
('','bzr: ERROR: No pull location known or specified.\n'))
257
# test implicit --remember when no parent set, this pull conflicts
258
self.build_tree(['d'])
260
tree_b.commit('commit d')
261
out = self.run_bzr('pull ../branch_a', retcode=3)
262
self.assertEquals(out,
263
('','bzr: ERROR: These branches have diverged.'
264
' Use the merge command to reconcile them.\n'))
265
self.assertEquals(branch_b.get_parent(), parent)
266
# test implicit --remember after resolving previous failure
267
uncommit(branch=branch_b, tree=tree_b)
268
transport.delete('branch_b/d')
270
self.assertEquals(branch_b.get_parent(), parent)
271
# test explicit --remember
272
self.run_bzr('pull ../branch_c --remember')
273
self.assertEquals(branch_b.get_parent(),
274
branch_c.bzrdir.root_transport.base)
276
def test_pull_bundle(self):
277
from bzrlib.testament import Testament
278
# Build up 2 trees and prepare for a pull
279
tree_a = self.make_branch_and_tree('branch_a')
280
f = open('branch_a/a', 'wb')
284
tree_a.commit('message')
286
tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
288
# Make a change to 'a' that 'b' can pull
289
f = open('branch_a/a', 'wb')
292
tree_a.commit('message')
294
# Create the bundle for 'b' to pull
296
self.run_bzr('bundle ../branch_b -o ../bundle')
298
os.chdir('../branch_b')
299
out, err = self.run_bzr('pull ../bundle')
300
self.assertEqual(out,
301
'Now on revision 2.\n')
302
self.assertEqual(err,
303
' M a\nAll changes applied successfully.\n')
305
self.assertEqualDiff(tree_a.branch.revision_history(),
306
tree_b.branch.revision_history())
308
testament_a = Testament.from_revision(tree_a.branch.repository,
309
tree_a.get_parent_ids()[0])
310
testament_b = Testament.from_revision(tree_b.branch.repository,
311
tree_b.get_parent_ids()[0])
312
self.assertEqualDiff(testament_a.as_text(),
313
testament_b.as_text())
315
# it is legal to attempt to pull an already-merged bundle
316
out, err = self.run_bzr('pull ../bundle')
317
self.assertEqual(err, '')
318
self.assertEqual(out, 'No revisions to pull.\n')
320
def test_pull_verbose_no_files(self):
321
"""Pull --verbose should not list modified files"""
322
tree_a = self.make_branch_and_tree('tree_a')
323
self.build_tree(['tree_a/foo'])
326
tree_b = self.make_branch_and_tree('tree_b')
327
out = self.run_bzr('pull --verbose -d tree_b tree_a')[0]
328
self.assertContainsRe(out, 'bar')
329
self.assertNotContainsRe(out, 'added:')
330
self.assertNotContainsRe(out, 'foo')