/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 breezy/tests/blackbox/test_status.py

  • Committer: Breezy landing bot
  • Author(s): Colin Watson
  • Date: 2020-11-16 21:47:08 UTC
  • mfrom: (7521.1.1 remove-lp-workaround)
  • Revision ID: breezy.the.bot@gmail.com-20201116214708-jos209mgxi41oy15
Remove breezy.git workaround for bazaar.launchpad.net.

Merged from https://code.launchpad.net/~cjwatson/brz/remove-lp-workaround/+merge/393710

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005-2012, 2016 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
22
22
interface later, they will be non blackbox tests.
23
23
"""
24
24
 
25
 
from cStringIO import StringIO
26
25
import codecs
 
26
from io import (
 
27
    BytesIO,
 
28
    StringIO,
 
29
    )
27
30
from os import mkdir, chdir, rmdir, unlink
28
31
import sys
29
 
from tempfile import TemporaryFile
30
32
 
31
 
from bzrlib import (
32
 
    bzrdir,
33
 
    conflicts,
 
33
from ... import (
34
34
    errors,
35
35
    osutils,
36
36
    status,
37
37
    )
38
 
import bzrlib.branch
39
 
from bzrlib.osutils import pathjoin
40
 
from bzrlib.revisionspec import RevisionSpec
41
 
from bzrlib.status import show_tree_status
42
 
from bzrlib.tests import TestCaseWithTransport, TestSkipped
43
 
from bzrlib.workingtree import WorkingTree
 
38
from breezy.bzr import (
 
39
    bzrdir,
 
40
    conflicts,
 
41
    )
 
42
import breezy.branch
 
43
from ...osutils import pathjoin
 
44
from ...revisionspec import RevisionSpec
 
45
from ...status import show_tree_status
 
46
from .. import TestCaseWithTransport, TestSkipped
 
47
from ...workingtree import WorkingTree
44
48
 
45
49
 
46
50
class BranchStatus(TestCaseWithTransport):
50
54
        # As TestCase.setUp clears all hooks, we install this default
51
55
        # post_status hook handler for the test.
52
56
        status.hooks.install_named_hook('post_status',
53
 
            status._show_shelve_summary,
54
 
            'bzr status')
 
57
                                        status._show_shelve_summary,
 
58
                                        'brz status')
55
59
 
56
60
    def assertStatus(self, expected_lines, working_tree, specific_files=None,
57
 
        revision=None, short=False, pending=True, verbose=False):
 
61
                     revision=None, short=False, pending=True, verbose=False):
58
62
        """Run status in working_tree and look for output.
59
63
 
60
64
        :param expected_lines: The lines to look for.
61
65
        :param working_tree: The tree to run status in.
