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
19
18
"""Tests for the update command of bzr."""
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
29
class TestUpdate(ExternalBase):
29
from bzrlib.tests.script import ScriptRunner
32
class TestUpdate(tests.TestCaseWithTransport):
31
34
def test_update_standalone_trivial(self):
33
out, err = self.runbzr('update')
34
self.assertEqual('Tree is up to date at revision 0.\n', err)
35
self.make_branch_and_tree('.')
36
out, err = self.run_bzr('update')
38
'Tree is up to date at revision 0 of branch %s\n' % self.test_dir,
40
self.assertEqual('', out)
42
def test_update_quiet(self):
43
self.make_branch_and_tree('.')
44
out, err = self.run_bzr('update --quiet')
45
self.assertEqual('', err)
35
46
self.assertEqual('', out)
37
48
def test_update_standalone_trivial_with_alias_up(self):
39
out, err = self.runbzr('up')
40
self.assertEqual('Tree is up to date at revision 0.\n', err)
49
self.make_branch_and_tree('.')
50
out, err = self.run_bzr('up')
51
self.assertEqual('Tree is up to date at revision 0 of branch %s\n'
41
54
self.assertEqual('', out)
43
56
def test_update_up_to_date_light_checkout(self):
44
57
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)
58
self.run_bzr('checkout --lightweight branch checkout')
59
out, err = self.run_bzr('update checkout')
60
self.assertEqual('Tree is up to date at revision 0 of branch %s\n'
61
% osutils.pathjoin(self.test_dir, 'branch'),
48
63
self.assertEqual('', out)
50
65
def test_update_up_to_date_checkout(self):
51
66
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)
67
self.run_bzr('checkout branch checkout')
69
sr.run_script(self, '''
71
2>Tree is up to date at revision 0 of branch .../branch
57
74
def test_update_out_of_date_standalone_tree(self):
58
75
# FIXME the default format has to change for this to pass
59
76
# because it currently uses the branch last-revision marker.
60
77
self.make_branch_and_tree('branch')
62
self.runbzr('checkout --lightweight branch checkout')
79
self.run_bzr('checkout --lightweight branch checkout')
63
80
self.build_tree(['checkout/file'])
64
self.runbzr('add checkout/file')
65
self.runbzr('commit -m add-file checkout')
81
self.run_bzr('add checkout/file')
82
self.run_bzr('commit -m add-file checkout')
66
83
# now branch should be out of date
67
out,err = self.runbzr('update branch')
84
out,err = self.run_bzr('update branch')
68
85
self.assertEqual('', out)
69
self.assertEqual('All changes applied successfully.\n'
70
'Updated to revision 1.\n', err)
71
self.failUnlessExists('branch/file')
86
self.assertEqualDiff("""+N file
87
All changes applied successfully.
88
Updated to revision 1 of branch %s
89
""" % osutils.pathjoin(self.test_dir, 'branch',),
91
self.assertPathExists('branch/file')
73
93
def test_update_out_of_date_light_checkout(self):
74
94
self.make_branch_and_tree('branch')
75
95
# make two checkouts
76
self.runbzr('checkout --lightweight branch checkout')
77
self.runbzr('checkout --lightweight branch checkout2')
96
self.run_bzr('checkout --lightweight branch checkout')
97
self.run_bzr('checkout --lightweight branch checkout2')
78
98
self.build_tree(['checkout/file'])
79
self.runbzr('add checkout/file')
80
self.runbzr('commit -m add-file checkout')
99
self.run_bzr('add checkout/file')
100
self.run_bzr('commit -m add-file checkout')
81
101
# 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',
102
out,err = self.run_bzr('update checkout2')
103
self.assertEqualDiff('''+N file
104
All changes applied successfully.
105
Updated to revision 1 of branch %s
106
''' % osutils.pathjoin(self.test_dir, 'branch',),
86
108
self.assertEqual('', out)
88
110
def test_update_conflicts_returns_2(self):
89
111
self.make_branch_and_tree('branch')
90
112
# make two checkouts
91
self.runbzr('checkout --lightweight branch checkout')
113
self.run_bzr('checkout --lightweight branch checkout')
92
114
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')
115
self.run_bzr('add checkout/file')
116
self.run_bzr('commit -m add-file checkout')
117
self.run_bzr('checkout --lightweight branch checkout2')
96
118
# now alter file in checkout
97
119
a_file = file('checkout/file', 'wt')
98
120
a_file.write('Foo')
100
self.runbzr('commit -m checnge-file checkout')
122
self.run_bzr('commit -m checnge-file checkout')
101
123
# now checkout2 should be out of date
102
124
# make a local change to file
103
125
a_file = file('checkout2/file', 'wt')
104
126
a_file.write('Bar')
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')
128
out,err = self.run_bzr('update checkout2', retcode=1)
129
self.assertEqualDiff(''' M file
130
Text conflict in file
131
1 conflicts encountered.
132
Updated to revision 2 of branch %s
133
''' % osutils.pathjoin(self.test_dir, 'branch',),
111
135
self.assertEqual('', out)
113
137
def test_smoke_update_checkout_bound_branch_local_commits(self):
114
138
# smoke test for doing an update of a checkout of a bound
115
139
# branch with local commits.
116
140
master = self.make_branch_and_tree('master')
141
master.commit('first commit')
117
142
# make a bound branch
118
self.run_bzr('checkout', 'master', 'child')
119
# get an object form of child
120
child = WorkingTree.open('child')
143
self.run_bzr('checkout master child')
122
self.run_bzr('checkout', '--lightweight', 'child', 'checkout')
145
self.run_bzr('checkout --lightweight child checkout')
123
146
# get an object form of the checkout to manipulate
124
wt = WorkingTree.open('checkout')
147
wt = workingtree.WorkingTree.open('checkout')
126
149
a_file = file('master/file', 'wt')
127
150
a_file.write('Foo')
205
237
checkout = readonly_branch.create_checkout('checkout',
206
238
lightweight=True)
207
239
tree.commit('empty commit')
208
self.runbzr(['update', 'checkout'])
240
self.run_bzr('update checkout')
242
def test_update_with_merge_merged_to_master(self):
243
# Test that 'bzr update' works correctly when you have
244
# an update in the master tree, and a [lightweight or otherwise]
245
# checkout which has merge a revision merged to master already.
246
master = self.make_branch_and_tree('master')
247
self.build_tree(['master/file'])
249
master.commit('one', rev_id='m1')
251
self.build_tree(['checkout1/'])
252
checkout_dir = bzrdir.BzrDirMetaFormat1().initialize('checkout1')
253
checkout_dir.set_branch_reference(master.branch)
254
checkout1 = checkout_dir.create_workingtree('m1')
256
# Create a second branch, with an extra commit
257
other = master.bzrdir.sprout('other').open_workingtree()
258
self.build_tree(['other/file2'])
260
other.commit('other2', rev_id='o2')
262
# Merge the other branch into checkout - 'start reviewing a patch'
263
checkout1.merge_from_branch(other.branch)
264
self.assertEqual(['o2'], checkout1.get_parent_ids()[1:])
266
# Create a new commit in the master branch - 'someone else lands its'
267
master.merge_from_branch(other.branch)
268
master.commit('f3', rev_id='m2')
270
# This should not report about local commits being pending
271
# merges, because they were real merges (but are now gone).
272
# It should perhaps report on them.
273
out, err = self.run_bzr('update', working_dir='checkout1')
274
self.assertEqual('', out)
275
self.assertEqualDiff('''All changes applied successfully.
276
Updated to revision 2 of branch %s
277
''' % osutils.pathjoin(self.test_dir, 'master',),
279
# The pending merges should still be there
280
self.assertEqual([], checkout1.get_parent_ids()[1:])
282
def test_update_dash_r(self):
283
master = self.make_branch_and_tree('master')
285
self.build_tree(['./file1'])
286
master.add(['file1'])
287
master.commit('one', rev_id='m1')
288
self.build_tree(['./file2'])
289
master.add(['file2'])
290
master.commit('two', rev_id='m2')
293
sr.run_script(self, '''
296
2>All changes applied successfully.
297
2>Updated to revision 1 of .../master
299
self.assertPathExists('./file1')
300
self.assertPathDoesNotExist('./file2')
301
self.assertEquals(['m1'], master.get_parent_ids())
303
def test_update_dash_r_outside_history(self):
304
"""Ensure that we can update -r to dotted revisions.
306
master = self.make_branch_and_tree('master')
307
self.build_tree(['master/file1'])
308
master.add(['file1'])
309
master.commit('one', rev_id='m1')
311
# Create a second branch, with extra commits
312
other = master.bzrdir.sprout('other').open_workingtree()
313
self.build_tree(['other/file2', 'other/file3'])
315
other.commit('other2', rev_id='o2')
317
other.commit('other3', rev_id='o3')
320
self.run_bzr('merge ../other')
321
master.commit('merge', rev_id='merge')
323
# Switch to o2. file3 was added only in o3 and should be deleted.
324
out, err = self.run_bzr('update -r revid:o2')
325
self.assertContainsRe(err, '-D\s+file3')
326
self.assertContainsRe(err, 'All changes applied successfully\.')
327
self.assertContainsRe(err, 'Updated to revision 1.1.1 of branch .*')
329
# Switch back to latest
330
out, err = self.run_bzr('update')
331
self.assertContainsRe(err, '\+N\s+file3')
332
self.assertContainsRe(err, 'All changes applied successfully\.')
333
self.assertContainsRe(err, 'Updated to revision 2 of branch .*')
335
def test_update_dash_r_in_master(self):
336
# Test that 'bzr update' works correctly when you have
337
# an update in the master tree,
338
master = self.make_branch_and_tree('master')
339
self.build_tree(['master/file1'])
340
master.add(['file1'])
341
master.commit('one', rev_id='m1')
343
self.run_bzr('checkout master checkout')
345
# add a revision in the master.
346
self.build_tree(['master/file2'])
347
master.add(['file2'])
348
master.commit('two', rev_id='m2')
352
sr.run_script(self, '''
353
$ bzr update -r revid:m2
355
2>All changes applied successfully.
356
2>Updated to revision 2 of branch .../master
359
def test_update_show_base(self):
360
"""bzr update support --show-base
362
see https://bugs.launchpad.net/bzr/+bug/202374"""
364
tree=self.make_branch_and_tree('.')
366
f = open('hello','wt')
372
f = open('hello','wt')
377
#tree.update() gives no such revision, so ...
378
self.run_bzr(['update','-r1'])
381
f = open('hello','wt')
385
out, err = self.run_bzr(['update','--show-base'],retcode=1)
387
# check for conflict notification
388
self.assertContainsString(err,
389
' M hello\nText conflict in hello\n1 conflicts encountered.\n')
391
self.assertEqualDiff('<<<<<<< TREE\n'
392
'fie||||||| BASE-REVISION\n'
394
'fee>>>>>>> MERGE-SOURCE\n',
395
open('hello').read())
397
def test_update_checkout_prevent_double_merge(self):
398
""""Launchpad bug 113809 in bzr "update performs two merges"
399
https://launchpad.net/bugs/113809"""
400
master = self.make_branch_and_tree('master')
401
self.build_tree_contents([('master/file', 'initial contents\n')])
403
master.commit('one', rev_id='m1')
405
checkout = master.branch.create_checkout('checkout')
406
lightweight = checkout.branch.create_checkout('lightweight',
409
# time to create a mess
410
# add a commit to the master
411
self.build_tree_contents([('master/file', 'master\n')])
412
master.commit('two', rev_id='m2')
413
self.build_tree_contents([('master/file', 'master local changes\n')])
415
# local commit on the checkout
416
self.build_tree_contents([('checkout/file', 'checkout\n')])
417
checkout.commit('tree', rev_id='c2', local=True)
418
self.build_tree_contents([('checkout/file',
419
'checkout local changes\n')])
422
self.build_tree_contents([('lightweight/file',
423
'lightweight local changes\n')])
425
# now update (and get conflicts)
426
out, err = self.run_bzr('update lightweight', retcode=1)
427
self.assertEqual('', out)
428
# NB: these conflicts are actually in the source code
429
self.assertFileEqual('''\
431
lightweight local changes
439
self.build_tree_contents([('lightweight/file',
440
'lightweight+checkout\n')])
441
self.run_bzr('resolve lightweight/file')
443
# check we get the second conflict
444
out, err = self.run_bzr('update lightweight', retcode=1)
445
self.assertEqual('', out)
446
# NB: these conflicts are actually in the source code
447
self.assertFileEqual('''\
457
def test_no_upgrade_single_file(self):
458
"""There's one basis revision per tree.
460
Since you can't actually change the basis for a single file at the
461
moment, we don't let you think you can.
465
self.make_branch_and_tree('.')
466
self.build_tree_contents([('a/',),
467
('a/file', 'content')])
469
sr.run_script(self, '''
471
2>bzr: ERROR: bzr update can only update a whole tree, not a file or subdirectory
472
$ bzr update ./a/file
473
2>bzr: ERROR: bzr update can only update a whole tree, not a file or subdirectory
475
2>Tree is up to date at revision 0 of branch ...
478
2>bzr: ERROR: bzr update can only update a whole tree, not a file or subdirectory
479
# however, you can update the whole tree from a subdirectory
481
2>Tree is up to date at revision 0 of branch ...