~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-04 12:10:51 UTC
  • mfrom: (5819.1.4 777007-developer-doc)
  • Revision ID: pqm@pqm.ubuntu.com-20110504121051-aovlsmqiivjmc4fc
(jelmer) Small fixes to developer documentation. (Jonathan Riddell)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 Canonical Ltd
2
 
# -*- coding: utf-8 -*-
 
1
# Copyright (C) 2006-2010 Canonical Ltd
3
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
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
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
16
 
18
17
 
19
18
"""Tests for the update command of bzr."""
20
19
 
21
20
import os
22
 
 
23
 
from bzrlib import branch, bzrdir
24
 
from bzrlib.tests import TestSkipped
25
 
from bzrlib.tests.blackbox import ExternalBase
26
 
from bzrlib.workingtree import WorkingTree
27
 
 
28
 
 
29
 
class TestUpdate(ExternalBase):
 
21
import re
 
22
 
 
23
from bzrlib import (
 
24
    branch,
 
25
    bzrdir,
 
26
    osutils,
 
27
    tests,
 
28
    urlutils,
 
29
    workingtree,
 
30
    )
 
31
from bzrlib.tests.script import ScriptRunner
 
32
 
 
33
 
 
34
class TestUpdate(tests.TestCaseWithTransport):
30
35
 
31
36
    def test_update_standalone_trivial(self):
32
 
        self.runbzr("init")
33
 
        out, err = self.runbzr('update')
34
 
        self.assertEqual('Tree is up to date at revision 0.\n', err)
 
37
        self.make_branch_and_tree('.')
 
38
        out, err = self.run_bzr('update')
 
39
        self.assertEqual(
 
40
            'Tree is up to date at revision 0 of branch %s\n' % self.test_dir,
 
41
            err)
 
42
        self.assertEqual('', out)
 
43
 
 
44
    def test_update_quiet(self):
 
45
        self.make_branch_and_tree('.')
 
46
        out, err = self.run_bzr('update --quiet')
 
47
        self.assertEqual('', err)
35
48
        self.assertEqual('', out)
36
49
 
37
50
    def test_update_standalone_trivial_with_alias_up(self):
38
 
        self.runbzr("init")
39
 
        out, err = self.runbzr('up')
40
 
        self.assertEqual('Tree is up to date at revision 0.\n', err)
 
51
        self.make_branch_and_tree('.')
 
52
        out, err = self.run_bzr('up')
 
53
        self.assertEqual('Tree is up to date at revision 0 of branch %s\n'
 
54
                         % self.test_dir,
 
55
                         err)
41
56
        self.assertEqual('', out)
42
57
 
43
58
    def test_update_up_to_date_light_checkout(self):
44
59
        self.make_branch_and_tree('branch')
45
 
        self.runbzr('checkout --lightweight branch checkout')
46
 
        out, err = self.runbzr('update checkout')
47
 
        self.assertEqual('Tree is up to date at revision 0.\n', err)
 
60
        self.run_bzr('checkout --lightweight branch checkout')
 
61
        out, err = self.run_bzr('update checkout')
 
62
        self.assertEqual('Tree is up to date at revision 0 of branch %s\n'
 
63
                         % osutils.pathjoin(self.test_dir, 'branch'),
 
64
                         err)
48
65
        self.assertEqual('', out)
49
66
 
50
67
    def test_update_up_to_date_checkout(self):
51
68
        self.make_branch_and_tree('branch')
52
 
        self.run_bzr('checkout', 'branch', 'checkout')
53
 
        out, err = self.run_bzr('update', 'checkout')
54
 
        self.assertEqual('Tree is up to date at revision 0.\n', err)
55
 
        self.assertEqual('', out)
 
69
        self.run_bzr('checkout branch checkout')
 
70
        sr = ScriptRunner()
 
71
        sr.run_script(self, '''
 
72
$ bzr update checkout
 
73
2>Tree is up to date at revision 0 of branch .../branch
 
74
''')
56
75
 
57
76
    def test_update_out_of_date_standalone_tree(self):
58
77
        # FIXME the default format has to change for this to pass
59
78
        # because it currently uses the branch last-revision marker.
60
79
        self.make_branch_and_tree('branch')
61
80
        # make a checkout
62
 
        self.runbzr('checkout --lightweight branch checkout')
 
81
        self.run_bzr('checkout --lightweight branch checkout')
63
82
        self.build_tree(['checkout/file'])
64
 
        self.runbzr('add checkout/file')
65
 
        self.runbzr('commit -m add-file checkout')
 
83
        self.run_bzr('add checkout/file')
 