62
66
        """
63
67
        output_string = self.status_string(working_tree, specific_files, revision, short,
64
 
                pending, verbose)
 
68
                                           pending, verbose)
65
69
        self.assertEqual(expected_lines, output_string.splitlines(True))
66
70
 
67
71
    def status_string(self, wt, specific_files=None, revision=None,
68
 
        short=False, pending=True, verbose=False):
69
 
        # use a real file rather than StringIO because it doesn't handle
70
 
        # Unicode very well.
71
 
        tof = codecs.getwriter('utf-8')(TemporaryFile())
72
 
        show_tree_status(wt, specific_files=specific_files, to_file=tof,
73
 
                revision=revision, short=short, show_pending=pending,
74
 
                verbose=verbose)
75
 
        tof.seek(0)
76
 
        return tof.read().decode('utf-8')
 
72
                      short=False, pending=True, verbose=False):
 
73
        uio = self.make_utf8_encoded_stringio()
 
74
        show_tree_status(wt, specific_files=specific_files, to_file=uio,
 
75
                         revision=revision, short=short, show_pending=pending,
 
76
                         verbose=verbose)
 
77
        return uio.getvalue().decode('utf-8')
77
78
 
78
79
    def test_branch_status(self):
79
80
        """Test basic branch status"""
87
88
 
88
89
        self.build_tree(['hello.c', 'bye.c'])
89
90
        self.assertStatus([
90
 
                'unknown:\n',
91
 
                '  bye.c\n',
92
 
                '  hello.c\n',
 
91
            'unknown:\n',
 
92
            '  bye.c\n',
 
93
            '  hello.c\n',
93
94
            ],
94
95
            wt)
95
96
        self.assertStatus([
96
 
                '?   bye.c\n',
97
 
                '?   hello.c\n',
 
97
            '?   bye.c\n',
 
98
            '?   hello.c\n',
98
99
            ],
99
100
            wt, short=True)
100
101
 
101
102
        # add a commit to allow showing pending merges.
102
103
        wt.commit('create a parent to allow testing merge output')
103
104
 
104
 
        wt.add_parent_tree_id('pending@pending-0-0')
 
105
        wt.add_parent_tree_id(b'pending@pending-0-0')
105
106
        self.assertStatus([
106
 
                'unknown:\n',
107
 
                '  bye.c\n',
108
 
                '  hello.c\n',
109
 
                'pending merge tips: (use -v to see all merge revisions)\n',
110
 
                '  (ghost) pending@pending-0-0\n',
 
107
            'unknown:\n',
 
108
            '  bye.c\n',
 
109
            '  hello.c\n',
 
110
            'pending merge tips: (use -v to see all merge revisions)\n',
 
111
            '  (ghost) pending@pending-0-0\n',
111
112
            ],
112
113
            wt)
113
114
        self.assertStatus([
114
 
                'unknown:\n',
115
 
                '  bye.c\n',
116
 
                '  hello.c\n',
117
 
                'pending merges:\n',
118
 
                '  (ghost) pending@pending-0-0\n',
 
115
            'unknown:\n',
 
116
            '  bye.c\n',
 
117
            '  hello.c\n',
 
118
            'pending merges:\n',
 
119
            '  (ghost) pending@pending-0-0\n',
119
120
            ],
120
121
            wt, verbose=True)
121
122
        self.assertStatus([
122
 
                '?   bye.c\n',
123
 
                '?   hello.c\n',
124
 
                'P   (ghost) pending@pending-0-0\n',
 
123
            '?   bye.c\n',
 
124
            '?   hello.c\n',
 
125
            'P   (ghost) pending@pending-0-0\n',
125
126
            ],
126
127
            wt, short=True)
127
128
        self.assertStatus([
128
 
                'unknown:\n',
129
 
                '  bye.c\n',
130
 
                '  hello.c\n',
 
129
            'unknown:\n',
 
130
            '  bye.c\n',
 
131
            '  hello.c\n',
131
132
            ],
132
133
            wt, pending=False)
133
134
        self.assertStatus([
134
 
                '?   bye.c\n',
135
 
                '?   hello.c\n',
 
135
            '?   bye.c\n',
 
136
            '?   hello.c\n',
136
137
            ],
137
138
            wt, short=True, pending=False)
138
139
 
147
148
 
148
149
        revs = [RevisionSpec.from_string('0')]
149
150
        self.assertStatus([
150
 
                'added:\n',
151
 
                '  bye.c\n',
152
 
                '  hello.c\n'
 
151
            'added:\n',
 
152
            '  bye.c\n',
 
153
            '  hello.c\n'
153
154
            ],
154
155
            wt,
155
156
            revision=revs)
160
161
 
161
162
        revs.append(RevisionSpec.from_string('1'))
162
163
        self.assertStatus([
163
 
                'added:\n',
164
 
                '  bye.c\n',
165
 
                '  hello.c\n',
 
164
            'added:\n',
 
165
            '  bye.c\n',
 
166
            '  hello.c\n',
166
167
            ],
167
168
            wt,
168
169
            revision=revs)
173
174
        wt = self.make_branch_and_tree('branch')
174
175
        b = wt.branch
175
176
        wt.commit("Empty commit 1")
176
 
        b_2_dir = b.bzrdir.sprout('./copy')
 
177
        b_2_dir = b.controldir.sprout('./copy')
177
178
        b_2 = b_2_dir.open_branch()
178
179
        wt2 = b_2_dir.open_workingtree()
179
180
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
183
184
        self.assertEndsWith(message, "Empty commit 2\n")
184
185
        wt2.commit("merged")
185
186
        # must be long to make sure we see elipsis at the end
186
 
        wt.commit("Empty commit 3 " +
187
 
                   "blah blah blah blah " * 100)
 
187
        wt.commit("Empty commit 3 "
 
188
                  + "blah blah blah blah " * 100)
188
189
        wt2.merge_from_branch(wt.branch)
189
190
        message = self.status_string(wt2, verbose=True)
190
191
        self.assertStartsWith(message, "pending merges:\n")
191
 
        self.assert_("Empty commit 3" in message)
 
192
        self.assertTrue("Empty commit 3" in message)
192
193
        self.assertEndsWith(message, "...\n")
193
194
 
194
195
    def test_tree_status_ignores(self):
198
199
        wt.commit('commit .bzrignore')
199
200
        self.build_tree(['foo.c', 'foo.c~'])
200
201
        self.assertStatus([
201
 
                'unknown:\n',
202
 
                '  foo.c\n',
203
 
                ],
204
 
                wt)
 
202
            'unknown:\n',
 
203
            '  foo.c\n',
 
204
            ],
 
205
            wt)
205
206
        self.assertStatus([
206
 
                '?   foo.c\n',
207
 
                ],
208
 
                wt, short=True)
 
207
            '?   foo.c\n',
 
208
            ],
 
209
            wt, short=True)
209
210
 
210
211
    def test_tree_status_specific_files(self):
211
212
        """Tests branch status with given specific files"""
212
213
        wt = self.make_branch_and_tree('.')
213
214
        b = wt.branch
214
215
 
215
 
        self.build_tree(['directory/','directory/hello.c',
216
 
                         'bye.c','test.c','dir2/',
 
216
        self.build_tree(['directory/', 'directory/hello.c',
 
217
                         'bye.c', 'test.c', 'dir2/',
217
218
                         'missing.c'])
218
219
        wt.add('directory')
219
220
        wt.add('test.c')
222
223
        unlink('missing.c')
223
224
 
224
225
        self.assertStatus([
225
 
                'missing:\n',
226
 
                '  missing.c\n',
227
 
                'unknown:\n',
228
 
                '  bye.c\n',
229
 
                '  dir2/\n',
230
 
                '  directory/hello.c\n'
231
 
                ],
232
 
                wt)
 
226
            'missing:\n',
 
227
            '  missing.c\n',
 
228
            'unknown:\n',
 
229
            '  bye.c\n',
 
230
            '  dir2/\n',
 
231
            '  directory/hello.c\n'
 
232
            ],
 
233
            wt)
233
234
 
234
235
        self.assertStatus([
235
 
                '?   bye.c\n',
236
 
                '?   dir2/\n',
237
 
                '+!  missing.c\n',
238
 
                '?   directory/hello.c\n'
239
 
                ],
240
 
                wt, short=True)
 
236
            '?   bye.c\n',
 
237
            '?   dir2/\n',
 
238
            '?   directory/hello.c\n',
 
239
            '+!  missing.c\n',
 
240
            ],
 
241
            wt, short=True)
241
242
 
242
243
        tof = StringIO()
243
244
        self.assertRaises(errors.PathsDoNotExist,
244
245
                          show_tree_status,
245
 
                          wt, specific_files=['bye.c','test.c','absent.c'],
 
246
                          wt, specific_files=['bye.c', 'test.c', 'absent.c'],
246
247
                          to_file=tof)
247
248
 
248
249
        tof = StringIO()
249
250
        show_tree_status(wt, specific_files=['directory'], to_file=tof)
250
251
        tof.seek(0)
251
 
        self.assertEquals(tof.readlines(),
252
 
                          ['unknown:\n',
253
 
                           '  directory/hello.c\n'
254
 
                           ])
 
252
        self.assertEqual(tof.readlines(),
 
253
                         ['unknown:\n',
 
254
                          '  directory/hello.c\n'
 
255
                          ])
255
256
        tof = StringIO()
256
257
        show_tree_status(wt, specific_files=['directory'], to_file=tof,
257
258
                         short=True)
258
259
        tof.seek(0)
259
 
        self.assertEquals(tof.readlines(), ['?   directory/hello.c\n'])
 
260
        self.assertEqual(tof.readlines(), ['?   directory/hello.c\n'])
260
261
 
261
262
        tof = StringIO()
262
263
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
263
264
        tof.seek(0)
264
 
        self.assertEquals(tof.readlines(),
265
 
                          ['unknown:\n',
266
 
                           '  dir2/\n'
267
 
                           ])
 
265
        self.assertEqual(tof.readlines(),
 
266
                         ['unknown:\n',
 
267
                          '  dir2/\n'
 
268
                          ])
268
269
        tof = StringIO()
269
270
        show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
270
271
        tof.seek(0)
271
 
        self.assertEquals(tof.readlines(), ['?   dir2/\n'])
 
272
        self.assertEqual(tof.readlines(), ['?   dir2/\n'])
272
273
 
273
274
        tof = StringIO()
274
275
        revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
275
276
        show_tree_status(wt, specific_files=['test.c'], to_file=tof,
276
277
                         short=True, revision=revs)
277
278
        tof.seek(0)
278
 
        self.assertEquals(tof.readlines(), ['+N  test.c\n'])
 
279
        self.assertEqual(tof.readlines(), ['+N  test.c\n'])
279
280
 
280
281
        tof = StringIO()
281
282
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof)
282
283
        tof.seek(0)
283
 
        self.assertEquals(tof.readlines(),
284
 
                          ['missing:\n',
285
 
                           '  missing.c\n'])
 
284
        self.assertEqual(tof.readlines(),
 
285
                         ['missing:\n',
 
286
                          '  missing.c\n'])
286
287
 
287
288
        tof = StringIO()
288
289
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof,
289
290
                         short=True)
290
291
        tof.seek(0)
291
 
        self.assertEquals(tof.readlines(),
292
 
                          ['+!  missing.c\n'])
 
292
        self.assertEqual(tof.readlines(),
 
293
                         ['+!  missing.c\n'])
293
294
 
294
295
    def test_specific_files_conflicts(self):
295
296
        tree = self.make_branch_and_tree('.')
296
297
        self.build_tree(['dir2/'])
297
298
        tree.add('dir2')
298
299
        tree.commit('added dir2')
299
 
        tree.set_conflicts(conflicts.ConflictList(
300
 
            [conflicts.ContentsConflict('foo')]))
301
 
        tof = StringIO()
 
300
        tree.set_conflicts([conflicts.ContentsConflict('foo')])
 
301
        tof = BytesIO()
302
302
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
303
 
        self.assertEqualDiff('', tof.getvalue())
304
 
        tree.set_conflicts(conflicts.ConflictList(
305
 
            [conflicts.ContentsConflict('dir2')]))
 
303
        self.assertEqualDiff(b'', tof.getvalue())
 
304
        tree.set_conflicts([conflicts.ContentsConflict('dir2')])
306
305
        tof = StringIO()
307
306
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
308
307
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2\n',
309
308
                             tof.getvalue())
310
309
 
311
 
        tree.set_conflicts(conflicts.ConflictList(
312
 
            [conflicts.ContentsConflict('dir2/file1')]))
 
310
        tree.set_conflicts([conflicts.ContentsConflict('dir2/file1')])
313
311
        tof = StringIO()
314
312
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
315
313
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2/file1\n',
325
323
        wt.add('FILE_D')
326
324
        wt.add('FILE_E')
327
325
        wt.commit('Create five empty files.')
328
 
        with open('FILE_B', 'w') as f: f.write('Modification to file FILE_B.')
329
 
        with open('FILE_C', 'w') as f: f.write('Modification to file FILE_C.')
 
326
        with open('FILE_B', 'w') as f:
 
327
            f.write('Modification to file FILE_B.')
 
328
        with open('FILE_C', 'w') as f:
 
329
            f.write('Modification to file FILE_C.')
330
330
        unlink('FILE_E')  # FILE_E will be versioned but missing
331
 
        with open('FILE_Q', 'w') as f: f.write('FILE_Q is added but not committed.')
 
331
        with open('FILE_Q', 'w') as f:
 
332
            f.write('FILE_Q is added but not committed.')
332
333
        wt.add('FILE_Q')  # FILE_Q will be added but not committed
333
334
        open('UNVERSIONED_BUT_EXISTING', 'w')
334
335
        return wt
361
362
        # Okay, everything's looking good with the existent files.
362
363
        # Let's see what happens when we throw in non-existent files.
363
364
 
364
 
        # bzr st [--short] NONEXISTENT '
 
365
        # brz st [--short] NONEXISTENT '
365
366
        expected = [
366
 
          'nonexistent:\n',
367
 
          '  NONEXISTENT\n',
368
 
          ]
 
367
            'nonexistent:\n',
 
368
            '  NONEXISTENT\n',
 
369
            ]
369
370
        out, err = self.run_bzr('status NONEXISTENT', retcode=3)
370
371
        self.assertEqual(expected, out.splitlines(True))
371
372
        self.assertContainsRe(err,
372
373
                              r'.*ERROR: Path\(s\) do not exist: '
373
374
                              'NONEXISTENT.*')
374
375
        expected = [
375
 
          'X:   NONEXISTENT\n',
376
 
          ]
 
376
            'X:   NONEXISTENT\n',
 
377
            ]
377
378
        out, err = self.run_bzr('status --short NONEXISTENT', retcode=3)
378
379
        self.assertContainsRe(err,
379
380
                              r'.*ERROR: Path\(s\) do not exist: '
380
381
                              'NONEXISTENT.*')
381
382
 
382
383
    def test_status_nonexistent_file_with_others(self):
383
 
        # bzr st [--short] NONEXISTENT ...others..
 
384
        # brz st [--short] NONEXISTENT ...others..
384
385
        wt = self._prepare_nonexistent()
385
386
        expected = [
386
 
          'removed:\n',
387
 
          '  FILE_E\n',
388
 
          'modified:\n',
389
 
          '  FILE_B\n',
390
 
          '  FILE_C\n',
391
 
          'nonexistent:\n',
392
 
          '  NONEXISTENT\n',
393
 
          ]
 
387
            'removed:\n',
 
388
            '  FILE_E\n',
 
389
            'modified:\n',
 
390
            '  FILE_B\n',
 
391
            '  FILE_C\n',
 
392
            'nonexistent:\n',
 
393
            '  NONEXISTENT\n',
 
394
            ]
394
395
        out, err = self.run_bzr('status NONEXISTENT '
395
396
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
396
397
                                retcode=3)
399
400
                              r'.*ERROR: Path\(s\) do not exist: '
400
401
                              'NONEXISTENT.*')
401
402
        expected = [
402
 
          ' D  FILE_E\n',
403
 
          ' M  FILE_C\n',
404
 
          ' M  FILE_B\n',
405
 
          'X   NONEXISTENT\n',
406
 
          ]
 
403
            ' M  FILE_B\n',
 
404
            ' M  FILE_C\n',
 
405
            ' D  FILE_E\n',
 
406
            'X   NONEXISTENT\n',
 
407
            ]
407
408
        out, err = self.run_bzr('status --short NONEXISTENT '
408
409
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
409
410
                                retcode=3)
413
414
                              'NONEXISTENT.*')
414
415
 
415
416
    def test_status_multiple_nonexistent_files(self):
416
 
        # bzr st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
 
417
        # brz st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
417
418
        wt = self._prepare_nonexistent()
418
419
        expected = [
419
 
          'removed:\n',
420
 
          '  FILE_E\n',
421
 
          'modified:\n',
422
 
          '  FILE_B\n',
423
 
          '  FILE_C\n',
424
 
          'nonexistent:\n',
425
 
          '  ANOTHER_NONEXISTENT\n',
426
 
          '  NONEXISTENT\n',
427
 
          ]
 
420
            'removed:\n',
 
421
            '  FILE_E\n',
 
422
            'modified:\n',
 
423
            '  FILE_B\n',
 
424
            '  FILE_C\n',
 
425
            'nonexistent:\n',
 
426
            '  ANOTHER_NONEXISTENT\n',
 
427
            '  NONEXISTENT\n',
 
428
            ]
428
429
        out, err = self.run_bzr('status NONEXISTENT '
429
430
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
430
431
                                'FILE_C FILE_D FILE_E', retcode=3)
433
434
                              r'.*ERROR: Path\(s\) do not exist: '
434
435
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
435
436
        expected = [
436
 
          ' D  FILE_E\n',
437
 
          ' M  FILE_C\n',
438
 
          ' M  FILE_B\n',
439
 
          'X   ANOTHER_NONEXISTENT\n',
440
 
          'X   NONEXISTENT\n',
441
 
          ]
 
437
            ' M  FILE_B\n',
 
438
            ' M  FILE_C\n',
 
439
            ' D  FILE_E\n',
 
440
            'X   ANOTHER_NONEXISTENT\n',
 
441
            'X   NONEXISTENT\n',
 
442
            ]
442
443
        out, err = self.run_bzr('status --short NONEXISTENT '
443
444
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
444
445
                                'FILE_C FILE_D FILE_E', retcode=3)
448
449
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
449
450
 
450
451
    def test_status_nonexistent_file_with_unversioned(self):
451
 
        # bzr st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
 
452
        # brz st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
452
453
        wt = self._prepare_nonexistent()
453
454
        expected = [
454
 
          'removed:\n',
455
 
          '  FILE_E\n',
456
 
          'added:\n',
457
 
          '  FILE_Q\n',
458
 
          'modified:\n',
459
 
          '  FILE_B\n',
460
 
          '  FILE_C\n',
461
 
          'unknown:\n',
462
 
          '  UNVERSIONED_BUT_EXISTING\n',
463
 
          'nonexistent:\n',
464
 
          '  NONEXISTENT\n',
465
 
          ]
 
455
            'removed:\n',
 
456
            '  FILE_E\n',
 
457
            'added:\n',
 
458
            '  FILE_Q\n',
 
459
            'modified:\n',
 
460
            '  FILE_B\n',
 
461
            '  FILE_C\n',
 
462
            'unknown:\n',
 
463
            '  UNVERSIONED_BUT_EXISTING\n',
 
464
            'nonexistent:\n',
 
465
            '  NONEXISTENT\n',
 
466
            ]
466
467
        out, err = self.run_bzr('status NONEXISTENT '
467
468
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
468
469
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
470
471
        self.assertContainsRe(err,
471
472
                              r'.*ERROR: Path\(s\) do not exist: '
472
473
                              'NONEXISTENT.*')
473
 
        expected = [
474
 
          '+N  FILE_Q\n',
475
 
          '?   UNVERSIONED_BUT_EXISTING\n',
476
 
          ' D  FILE_E\n',
477
 
          ' M  FILE_C\n',
478
 
          ' M  FILE_B\n',
479
 
          'X   NONEXISTENT\n',
480
 
          ]
481
 
        expected.sort()
 
474
        expected = sorted([
 
475
            '+N  FILE_Q\n',
 
476
            '?   UNVERSIONED_BUT_EXISTING\n',
 
477
            ' D  FILE_E\n',
 
478
            ' M  FILE_C\n',
 
479
            ' M  FILE_B\n',
 
480
            'X   NONEXISTENT\n',
 
481
            ])
482
482
        out, err = self.run_bzr('status --short NONEXISTENT '
483
483
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
484
484
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
492
492
    def test_status_out_of_date(self):
493
493
        """Simulate status of out-of-date tree after remote push"""
494
494
        tree = self.make_branch_and_tree('.')
495
 
        self.build_tree_contents([('a', 'foo\n')])
496
 
        tree.lock_write()
497
 
        try:
 
495
        self.build_tree_contents([('a', b'foo\n')])
 
496
        with tree.lock_write():
498
497
            tree.add(['a'])
499
498
            tree.commit('add test file')
500
499
            # simulate what happens after a remote push
501
 
            tree.set_last_revision("0")
502
 
        finally:
503
 
            # before run another commands we should unlock tree
504
 
            tree.unlock()
 
500
            tree.set_last_revision(b"0")
505
501
        out, err = self.run_bzr('status')
506
 
        self.assertEqual("working tree is out of date, run 'bzr update'\n",
 
502
        self.assertEqual("working tree is out of date, run 'brz update'\n",
507
503
                         err)
508
504
 
509
505
    def test_status_on_ignored(self):
517
513
        result = self.run_bzr('status')[0]
518
514
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
519
515
        short_result = self.run_bzr('status --short')[0]
520
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
516
        self.assertContainsRe(short_result, "\\?   test1.c\n")
521
517
 
522
518
        result = self.run_bzr('status test1.c')[0]
523
519
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
524
520
        short_result = self.run_bzr('status --short test1.c')[0]
525
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
521
        self.assertContainsRe(short_result, "\\?   test1.c\n")
526
522
 
527
523
        result = self.run_bzr('status test1.c~')[0]
528
524
        self.assertContainsRe(result, "ignored:\n  test1.c~\n")
535
531
        self.assertContainsRe(short_result, "I   test1.c~\nI   test2.c~\n")
536
532
 
537
533
        result = self.run_bzr('status test1.c test1.c~ test2.c~')[0]
538
 
        self.assertContainsRe(result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
539
 
        short_result = self.run_bzr('status --short test1.c test1.c~ test2.c~')[0]
540
 
        self.assertContainsRe(short_result, "\?   test1.c\nI   test1.c~\nI   test2.c~\n")
 
534
        self.assertContainsRe(
 
535
            result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
 
536
        short_result = self.run_bzr(
 
537
            'status --short test1.c test1.c~ test2.c~')[0]
 
538
        self.assertContainsRe(
 
539
            short_result, "\\?   test1.c\nI   test1.c~\nI   test2.c~\n")
541
540
 
542
541
    def test_status_write_lock(self):
543
542
        """Test that status works without fetching history and
