~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-08-23 00:18:12 UTC
  • mfrom: (2743.1.5 misc-fixen)
  • Revision ID: pqm@pqm.ubuntu.com-20070823001812-eermtd2vfr5o6b7o
(robertc) Several minor miscellaneous code cleanup fixes. (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
# -*- coding: utf-8 -*-
3
 
 
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#
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.
8
 
 
 
7
#
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.
13
 
 
 
12
#
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
17
16
 
18
17
 
19
 
"""Black-box tests for bzr pull.
20
 
"""
 
18
"""Black-box tests for bzr pull."""
21
19
 
22
20
import os
23
21
import sys
24
22
 
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
 
27
 
27
28
 
28
29
class TestPull(ExternalBase):
29
30
 
30
31
    def example_branch(test):
31
 
        test.runbzr('init')
 
32
        test.run_bzr('init')
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')
38
39
 
39
40
    def test_pull(self):
40
41
        """Pull changes from one branch to another."""
42
43
        os.chdir('a')
43
44
 
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)
57
 
            self.runbzr('pull')
58
 
        self.runbzr('pull /', retcode=3)
59
 
        if sys.platform not in ('win32', 'cygwin'):
60
 
            self.runbzr('pull')
 
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
 
52
        self.run_bzr('pull')
 
53
        self.run_bzr('pull /', retcode=3)
 
54
        if sys.platform not in ('win32', 'cygwin'):
 
55
            self.run_bzr('pull')
61
56
 
62
57
        os.chdir('..')
63
 
        self.runbzr('branch a b')
 
58
        self.run_bzr('branch a b')
64
59
        os.chdir('b')
65
 
        self.runbzr('pull')
 
60
        self.run_bzr('pull')
66
61
        os.mkdir('subdir')
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')
69
64
        os.chdir('../a')
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')
76
71
        os.chdir('../b')
77
 
        self.runbzr('commit -m blah3 --unchanged')
 
72
        self.run_bzr('commit -m blah3 --unchanged')
78
73
        # no overwrite
79
 
        self.runbzr('pull ../a', retcode=3)
 
74
        self.run_bzr('pull ../a', retcode=3)
80
75
        os.chdir('..')
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())
87
82
        os.chdir('../a')
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')
95
90
        os.chdir('..')
96
 
        self.runbzr('pull ../a')
 
91
        self.run_bzr('pull ../a')
97
92
        os.chdir('../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')
 
98
 
 
99
    def test_pull_dash_d(self):
 
100
        os.mkdir('a')
 
101
        os.chdir('a')
 
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)
 
111
 
 
112
    def test_pull_revision(self):
 
113
        """Pull some changes from one branch to another."""
 
114
        os.mkdir('a')
 
115
        os.chdir('a')
 
116
 
 
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')
 
124
 
 
125
        os.chdir('..')
 
126
        self.run_bzr('branch -r 1 a b')
 
127
        os.chdir('b')
 
128
        self.run_bzr('pull -r 2')
 
129
        a = Branch.open('../a')
 
130
        b = Branch.open('.')
 
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())
 
137
 
103
138
 
104
139
    def test_overwrite_uptodate(self):
105
140
        # Make sure pull --overwrite overwrites
108
143
        bzr = self.run_bzr
109
144
 
110
145
        def get_rh(expected_len):
111
 
            rh = self.capture('revision-history')
 
146
            rh = self.run_bzr('revision-history')[0]
112
147
            # Make sure we don't have trailing empty revisions
113
148
            rh = rh.strip().split('\n')
114
149
            self.assertEqual(len(rh), expected_len)
118
153
        os.chdir('a')
119
154
        bzr('init')
120
155
        open('foo', 'wb').write('original\n')
121
 
        bzr('add', 'foo')
122
 
        bzr('commit', '-m', 'initial commit')
 
156
        bzr('add foo')
 
157
        bzr(['commit', '-m', 'initial commit'])
123
158
 
124
159
        os.chdir('..')
125
 
        bzr('branch', 'a', 'b')
 
160
        bzr('branch a b')
126
161
 
127
162
        os.chdir('a')
128
163
        open('foo', 'wb').write('changed\n')
129
 
        bzr('commit', '-m', 'later change')
 
164
        bzr(['commit', '-m', 'later change'])
130
165
 
131
166
        open('foo', 'wb').write('another\n')
132
 
        bzr('commit', '-m', 'a third change')
 