84
        self.run_bzr('commit -m add-file checkout')
66
85
        # now branch should be out of date
67
 
        out,err = self.runbzr('update branch')
 
86
        out,err = self.run_bzr('update branch')
68
87
        self.assertEqual('', out)
69
 
        self.assertEqual('All changes applied successfully.\n'
70
 
                         'Updated to revision 1.\n', err)
71
 
        self.failUnlessExists('branch/file')
 
88
        self.assertEqualDiff("""+N  file
 
89
All changes applied successfully.
 
90
Updated to revision 1 of branch %s
 
91
""" % osutils.pathjoin(self.test_dir, 'branch',),
 
92
                         err)
 
93
        self.assertPathExists('branch/file')
72
94
 
73
95
    def test_update_out_of_date_light_checkout(self):
74
96
        self.make_branch_and_tree('branch')
75
97
        # make two checkouts
76
 
        self.runbzr('checkout --lightweight branch checkout')
77
 
        self.runbzr('checkout --lightweight branch checkout2')
 
98
        self.run_bzr('checkout --lightweight branch checkout')
 
99
        self.run_bzr('checkout --lightweight branch checkout2')
78
100
        self.build_tree(['checkout/file'])
79
 
        self.runbzr('add checkout/file')
80
 
        self.runbzr('commit -m add-file checkout')
 
101
        self.run_bzr('add checkout/file')
 
102
        self.run_bzr('commit -m add-file checkout')
81
103
        # now checkout2 should be out of date
82
 
        out,err = self.runbzr('update checkout2')
83
 
        self.assertEqual('All changes applied successfully.\n'
84
 
                         'Updated to revision 1.\n',
 
104
        out,err = self.run_bzr('update checkout2')
 
105
        self.assertEqualDiff('''+N  file
 
106
All changes applied successfully.
 
107
Updated to revision 1 of branch %s
 
108
''' % osutils.pathjoin(self.test_dir, 'branch',),
85
109
                         err)
86
110
        self.assertEqual('', out)
87
111
 
88
112
    def test_update_conflicts_returns_2(self):
89
113
        self.make_branch_and_tree('branch')
90
114
        # make two checkouts
91
 
        self.runbzr('checkout --lightweight branch checkout')
 
115
        self.run_bzr('checkout --lightweight branch checkout')
92
116
        self.build_tree(['checkout/file'])
93
 
        self.runbzr('add checkout/file')
94
 
        self.runbzr('commit -m add-file checkout')
95
 
        self.runbzr('checkout --lightweight branch checkout2')
 
117
        self.run_bzr('add checkout/file')
 
118
        self.run_bzr('commit -m add-file checkout')
 
119
        self.run_bzr('checkout --lightweight branch checkout2')
96
120
        # now alter file in checkout
97
121
        a_file = file('checkout/file', 'wt')
98
122
        a_file.write('Foo')
99
123
        a_file.close()
100
 
        self.runbzr('commit -m checnge-file checkout')
 
124
        self.run_bzr('commit -m checnge-file checkout')
101
125
        # now checkout2 should be out of date
102
126
        # make a local change to file
103
127
        a_file = file('checkout2/file', 'wt')
104
128
        a_file.write('Bar')
105
129
        a_file.close()
106
 
        out,err = self.runbzr('update checkout2', retcode=1)
107
 
        self.assertEqual(['1 conflicts encountered.',
108
 
                          'Updated to revision 2.'],
109
 
                         err.split('\n')[1:3])
110
 
        self.assertContainsRe(err, 'Text conflict in file\n')
 
130
        out,err = self.run_bzr('update checkout2', retcode=1)
 
131
        self.assertEqualDiff(''' M  file
 
132
Text conflict in file
 
133
1 conflicts encountered.
 
134
Updated to revision 2 of branch %s
 
135
''' % osutils.pathjoin(self.test_dir, 'branch',),
 
136
                         err)
111
137
        self.assertEqual('', out)
112
138
 
113
139
    def test_smoke_update_checkout_bound_branch_local_commits(self):
115
141
        # branch with local commits.
116
142
        master = self.make_branch_and_tree('master')
117
143
        # make a bound branch
118
 
        self.run_bzr('checkout', 'master', 'child')
 
144
        self.run_bzr('checkout master child')
119
145
        # get an object form of child
120
 
        child = WorkingTree.open('child')
 
146
        child = workingtree.WorkingTree.open('child')
121
147
        # check that out
122
 
        self.run_bzr('checkout', '--lightweight', 'child', 'checkout')
 
148
        self.run_bzr('checkout --lightweight child checkout')
123
149
        # get an object form of the checkout to manipulate
124
 
        wt = WorkingTree.open('checkout')
 
150
        wt = workingtree.WorkingTree.open('checkout')
125
151
        # change master
126
152
        a_file = file('master/file', 'wt')
127
153
        a_file.write('Foo')
142
168
 
143
169
        # now, update checkout ->
144
170
        # get all three files and a pending merge.
145
 
        out, err = self.run_bzr('update', 'checkout')
 
171
        out, err = self.run_bzr('update checkout')
146
172
        self.assertEqual('', out)
147
 
        self.assertContainsRe(err, 'Updated to revision 1.\n'
148
 
                                   'Your local commits will now show as'
149
 
                                   ' pending merges')
 
173
        self.assertEqualDiff("""+N  file_b
 
174
All changes applied successfully.
 
175
+N  file
 
176
All changes applied successfully.
 
177
Updated to revision 1 of branch %s
 
178
Your local commits will now show as pending merges with 'bzr status', and can be committed with 'bzr commit'.
 
179
""" % osutils.pathjoin(self.test_dir, 'master',),
 
180
                         err)
150
181
        self.assertEqual([master_tip, child_tip], wt.get_parent_ids())
151
 
        self.failUnlessExists('checkout/file')
152
 
        self.failUnlessExists('checkout/file_b')
153
 
        self.failUnlessExists('checkout/file_c')
 
182
        self.assertPathExists('checkout/file')
 
183
        self.assertPathExists('checkout/file_b')
 
184
        self.assertPathExists('checkout/file_c')
154
185
        self.assertTrue(wt.has_filename('file_c'))
155
186
 
156
187
    def test_update_with_merges(self):
164
195
 
165
196
        self.build_tree(['checkout1/'])
166
197
        checkout_dir = bzrdir.BzrDirMetaFormat1().initialize('checkout1')
167
 
        branch.BranchReferenceFormat().initialize(checkout_dir, master.branch)
 
198
        branch.BranchReferenceFormat().initialize(checkout_dir,
 
199
            target_branch=master.branch)
168
200
        checkout1 = checkout_dir.create_workingtree('m1')
169
201
 
170
202
        # Create a second branch, with an extra commit
180
212
 
181
213
        # Merge the other branch into checkout
182
214
        os.chdir('checkout1')
183
 
        self.run_bzr('merge', '../other')
 
215
        self.run_bzr('merge ../other')
184
216
 
185
217
        self.assertEqual(['o2'], checkout1.get_parent_ids()[1:])
186
218
 
187
219
        # At this point, 'commit' should fail, because we are out of date
188
220
        self.run_bzr_error(["please run 'bzr update'"],
189
 
                           'commit', '-m', 'merged')
 
221
                           'commit -m merged')