549
548
        wt = self.make_branch_and_tree('branch1')
550
549
        b = wt.branch
551
550
        wt.commit('Empty commit 1')
552
 
        wt2 = b.bzrdir.sprout('branch2').open_workingtree()
 
551
        wt2 = b.controldir.sprout('branch2').open_workingtree()
553
552
        wt2.commit('Empty commit 2')
554
553
        out, err = self.run_bzr('status branch1 -rbranch:branch2')
555
554
        self.assertEqual('', out)
564
563
        self.build_tree(['bye.c'])
565
564
        wt.add('bye.c')
566
565
        self.assertStatus([
567
 
                'added:\n',
568
 
                '  bye.c\n',
569
 
                '1 shelf exists. See "bzr shelve --list" for details.\n',
 
566
            'added:\n',
 
567
            '  bye.c\n',
 
568
            '1 shelf exists. See "brz shelve --list" for details.\n',
570
569
            ],
571
570
            wt)
572
571
        self.run_bzr(['shelve', '--all', '-m', 'bar'])
574
573
        wt.add('eggs.c')
575
574
        wt.add('spam.c')
576
575
        self.assertStatus([
577
 
                'added:\n',
578
 
                '  eggs.c\n',
579
 
                '  spam.c\n',
580
 
                '2 shelves exist. See "bzr shelve --list" for details.\n',
 
576
            'added:\n',
 
577
            '  eggs.c\n',
 
578
            '  spam.c\n',
 
579
            '2 shelves exist. See "brz shelve --list" for details.\n',
581
580
            ],
582
581
            wt)
