/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-03-20 07:46:42 UTC
  • mfrom: (1551.19.30 Aaron's mergeable stuff)
  • Revision ID: pqm@pqm.ubuntu.com-20080320074642-46bf1vcpyubnaptz
Speed up merge by avoiding unnecessary file-existence checks
        (abentley)

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
 
from bzrlib.osutils import abspath
 
24
from bzrlib.osutils import pathjoin
27
25
from bzrlib.tests.blackbox import ExternalBase
28
26
from bzrlib.uncommit import uncommit
 
27
from bzrlib.workingtree import WorkingTree
 
28
from bzrlib import urlutils
29
29
 
30
30
 
31
31
class TestPull(ExternalBase):
32
32
 
33
 
    def example_branch(test):
34
 
        test.runbzr('init')
35
 
        file('hello', 'wt').write('foo')
36
 
        test.runbzr('add hello')
37
 
        test.runbzr('commit -m setup hello')
38
 
        file('goodbye', 'wt').write('baz')
39
 
        test.runbzr('add goodbye')
40
 
        test.runbzr('commit -m setup goodbye')
 
33
    def example_branch(self, path='.'):
 
34
        tree = self.make_branch_and_tree(path)
 
35
        self.build_tree_contents([
 
36
            (pathjoin(path, 'hello'),   'foo'),
 
37
            (pathjoin(path, 'goodbye'), 'baz')])
 
38
        tree.add('hello')
 
39
        tree.commit(message='setup')
 
40
        tree.add('goodbye')
 
41
        tree.commit(message='setup')
 
42
        return tree
41
43
 
42
44
    def test_pull(self):
43
45
        """Pull changes from one branch to another."""
44
 
        os.mkdir('a')
 
46
        a_tree = self.example_branch('a')
45
47
        os.chdir('a')
46
 
 
47
 
        self.example_branch()
48
 
        self.runbzr('pull', retcode=3)
49
 
        self.runbzr('missing', retcode=3)
50
 
        self.runbzr('missing .')
51
 
        self.runbzr('missing')
52
 
        if sys.platform not in ('win32', 'cygwin'):
53
 
            # This is equivalent to doing "bzr pull ."
54
 
            # Which means that bzr creates 2 branches grabbing
55
 
            # the same location, and tries to pull.
56
 
            # However, 2 branches mean 2 locks on the same file
57
 
            # which ultimately implies a deadlock.
58
 
            # (non windows platforms allow multiple locks on the
59
 
            # same file by the same calling process)
60
 
            self.runbzr('pull')
61
 
        self.runbzr('pull /', retcode=3)
62
 
        if sys.platform not in ('win32', 'cygwin'):
63
 
            self.runbzr('pull')
 
48
        self.run_bzr('pull', retcode=3)
 
49
        self.run_bzr('missing', retcode=3)
 
50
        self.run_bzr('missing .')
 
51
        self.run_bzr('missing')
 
52
        # this will work on windows because we check for the same branch
 
53
        # in pull - if it fails, it is a regression
 
54
        self.run_bzr('pull')
 
55
        self.run_bzr('pull /', retcode=3)
 
56
        if sys.platform not in ('win32', 'cygwin'):
 
57
            self.run_bzr('pull')
64
58
 
65
59
        os.chdir('..')
66
 
        self.runbzr('branch a b')
 
60
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
67
61
        os.chdir('b')
68
 
        self.runbzr('pull')
 
62
        self.run_bzr('pull')
69
63
        os.mkdir('subdir')
70
 
        self.runbzr('add subdir')
71
 
        self.runbzr('commit -m blah --unchanged')
72
 
        os.chdir('../a')
73
 
        a = Branch.open('.')
74
 
        b = Branch.open('../b')
75
 
        self.assertEquals(a.revision_history(), b.revision_history()[:-1])
76
 
        self.runbzr('pull ../b')
77
 
        self.assertEquals(a.revision_history(), b.revision_history())
78
 
        self.runbzr('commit -m blah2 --unchanged')
79
 
        os.chdir('../b')
80
 
        self.runbzr('commit -m blah3 --unchanged')
 
64
        b_tree.add('subdir')
 
65
        b_tree.commit(message='blah', allow_pointless=True)
 
66
 
 
67
        os.chdir('..')
 
68
        a = Branch.open('a')
 
69
        b = Branch.open('b')
 
70
        self.assertEqual(a.revision_history(), b.revision_history()[:-1])
 
71
 
 
72
        os.chdir('a')
 
73
        self.run_bzr('pull ../b')
 
74
        self.assertEqual(a.revision_history(), b.revision_history())
 
75
        a_tree.commit(message='blah2', allow_pointless=True)
 
76
        b_tree.commit(message='blah3', allow_pointless=True)
81
77
        # no overwrite
82
 
        self.runbzr('pull ../a', retcode=3)
 
78
        os.chdir('../b')
 
79
        self.run_bzr('pull ../a', retcode=3)
83
80
        os.chdir('..')
84
 
        self.runbzr('branch b overwriteme')
 
81
        b_tree.bzrdir.sprout('overwriteme')
85
82
        os.chdir('overwriteme')
86
 
        self.runbzr('pull --overwrite ../a')
 
83
        self.run_bzr('pull --overwrite ../a')
87
84
        overwritten = Branch.open('.')
88
85
        self.assertEqual(overwritten.revision_history(),
89
86
                         a.revision_history())
90
 
        os.chdir('../a')
91
 
        self.runbzr('merge ../b')
92
 
        self.runbzr('commit -m blah4 --unchanged')
 
87
        a_tree.merge_from_branch(b_tree.branch)
 
88
        a_tree.commit(message="blah4", allow_pointless=True)
93
89
        os.chdir('../b/subdir')
94
 
        self.runbzr('pull ../../a')
95
 
        self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
96
 
        self.runbzr('commit -m blah5 --unchanged')
97
 
        self.runbzr('commit -m blah6 --unchanged')
 
90
        self.run_bzr('pull ../../a')
 
91
        self.assertEqual(a.revision_history()[-1], b.revision_history()[-1])
 
92
        sub_tree = WorkingTree.open_containing('.')[0]
 
93
        sub_tree.commit(message="blah5", allow_pointless=True)
 
94
        sub_tree.commit(message="blah6", allow_pointless=True)
98
95
        os.chdir('..')
99
 
        self.runbzr('pull ../a')
 
96
        self.run_bzr('pull ../a')
100
97
        os.chdir('../a')
101
 
        self.runbzr('commit -m blah7 --unchanged')
102
 
        self.runbzr('merge ../b')
103
 
        self.runbzr('commit -m blah8 --unchanged')
104
 
        self.runbzr('pull ../b')
105
 
        self.runbzr('pull ../b')
 
98
        a_tree.commit(message="blah7", allow_pointless=True)
 
99
        a_tree.merge_from_branch(b_tree.branch)
 
100
        a_tree.commit(message="blah8", allow_pointless=True)
 
101
        self.run_bzr('pull ../b')
 
102
        self.run_bzr('pull ../b')
 
103
 
 
104
    def test_pull_dash_d(self):
 
105
        self.example_branch('a')
 
106
        self.make_branch_and_tree('b')
 
107
        self.make_branch_and_tree('c')
 
108
        # pull into that branch
 
109
        self.run_bzr('pull -d b a')
 
110
        # pull into a branch specified by a url
 
111
        c_url = urlutils.local_path_to_url('c')
 
112
        self.assertStartsWith(c_url, 'file://')
 
113
        self.run_bzr(['pull', '-d', c_url, 'a'])
106
114
 
107
115
    def test_pull_revision(self):
108
116
        """Pull some changes from one branch to another."""
109
 
        os.mkdir('a')
110
 
        os.chdir('a')
111
 
 
112
 
        self.example_branch()
113
 
        file('hello2', 'wt').write('foo')
114
 
        self.runbzr('add hello2')
115
 
        self.runbzr('commit -m setup hello2')
116
 
        file('goodbye2', 'wt').write('baz')
117
 
        self.runbzr('add goodbye2')
118
 
        self.runbzr('commit -m setup goodbye2')
119
 
 
120
 
        os.chdir('..')
121
 
        self.runbzr('branch -r 1 a b')
 
117
        a_tree = self.example_branch('a')
 
118
        self.build_tree_contents([
 
119
            ('a/hello2',   'foo'),
 
120
            ('a/goodbye2', 'baz')])
 
121
        a_tree.add('hello2')
 
122
        a_tree.commit(message="setup")
 
123
        a_tree.add('goodbye2')
 
124
        a_tree.commit(message="setup")
 
125
 
 
126
        b_tree = a_tree.bzrdir.sprout('b',
 
127
                   revision_id=a_tree.branch.get_rev_id(1)).open_workingtree()
122
128
        os.chdir('b')
123
 
        self.runbzr('pull -r 2')
 
129
        self.run_bzr('pull -r 2')
124
130
        a = Branch.open('../a')
125
131
        b = Branch.open('.')
126
 
        self.assertEquals(a.revno(),4)
127
 
        self.assertEquals(b.revno(),2)
128
 
        self.runbzr('pull -r 3')
129
 
        self.assertEquals(b.revno(),3)
130
 
        self.runbzr('pull -r 4')
131
 
        self.assertEquals(a.revision_history(), b.revision_history())
 
132
        self.assertEqual(a.revno(),4)
 
133
        self.assertEqual(b.revno(),2)
 
134
        self.run_bzr('pull -r 3')
 
135
        self.assertEqual(b.revno(),3)
 
136
        self.run_bzr('pull -r 4')
 
137
        self.assertEqual(a.revision_history(), b.revision_history())
132
138
 
133
139
 
134
140
    def test_overwrite_uptodate(self):
135
141
        # Make sure pull --overwrite overwrites
136
142
        # even if the target branch has merged
137
143
        # everything already.
138
 
        bzr = self.run_bzr
139
 
 
140
 
        def get_rh(expected_len):
141
 
            rh = self.capture('revision-history')
142
 
            # Make sure we don't have trailing empty revisions
143
 
            rh = rh.strip().split('\n')
144
 
            self.assertEqual(len(rh), expected_len)
145
 
            return rh
146
 
 
147
 
        os.mkdir('a')
148
 
        os.chdir('a')
149
 
        bzr('init')
150
 
        open('foo', 'wb').write('original\n')
151
 
        bzr('add', 'foo')
152
 
        bzr('commit', '-m', 'initial commit')
153
 
 
154
 
        os.chdir('..')
155
 
        bzr('branch', 'a', 'b')
156
 
 
157
 
        os.chdir('a')
158
 
        open('foo', 'wb').write('changed\n')
159
 
        bzr('commit', '-m', 'later change')
160
 
 
161
 
        open('foo', 'wb').write('another\n')
162
 
        bzr('commit', '-m', 'a third change')
163
 
 
164
 
        rev_history_a = get_rh(3)
165
 
 
166
 
        os.chdir('../b')
167
 
        bzr('merge', '../a')
168
 
        bzr('commit', '-m', 'merge')
169
 
 
170
 
        rev_history_b = get_rh(2)
171
 
 
172
 
        bzr('pull', '--overwrite', '../a')
173
 
        rev_history_b = get_rh(3)
 
144
        a_tree = self.make_branch_and_tree('a')
 
145
        self.build_tree_contents([('a/foo', 'original\n')])
 
146
        a_tree.add('foo')
 
147
        a_tree.commit(message='initial commit')
 
148
 
 
149
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
150
 
 
151
        self.build_tree_contents([('a/foo', 'changed\n')])
 
152
        a_tree.commit(message='later change')
 
153
 
 
154
        self.build_tree_contents([('a/foo', 'a third change')])
 
155
        a_tree.commit(message='a third change')
 
156
 
 
157
        rev_history_a = a_tree.branch.revision_history()
 
158
        self.assertEqual(len(rev_history_a), 3)
 
159
 
 
160
        b_tree.merge_from_branch(a_tree.branch)
 
161
        b_tree.commit(message='merge')
 
162
 
 
163
        self.assertEqual(len(b_tree.branch.revision_history()), 2)
 
164
 
 
165
        os.chdir('b')
 
166
        self.run_bzr('pull --overwrite ../a')
 
167
        rev_history_b = b_tree.branch.revision_history()
 
168
        self.assertEqual(len(rev_history_b), 3)
174
169
 
175
170
        self.assertEqual(rev_history_b, rev_history_a)
176
171
 
177
172
    def test_overwrite_children(self):
178
173
        # Make sure pull --overwrite sets the revision-history
179
174
        # to be identical to the pull source, even if we have convergence
180
 
        bzr = self.run_bzr
181
 
 
182
 
        def get_rh(expected_len):
183
 
            rh = self.capture('revision-history')
184
 
            # Make sure we don't have trailing empty revisions
185
 
            rh = rh.strip().split('\n')
186
 
            self.assertEqual(len(rh), expected_len)
187
 
            return rh
188
 
 
189
 
        os.mkdir('a')
190
 
        os.chdir('a')
191
 
        bzr('init')
192
 
        open('foo', 'wb').write('original\n')
193
 
        bzr('add', 'foo')
194
 
        bzr('commit', '-m', 'initial commit')
195
 
 
196
 
        os.chdir('..')
197
 
        bzr('branch', 'a', 'b')
198
 
 
199
 
        os.chdir('a')
200
 
        open('foo', 'wb').write('changed\n')
201
 
        bzr('commit', '-m', 'later change')
202
 
 
203
 
        open('foo', 'wb').write('another\n')
204
 
        bzr('commit', '-m', 'a third change')
205
 
 
206
 
        rev_history_a = get_rh(3)
207
 
 
208
 
        os.chdir('../b')
209
 
        bzr('merge', '../a')
210
 
        bzr('commit', '-m', 'merge')
211
 
 
212
 
        rev_history_b = get_rh(2)
213
 
 
214
 
        os.chdir('../a')
215
 
        open('foo', 'wb').write('a fourth change\n')
216
 
        bzr('commit', '-m', 'a fourth change')
217
 
 
218
 
        rev_history_a = get_rh(4)
 
175
        a_tree = self.make_branch_and_tree('a')
 
176
        self.build_tree_contents([('a/foo', 'original\n')])
 
177
        a_tree.add('foo')
 
178
        a_tree.commit(message='initial commit')
 
179
 
 
180
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
181
 
 
182
        self.build_tree_contents([('a/foo', 'changed\n')])
 
183
        a_tree.commit(message='later change')
 
184
 
 
185
        self.build_tree_contents([('a/foo', 'a third change')])
 
186
        a_tree.commit(message='a third change')
 
187
 
 
188
        self.assertEqual(len(a_tree.branch.revision_history()), 3)
 
189
 
 
190
        b_tree.merge_from_branch(a_tree.branch)
 
191
        b_tree.commit(message='merge')
 
192
 
 
193
        self.assertEqual(len(b_tree.branch.revision_history()), 2)
 
194
 
 
195
        self.build_tree_contents([('a/foo', 'a fourth change\n')])
 
196
        a_tree.commit(message='a fourth change')
 
197
 
 
198
        rev_history_a = a_tree.branch.revision_history()
 
199
        self.assertEqual(len(rev_history_a), 4)
219
200
 
220
201
        # With convergence, we could just pull over the
221
202
        # new change, but with --overwrite, we want to switch our history
222
 
        os.chdir('../b')
223
 
        bzr('pull', '--overwrite', '../a')
224
 
        rev_history_b = get_rh(4)
 
203
        os.chdir('b')
 
204
        self.run_bzr('pull --overwrite ../a')
 
205
        rev_history_b = b_tree.branch.revision_history()
 
206
        self.assertEqual(len(rev_history_b), 4)
225
207
 
226
208
        self.assertEqual(rev_history_b, rev_history_a)
227
209
 
233
215
        self.build_tree(['branch_a/a'])
234
216
        tree_a.add('a')
235
217
        tree_a.commit('commit a')
236
 
        branch_b = branch_a.bzrdir.sprout('branch_b').open_branch()
237
 
        tree_b = branch_b.bzrdir.open_workingtree()
238
 
        branch_c = branch_a.bzrdir.sprout('branch_c').open_branch()
239
 
        tree_c = branch_c.bzrdir.open_workingtree()
 
218
        tree_b = branch_a.bzrdir.sprout('branch_b').open_workingtree()
 
219
        branch_b = tree_b.branch
 
220
        tree_c = branch_a.bzrdir.sprout('branch_c').open_workingtree()
 
221
        branch_c = tree_c.branch
240
222
        self.build_tree(['branch_a/b'])
241
223
        tree_a.add('b')
242
224
        tree_a.commit('commit b')
246
228
        self.assertEqual(None, branch_b.get_parent())
247
229
        # test pull for failure without parent set
248
230
        os.chdir('branch_b')
249
 
        out = self.runbzr('pull', retcode=3)
250
 
        self.assertEquals(out,
 
231
        out = self.run_bzr('pull', retcode=3)
 
232
        self.assertEqual(out,
251
233
                ('','bzr: ERROR: No pull location known or specified.\n'))
252
234
        # test implicit --remember when no parent set, this pull conflicts
253
235
        self.build_tree(['d'])
254
236
        tree_b.add('d')
255
237
        tree_b.commit('commit d')
256
 
        out = self.runbzr('pull ../branch_a', retcode=3)
257
 
        self.assertEquals(out,
258
 
                ('','bzr: ERROR: These branches have diverged.  Try merge.\n'))
259
 
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
238
        out = self.run_bzr('pull ../branch_a', retcode=3)
 
239
        self.assertEqual(out,
 
240
                ('','bzr: ERROR: These branches have diverged.'
 
241
                    ' Use the merge command to reconcile them.\n'))
 
242
        self.assertEqual(branch_b.get_parent(), parent)
260
243
        # test implicit --remember after resolving previous failure
261
244
        uncommit(branch=branch_b, tree=tree_b)
262
245
        transport.delete('branch_b/d')
263
 
        self.runbzr('pull')
264
 
        self.assertEquals(abspath(branch_b.get_parent()), abspath(parent))
 
246
        self.run_bzr('pull')
 
247
        self.assertEqual(branch_b.get_parent(), parent)
265
248
        # test explicit --remember
266
 
        self.runbzr('pull ../branch_c --remember')
267
 
        self.assertEquals(abspath(branch_b.get_parent()),
268
 
                          abspath(branch_c.bzrdir.root_transport.base))
 
249
        self.run_bzr('pull ../branch_c --remember')
 
250
        self.assertEqual(branch_b.get_parent(),
 
251
                          branch_c.bzrdir.root_transport.base)
 
252
 
 
253
    def test_pull_bundle(self):
 
254
        from bzrlib.testament import Testament
 
255
        # Build up 2 trees and prepare for a pull
 
256
        tree_a = self.make_branch_and_tree('branch_a')
 
257
        f = open('branch_a/a', 'wb')
 
258
        f.write('hello')
 
259
        f.close()
 
260
        tree_a.add('a')
 
261
        tree_a.commit('message')
 
262
 
 
263
        tree_b = tree_a.bzrdir.sprout('branch_b').open_workingtree()
 
264
 
 
265
        # Make a change to 'a' that 'b' can pull
 
266
        f = open('branch_a/a', 'wb')
 
267
        f.write('hey there')
 
268
        f.close()
 
269
        tree_a.commit('message')
 
270
 
 
271
        # Create the bundle for 'b' to pull
 
272
        os.chdir('branch_a')
 
273
        self.run_bzr('bundle ../branch_b -o ../bundle')
 
274
 
 
275
        os.chdir('../branch_b')
 
276
        out, err = self.run_bzr('pull ../bundle')
 
277
        self.assertEqual(out,
 
278
                         'Now on revision 2.\n')
 
279
        self.assertEqual(err,
 
280
                ' M  a\nAll changes applied successfully.\n')
 
281
 
 
282
        self.assertEqualDiff(tree_a.branch.revision_history(),
 
283
                             tree_b.branch.revision_history())
 
284
 
 
285
        testament_a = Testament.from_revision(tree_a.branch.repository,
 
286
                                              tree_a.get_parent_ids()[0])
 
287
        testament_b = Testament.from_revision(tree_b.branch.repository,
 
288
                                              tree_b.get_parent_ids()[0])
 
289
        self.assertEqualDiff(testament_a.as_text(),
 
290
                             testament_b.as_text())
 
291
 
 
292
        # it is legal to attempt to pull an already-merged bundle
 
293
        out, err = self.run_bzr('pull ../bundle')
 
294
        self.assertEqual(err, '')
 
295
        self.assertEqual(out, 'No revisions to pull.\n')
 
296
 
 
297
    def test_pull_verbose_no_files(self):
 
298
        """Pull --verbose should not list modified files"""
 
299
        tree_a = self.make_branch_and_tree('tree_a')
 
300
        self.build_tree(['tree_a/foo'])
 
301
        tree_a.add('foo')
 
302
        tree_a.commit('bar')
 
303
        tree_b = self.make_branch_and_tree('tree_b')
 
304
        out = self.run_bzr('pull --verbose -d tree_b tree_a')[0]
 
305
        self.assertContainsRe(out, 'bar')
 
306
        self.assertNotContainsRe(out, 'added:')
 
307
        self.assertNotContainsRe(out, 'foo')
 
308
 
 
309
    def test_pull_quiet(self):
 
310
        """Check that bzr pull --quiet does not print anything"""
 
311
        tree_a = self.make_branch_and_tree('tree_a')
 
312
        self.build_tree(['tree_a/foo'])
 
313
        tree_a.add('foo')
 
314
        revision_id = tree_a.commit('bar')
 
315
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
 
316
        out, err = self.run_bzr('pull --quiet -d tree_b')
 
317
        self.assertEqual(out, '')
 
318
        self.assertEqual(err, '')
 
319
        self.assertEqual(tree_b.last_revision(), revision_id)
 
320
        self.build_tree(['tree_a/moo'])
 
321
        tree_a.add('moo')
 
322
        revision_id = tree_a.commit('quack')
 
323
        out, err = self.run_bzr('pull --quiet -d tree_b')
 
324
        self.assertEqual(out, '')
 
325
        self.assertEqual(err, '')
 
326
        self.assertEqual(tree_b.last_revision(), revision_id)