190
222
 
191
223
        # This should not report about local commits being pending
192
224
        # merges, because they were real merges
193
225
        out, err = self.run_bzr('update')
194
226
        self.assertEqual('', out)
195
 
        self.assertEqual('All changes applied successfully.\n'
196
 
                         'Updated to revision 2.\n', err)
197
 
 
 
227
        self.assertEqualDiff('''+N  file3
 
228
All changes applied successfully.
 
229
Updated to revision 2 of branch %s
 
230
''' % osutils.pathjoin(self.test_dir, 'master',),
 
231
                         err)
198
232
        # The pending merges should still be there
199
233
        self.assertEqual(['o2'], checkout1.get_parent_ids()[1:])
200
234
 
202
236
        """Update a light checkout of a readonly branch"""
203
237
        tree = self.make_branch_and_tree('branch')
204
238
        readonly_branch = branch.Branch.open(self.get_readonly_url('branch'))
205
 
        checkout = readonly_branch.create_checkout('checkout', 
 
239
        checkout = readonly_branch.create_checkout('checkout',
206
240
                                                   lightweight=True)
207
241
        tree.commit('empty commit')
208
 
        self.runbzr(['update', 'checkout'])
 
242
        self.run_bzr('update checkout')
 
243
 
 
244
    def test_update_with_merge_merged_to_master(self):
 
245
        # Test that 'bzr update' works correctly when you have
 
246
        # an update in the master tree, and a [lightweight or otherwise]
 
247
        # checkout which has merge a revision merged to master already.
 
248
        master = self.make_branch_and_tree('master')
 
249
        self.build_tree(['master/file'])
 
250
        master.add(['file'])
 
251
        master.commit('one', rev_id='m1')
 
252
 
 
253
        self.build_tree(['checkout1/'])
 
254
        checkout_dir = bzrdir.BzrDirMetaFormat1().initialize('checkout1')
 
255
        branch.BranchReferenceFormat().initialize(checkout_dir,
 
256
            target_branch=master.branch)
 
257
        checkout1 = checkout_dir.create_workingtree('m1')
 
258
 
 
259
        # Create a second branch, with an extra commit
 
260
        other = master.bzrdir.sprout('other').open_workingtree()
 
261
        self.build_tree(['other/file2'])
 
262
        other.add(['file2'])
 
263
        other.commit('other2', rev_id='o2')
 
264
 
 
265
        # Merge the other branch into checkout -  'start reviewing a patch'
 
266
        checkout1.merge_from_branch(other.branch)
 
267
        self.assertEqual(['o2'], checkout1.get_parent_ids()[1:])
 
268
 
 
269
        # Create a new commit in the master branch - 'someone else lands its'
 
270
        master.merge_from_branch(other.branch)
 
271
        master.commit('f3', rev_id='m2')
 
272
 
 
273
        # This should not report about local commits being pending
 
274
        # merges, because they were real merges (but are now gone).
 
275
        # It should perhaps report on them.
 
276
        out, err = self.run_bzr('update', working_dir='checkout1')
 
277
        self.assertEqual('', out)
 
278
        self.assertEqualDiff('''All changes applied successfully.
 
279
Updated to revision 2 of branch %s
 
280
''' % osutils.pathjoin(self.test_dir, 'master',),
 
281
                         err)
 
282
        # The pending merges should still be there
 
283
        self.assertEqual([], checkout1.get_parent_ids()[1:])
 
284
 
 
285
    def test_update_dash_r(self):
 
286
        master = self.make_branch_and_tree('master')
 
287
        os.chdir('master')
 
288
        self.build_tree(['./file1'])
 
289
        master.add(['file1'])
 
290
        master.commit('one', rev_id='m1')
 
291
        self.build_tree(['./file2'])
 
292
        master.add(['file2'])
 
293
        master.commit('two', rev_id='m2')
 
294
 
 
295
        sr = ScriptRunner()
 
296
        sr.run_script(self, '''
 
297
$ bzr update -r 1
 
298
2>-D  file2
 
299
2>All changes applied successfully.
 
300
2>Updated to revision 1 of .../master
 
301
''')
 
302
        self.assertPathExists('./file1')
 
303
        self.assertPathDoesNotExist('./file2')
 
304
        self.assertEquals(['m1'], master.get_parent_ids())
 
305
 
 
306
    def test_update_dash_r_outside_history(self):
 
307
        """Ensure that we can update -r to dotted revisions.
 
308
        """
 
309
        master = self.make_branch_and_tree('master')
 
310
        self.build_tree(['master/file1'])
 
311
        master.add(['file1'])
 
312
        master.commit('one', rev_id='m1')
 
313
 
 
314
        # Create a second branch, with extra commits
 
315
        other = master.bzrdir.sprout('other').open_workingtree()
 
316
        self.build_tree(['other/file2', 'other/file3'])
 
317
        other.add(['file2'])
 
318
        other.commit('other2', rev_id='o2')
 
319
        other.add(['file3'])
 
320
        other.commit('other3', rev_id='o3')
 
321
 
 
322
        os.chdir('master')
 
323
        self.run_bzr('merge ../other')
 
324
        master.commit('merge', rev_id='merge')
 
325
 
 
326
        # Switch to o2. file3 was added only in o3 and should be deleted.
 
327
        out, err = self.run_bzr('update -r revid:o2')
 
328
        self.assertContainsRe(err, '-D\s+file3')
 
329
        self.assertContainsRe(err, 'All changes applied successfully\.')
 
330
        self.assertContainsRe(err, 'Updated to revision 1.1.1 of branch .*')
 
331
 
 
332
        # Switch back to latest
 
333
        out, err = self.run_bzr('update')
 
334
        self.assertContainsRe(err, '\+N\s+file3')
 
335
        self.assertContainsRe(err, 'All changes applied successfully\.')
 
336
        self.assertContainsRe(err, 'Updated to revision 2 of branch .*')
 
337
 
 
338
    def test_update_dash_r_in_master(self):
 
339
        # Test that 'bzr update' works correctly when you have
 
340
        # an update in the master tree,
 
341
        master = self.make_branch_and_tree('master')
 
342
        self.build_tree(['master/file1'])
 
343
        master.add(['file1'])
 
344
        master.commit('one', rev_id='m1')
 
345
 
 
346
        self.run_bzr('checkout master checkout')
 
347
 
 
348
        # add a revision in the master.
 
349
        self.build_tree(['master/file2'])
 
350
        master.add(['file2'])
 
351
        master.commit('two', rev_id='m2')
 
352
 
 
353
        os.chdir('checkout')
 
354
        sr = ScriptRunner()
 
355
        sr.run_script(self, '''
 
356
$ bzr update -r revid:m2
 
357
2>+N  file2
 
358
2>All changes applied successfully.
 
359
2>Updated to revision 2 of branch .../master
 
360
''')
 
361
 
 
362
    def test_update_show_base(self):
 
363
        """bzr update support --show-base
 
364
 
 
365
        see https://bugs.launchpad.net/bzr/+bug/202374"""
 
366
 
 
367
        tree=self.make_branch_and_tree('.')
 
368
 
 
369
        f = open('hello','wt')
 
370
        f.write('foo')
 
371
        f.close()
 
372
        tree.add('hello')
 
373
        tree.commit('fie')
 
374
 
 
375
        f = open('hello','wt')
 
376
        f.write('fee')
 
377
        f.close()
 
378
        tree.commit('fee')
 
379
 
 
380
        #tree.update() gives no such revision, so ...
 
381
        self.run_bzr(['update','-r1'])
 
382
 
 
383
        #create conflict
 
384
        f = open('hello','wt')
 
385
        f.write('fie')
 
386
        f.close()
 
387
 
 
388
        out, err = self.run_bzr(['update','--show-base'],retcode=1)
 
389
 
 
390
        # check for conflict notification
 
391
        self.assertContainsString(err,
 
392
                                  ' M  hello\nText conflict in hello\n1 conflicts encountered.\n')
 
393
        
 
394
        self.assertEqualDiff('<<<<<<< TREE\n'
 
395
                             'fie||||||| BASE-REVISION\n'
 
396
                             'foo=======\n'
 
397
                             'fee>>>>>>> MERGE-SOURCE\n',
 
398
                             open('hello').read())
 
399
 
 
400
    def test_update_checkout_prevent_double_merge(self):
 
401
        """"Launchpad bug 113809 in bzr "update performs two merges"
 
402
        https://launchpad.net/bugs/113809"""
 
403
        master = self.make_branch_and_tree('master')
 
404
        self.build_tree_contents([('master/file', 'initial contents\n')])
 
405
        master.add(['file'])
 
406
        master.commit('one', rev_id='m1')
 
407
 
 
408
        checkout = master.branch.create_checkout('checkout')
 
409
        lightweight = checkout.branch.create_checkout('lightweight',
 
410
                                                      lightweight=True)
 
411
 
 
412
        # time to create a mess
 
413
        # add a commit to the master
 
414
        self.build_tree_contents([('master/file', 'master\n')])
 
415
        master.commit('two', rev_id='m2')
 
416
        self.build_tree_contents([('master/file', 'master local changes\n')])
 
417
 
 
418
        # local commit on the checkout
 
419
        self.build_tree_contents([('checkout/file', 'checkout\n')])
 
420
        checkout.commit('tree', rev_id='c2', local=True)
 
421
        self.build_tree_contents([('checkout/file',
 
422
                                   'checkout local changes\n')])
 
423
 
 
424
        # lightweight 
 
425
        self.build_tree_contents([('lightweight/file',
 
426
                                   'lightweight local changes\n')])
 
427
 
 
428
        # now update (and get conflicts)
 
429
        out, err = self.run_bzr('update lightweight', retcode=1)
 
430
        self.assertEqual('', out)
 
431
        # NB: these conflicts are actually in the source code
 
432
        self.assertFileEqual('''\
 
433
<<<<<<< TREE
 
434
lightweight local changes
 
435
=======
 
436
checkout
 
437
>>>>>>> MERGE-SOURCE
 
438
''',
 
439
                             'lightweight/file')
 
440
 
 
441
        # resolve it
 
442
        self.build_tree_contents([('lightweight/file',
 
443
                                   'lightweight+checkout\n')])
 
444
        self.run_bzr('resolve lightweight/file')
 
445
 
 
446
        # check we get the second conflict
 
447
        out, err = self.run_bzr('update lightweight', retcode=1)
 
448
        self.assertEqual('', out)
 
449
        # NB: these conflicts are actually in the source code
 
450
        self.assertFileEqual('''\
 
451
<<<<<<< TREE
 
452
lightweight+checkout
 
453
=======
 
454
master
 
455
>>>>>>> MERGE-SOURCE
 
456
''',
 
457
                             'lightweight/file')