583
582
        self.assertStatus([
584
 
                'added:\n',
585
 
                '  spam.c\n',
 
583
            'added:\n',
 
584
            '  spam.c\n',
586
585
            ],
587
586
            wt,
588
587
            specific_files=['spam.c'])
624
623
 
625
624
        self.build_tree(['world.txt'])
626
625
        result = self.run_bzr("status -r 0")[0]
627
 
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
 
626
        self.assertContainsRe(result, "added:\n  hello.txt\n"
628
627
                                      "unknown:\n  world.txt\n")
629
628
        result2 = self.run_bzr("status -r 0..")[0]
630
 
        self.assertEquals(result2, result)
 
629
        self.assertEqual(result2, result)
631
630
 
632
631
    def test_status_short(self):
633
632
        tree = self.make_branch_and_tree('.')
646
645
 
647
646
        self.build_tree(['world.txt'])
648
647
        result = self.run_bzr("status -S -r 0")[0]
649
 
        self.assertContainsRe(result, "[+]N  hello.txt\n" \
 
648
        self.assertContainsRe(result, "[+]N  hello.txt\n"
650
649
                                      "[?]   world.txt\n")
651
650
        result2 = self.run_bzr("status -S -r 0..")[0]
652
 
        self.assertEquals(result2, result)
 
651
        self.assertEqual(result2, result)
653
652
 
654
653
    def test_status_versioned(self):
655
654
        tree = self.make_branch_and_tree('.')
671
670
        self.assertContainsRe(result, "added:\n  hello.txt\n")
672
671
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
673
672
        result2 = self.run_bzr("status --versioned -r 0..")[0]
674
 
        self.assertEquals(result2, result)
 
673
        self.assertEqual(result2, result)
675
674
 
676
675
    def test_status_SV(self):
677
676
        tree = self.make_branch_and_tree('.')
693
692
        self.assertContainsRe(result, "[+]N  hello.txt\n")
694
693
 
695
694
        result2 = self.run_bzr("status -SV -r 0..")[0]
696
 
        self.assertEquals(result2, result)
 
695
        self.assertEqual(result2, result)
697
696
 
698
697
    def assertStatusContains(self, pattern, short=False):
699
698
        """Run status, and assert it contains the given pattern"""
710
709
        tree.commit('added file')
711
710
        unlink('file')
712
711
        self.build_tree(['file/'])
713
 
        self.assertStatusContains('kind changed:\n  file \(file => directory\)')
 
712
        self.assertStatusContains(
 
713
            'kind changed:\n  file \\(file => directory\\)')
714
714
        tree.rename_one('file', 'directory')
715
 
        self.assertStatusContains('renamed:\n  file/ => directory/\n' \
 
715
        self.assertStatusContains('renamed:\n  file => directory/\n'
716
716
                                  'modified:\n  directory/\n')
717
717
        rmdir('directory')
718
718
        self.assertStatusContains('removed:\n  file\n')
725
725
        unlink('file')
726
726
        self.build_tree(['file/'])
727
727
        self.assertStatusContains('K  file => file/',
728
 
                                   short=True)
 
728
                                  short=True)
729
729
        tree.rename_one('file', 'directory')
730
730
        self.assertStatusContains('RK  file => directory/',
731
 
                                   short=True)
 
731
                                  short=True)