167
        bzr(['commit', '-m', 'a third change'])
133
168
 
134
169
        rev_history_a = get_rh(3)
135
170
 
136
171
        os.chdir('../b')
137
 
        bzr('merge', '../a')
138
 
        bzr('commit', '-m', 'merge')
 
172
        bzr('merge ../a')
 
173
        bzr('commit -m merge')
139
174
 
140
175
        rev_history_b = get_rh(2)
141
176
 
142
 
        bzr('pull', '--overwrite', '../a')
 
177
        bzr('pull --overwrite ../a')
143
178
        rev_history_b = get_rh(3)
144
179
 
145
180
        self.assertEqual(rev_history_b, rev_history_a)
150
185
        bzr = self.run_bzr
151
186
 
152
187
        def get_rh(expected_len):
153
 
            rh = self.capture('revision-history')
 
188
            rh = self.run_bzr('revision-history')[0]
154
189
            # Make sure we don't have trailing empty revisions
155
190
            rh = rh.strip().split('\n')
156
191
            self.assertEqual(len(rh), expected_len)
160
195
        os.chdir('a')
161
196
        bzr('init')
162
197
        open('foo', 'wb').write('original\n')
163
 
        bzr('add', 'foo')
164
 
        bzr('commit', '-m', 'initial commit')
 
198
        bzr('add foo')
 
199
        bzr(['commit', '-m', 'initial commit'])
165
200
 
166
201
        os.chdir('..')
167
 
        bzr('branch', 'a', 'b')
 
202
        bzr('branch a b')
168
203
 
169
204
        os.chdir('a')
170
205
        open('foo', 'wb').write('changed\n')
171
 
        bzr('commit', '-m', 'later change')
 
206
        bzr(['commit', '-m', 'later change'])
172
207
 
173
208
        open('foo', 'wb').write('another\n')
174
 
        bzr('commit', '-m', 'a third change')
 
209
        bzr(['commit', '-m', 'a third change'])
175
210
 
176
211
        rev_history_a = get_rh(3)
177
212
 
178
213
        os.chdir('../b')
179
 
        bzr('merge', '../a')
180
 
        bzr('commit', '-m', 'merge')
 
214
        bzr('merge ../a')
 
215
        bzr('commit -m merge')
181
216
 
182
217
        rev_history_b = get_rh(2)
183
218
 
184
219
        os.chdir('../a')
185
220
        open('foo', 'wb').write('a fourth change\n')
186
 
        bzr('commit', '-m', 'a fourth change')
 
221
        bzr(['commit', '-m', 'a fourth change'])
187
222
 
188
223
        rev_history_a = get_rh(4)
189
224
 
190
225
        # With convergence, we could just pull over the
191
226
        # new change, but with --overwrite, we want to switch our history
192
227
        os.chdir('../b')
193
 
        bzr('pull', '--overwrite', '../a')
 
228
        bzr('pull --overwrite ../a')
194
229
        rev_history_b = get_rh(4)
195
230
 
196
231
        self.assertEqual(rev_history_b, rev_history_a)
197
232
 
198
 
 
 
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'])
 
239
        tree_a.add('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'])
 
246
        tree_a.add('b')
 
247
        tree_a.commit('commit b')
 
248
        # reset parent
 
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
 
253
        os.chdir('branch_b')
 
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'])
 
259
        tree_b.add('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')
 
269
        self.run_bzr('pull')
 
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)
 
275
 
 
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')
 
281
        f.write('hello')
 
282
        f.close()
 
283
        tree_a.add('a')
 
284
        tree_a.commit('message')
 
285
 
 
286
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
 
287
 
 
288
        # Make a change to 'a' that 'b' can pull
 
289
        f = open('branch_a/a', 'wb')
 
290
        f.write('hey there')
 
291
        f.close()
 
292
        tree_a.commit('message')
 
293
 
 
294
        # Create the bundle for 'b' to pull
 
295
        os.chdir('branch_a')
 
296
        self.run_bzr('bundle ../branch_b -o ../bundle')
 
297
 
 
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')
 
304
 
 
305
        self.assertEqualDiff(tree_a.branch.revision_history(),
 
306
                             tree_b.branch.revision_history())
 
307
 
 
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())
 
314
 
 
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')
 
319
 
 
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'])
 
324
        tree_a.add('foo')
 
325
        tree_a.commit('bar')
 
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')