732
732
        rmdir('directory')
733
733
        self.assertStatusContains('RD  file => directory',
734
 
                                   short=True)
 
734
                                  short=True)
735
735
 
736
736
    def test_status_illegal_revision_specifiers(self):
737
737
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
742
742
        self.build_tree(['a/a'])
743
743
        a_tree.add('a')
744
744
        a_tree.commit('a')
745
 
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
745
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
746
746
        self.build_tree(['b/b'])
747
747
        b_tree.add('b')
748
748
        b_tree.commit('b')
749
749
 
750
750
        self.run_bzr('merge ../b', working_dir='a')
751
751
        out, err = self.run_bzr('status --no-pending', working_dir='a')
752
 
        self.assertEquals(out, "added:\n  b\n")
 
752
        self.assertEqual(out, "added:\n  b\n")
753
753
 
754
754
    def test_pending_specific_files(self):
755
755
        """With a specific file list, pending merges are not shown."""
756
756
        tree = self.make_branch_and_tree('tree')
757
 
        self.build_tree_contents([('tree/a', 'content of a\n')])
 
757
        self.build_tree_contents([('tree/a', b'content of a\n')])
758
758
        tree.add('a')
759
759
        r1_id = tree.commit('one')
760
 
        alt = tree.bzrdir.sprout('alt').open_workingtree()
761
 
        self.build_tree_contents([('alt/a', 'content of a\nfrom alt\n')])
 
760
        alt = tree.controldir.sprout('alt').open_workingtree()
 
761
        self.build_tree_contents([('alt/a', b'content of a\nfrom alt\n')])
762
762
        alt_id = alt.commit('alt')
763
763
        tree.merge_from_branch(alt.branch)
764
764
        output = self.make_utf8_encoded_stringio()
765
765
        show_tree_status(tree, to_file=output)
766
 
        self.assertContainsRe(output.getvalue(), 'pending merge')
 
766
        self.assertContainsRe(output.getvalue(), b'pending merge')
767
767
        out, err = self.run_bzr('status tree/a')
768
768
        self.assertNotContainsRe(out, 'pending merge')
769
769
 
775
775
        working_tree = self.make_branch_and_tree(u'.')
776
776
        filename = u'hell\u00d8'
777
777
        try:
778
 
            self.build_tree_contents([(filename, 'contents of hello')])
 
778
            self.build_tree_contents([(filename, b'contents of hello')])
779
779
        except UnicodeEncodeError:
780
780
            raise TestSkipped("can't build unicode working tree in "
781
 
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
781
                              "filesystem encoding %s" % sys.getfilesystemencoding())
782
782
        working_tree.add(filename)
783
783
        return working_tree
784
784
 
787
787
        working_tree = self.make_uncommitted_tree()
788
788
        stdout, stderr = self.run_bzr("status")
789
789
 
790
 
        self.assertEquals(stdout, """\
 
790
        self.assertEqual(stdout, """\
791
791
added:
792
792
  hell?
793
793
""")
797
797
        working_tree = self.make_uncommitted_tree()
798
798
        stdout, stderr = self.run_bzr('status')
799
799
 
800
 
        self.assertEquals(stdout, u"""\
 
800
        expected = u"""\
801
801
added:
802
802
  hell\u00d8
803
 
""".encode('latin-1'))
804
 
 
 
803
"""
 
804
        self.assertEqual(stdout, expected)