/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: Jelmer Vernooij
  • Date: 2019-02-15 17:41:17 UTC
  • mto: (7290.1.2 work)
  • mto: This revision was merged to the branch mainline in revision 7295.
  • Revision ID: jelmer@jelmer.uk-20190215174117-o9w1am2z88mg9g1q
Update references to home location.

~/.config/breezy rather than ~/.bazaar.

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
27
26
from os import mkdir, chdir, rmdir, unlink
28
27
import sys
29
 
from tempfile import TemporaryFile
30
28
 
31
 
from bzrlib import (
32
 
    bzrdir,
 
29
from ... import (
33
30
    conflicts,
34
31
    errors,
35
32
    osutils,
36
 
    )
37
 
import bzrlib.branch
38
 
from bzrlib.osutils import pathjoin
39
 
from bzrlib.revisionspec import RevisionSpec
40
 
from bzrlib.status import show_tree_status
41
 
from bzrlib.tests import TestCaseWithTransport, TestSkipped
42
 
from bzrlib.workingtree import WorkingTree
 
33
    status,
 
34
    )
 
35
from breezy.bzr import (
 
36
    bzrdir,
 
37
    )
 
38
import breezy.branch
 
39
from ...osutils import pathjoin
 
40
from ...revisionspec import RevisionSpec
 
41
from ...sixish import (
 
42
    BytesIO,
 
43
    StringIO,
 
44
    PY3,
 
45
    )
 
46
from ...status import show_tree_status
 
47
from .. import TestCaseWithTransport, TestSkipped
 
48
from ...workingtree import WorkingTree
43
49
 
44
50
 
45
51
class BranchStatus(TestCaseWithTransport):
46
52
 
47
 
    def assertStatus(self, expected_lines, working_tree,
48
 
        revision=None, short=False, pending=True, verbose=False):
 
53
    def setUp(self):
 
54
        super(BranchStatus, self).setUp()
 
55
        # As TestCase.setUp clears all hooks, we install this default
 
56
        # post_status hook handler for the test.
 
57
        status.hooks.install_named_hook('post_status',
 
58
                                        status._show_shelve_summary,
 
59
                                        'brz status')
 
60
 
 
61
    def assertStatus(self, expected_lines, working_tree, specific_files=None,
 
62
                     revision=None, short=False, pending=True, verbose=False):
49
63
        """Run status in working_tree and look for output.
50
64
 
51
65
        :param expected_lines: The lines to look for.
52
66
        :param working_tree: The tree to run status in.
53
67
        """
54
 
        output_string = self.status_string(working_tree, revision, short,
55
 
                pending, verbose)
 
68
        output_string = self.status_string(working_tree, specific_files, revision, short,
 
69
                                           pending, verbose)
56
70
        self.assertEqual(expected_lines, output_string.splitlines(True))
57
71
 
58
 
    def status_string(self, wt, revision=None, short=False, pending=True,
59
 
        verbose=False):
60
 
        # use a real file rather than StringIO because it doesn't handle
61
 
        # Unicode very well.
62
 
        tof = codecs.getwriter('utf-8')(TemporaryFile())
63
 
        show_tree_status(wt, to_file=tof, revision=revision, short=short,
64
 
                show_pending=pending, verbose=verbose)
65
 
        tof.seek(0)
66
 
        return tof.read().decode('utf-8')
 
72
    def status_string(self, wt, specific_files=None, revision=None,
 
73
                      short=False, pending=True, verbose=False):
 
74
        uio = self.make_utf8_encoded_stringio()
 
75
        show_tree_status(wt, specific_files=specific_files, to_file=uio,
 
76
                         revision=revision, short=short, show_pending=pending,
 
77
                         verbose=verbose)
 
78
        return uio.getvalue().decode('utf-8')
67
79
 
68
80
    def test_branch_status(self):
69
81
        """Test basic branch status"""
77
89
 
78
90
        self.build_tree(['hello.c', 'bye.c'])
79
91
        self.assertStatus([
80
 
                'unknown:\n',
81
 
                '  bye.c\n',
82
 
                '  hello.c\n',
 
92
            'unknown:\n',
 
93
            '  bye.c\n',
 
94
            '  hello.c\n',
83
95
            ],
84
96
            wt)
85
97
        self.assertStatus([
86
 
                '?   bye.c\n',
87
 
                '?   hello.c\n',
 
98
            '?   bye.c\n',
 
99
            '?   hello.c\n',
88
100
            ],
89
101
            wt, short=True)
90
102
 
91
103
        # add a commit to allow showing pending merges.
92
104
        wt.commit('create a parent to allow testing merge output')
93
105
 
94
 
        wt.add_parent_tree_id('pending@pending-0-0')
 
106
        wt.add_parent_tree_id(b'pending@pending-0-0')
95
107
        self.assertStatus([
96
 
                'unknown:\n',
97
 
                '  bye.c\n',
98
 
                '  hello.c\n',
99
 
                'pending merge tips: (use -v to see all merge revisions)\n',
100
 
                '  (ghost) pending@pending-0-0\n',
 
108
            'unknown:\n',
 
109
            '  bye.c\n',
 
110
            '  hello.c\n',
 
111
            'pending merge tips: (use -v to see all merge revisions)\n',
 
112
            '  (ghost) pending@pending-0-0\n',
101
113
            ],
102
114
            wt)
103
115
        self.assertStatus([
104
 
                'unknown:\n',
105
 
                '  bye.c\n',
106
 
                '  hello.c\n',
107
 
                'pending merges:\n',
108
 
                '  (ghost) pending@pending-0-0\n',
 
116
            'unknown:\n',
 
117
            '  bye.c\n',
 
118
            '  hello.c\n',
 
119
            'pending merges:\n',
 
120
            '  (ghost) pending@pending-0-0\n',
109
121
            ],
110
122
            wt, verbose=True)
111
123
        self.assertStatus([
112
 
                '?   bye.c\n',
113
 
                '?   hello.c\n',
114
 
                'P   (ghost) pending@pending-0-0\n',
 
124
            '?   bye.c\n',
 
125
            '?   hello.c\n',
 
126
            'P   (ghost) pending@pending-0-0\n',
115
127
            ],
116
128
            wt, short=True)
117
129
        self.assertStatus([
118
 
                'unknown:\n',
119
 
                '  bye.c\n',
120
 
                '  hello.c\n',
 
130
            'unknown:\n',
 
131
            '  bye.c\n',
 
132
            '  hello.c\n',
121
133
            ],
122
134
            wt, pending=False)
123
135
        self.assertStatus([
124
 
                '?   bye.c\n',
125
 
                '?   hello.c\n',
 
136
            '?   bye.c\n',
 
137
            '?   hello.c\n',
126
138
            ],
127
139
            wt, short=True, pending=False)
128
140
 
137
149
 
138
150
        revs = [RevisionSpec.from_string('0')]
139
151
        self.assertStatus([
140
 
                'added:\n',
141
 
                '  bye.c\n',
142
 
                '  hello.c\n'
 
152
            'added:\n',
 
153
            '  bye.c\n',
 
154
            '  hello.c\n'
143
155
            ],
144
156
            wt,
145
157
            revision=revs)
150
162
 
151
163
        revs.append(RevisionSpec.from_string('1'))
152
164
        self.assertStatus([
153
 
                'added:\n',
154
 
                '  bye.c\n',
155
 
                '  hello.c\n',
 
165
            'added:\n',
 
166
            '  bye.c\n',
 
167
            '  hello.c\n',
156
168
            ],
157
169
            wt,
158
170
            revision=revs)
163
175
        wt = self.make_branch_and_tree('branch')
164
176
        b = wt.branch
165
177
        wt.commit("Empty commit 1")
166
 
        b_2_dir = b.bzrdir.sprout('./copy')
 
178
        b_2_dir = b.controldir.sprout('./copy')
167
179
        b_2 = b_2_dir.open_branch()
168
180
        wt2 = b_2_dir.open_workingtree()
169
181
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
173
185
        self.assertEndsWith(message, "Empty commit 2\n")
174
186
        wt2.commit("merged")
175
187
        # must be long to make sure we see elipsis at the end
176
 
        wt.commit("Empty commit 3 " +
177
 
                   "blah blah blah blah " * 100)
 
188
        wt.commit("Empty commit 3 "
 
189
                  + "blah blah blah blah " * 100)
178
190
        wt2.merge_from_branch(wt.branch)
179
191
        message = self.status_string(wt2, verbose=True)
180
192
        self.assertStartsWith(message, "pending merges:\n")
181
 
        self.assert_("Empty commit 3" in message)
 
193
        self.assertTrue("Empty commit 3" in message)
182
194
        self.assertEndsWith(message, "...\n")
183
195
 
184
196
    def test_tree_status_ignores(self):
188
200
        wt.commit('commit .bzrignore')
189
201
        self.build_tree(['foo.c', 'foo.c~'])
190
202
        self.assertStatus([
191
 
                'unknown:\n',
192
 
                '  foo.c\n',
193
 
                ],
194
 
                wt)
 
203
            'unknown:\n',
 
204
            '  foo.c\n',
 
205
            ],
 
206
            wt)
195
207
        self.assertStatus([
196
 
                '?   foo.c\n',
197
 
                ],
198
 
                wt, short=True)
 
208
            '?   foo.c\n',
 
209
            ],
 
210
            wt, short=True)
199
211
 
200
212
    def test_tree_status_specific_files(self):
201
213
        """Tests branch status with given specific files"""
202
214
        wt = self.make_branch_and_tree('.')
203
215
        b = wt.branch
204
216
 
205
 
        self.build_tree(['directory/','directory/hello.c', 'bye.c','test.c','dir2/'])
 
217
        self.build_tree(['directory/', 'directory/hello.c',
 
218
                         'bye.c', 'test.c', 'dir2/',
 
219
                         'missing.c'])
206
220
        wt.add('directory')
207
221
        wt.add('test.c')
208
222
        wt.commit('testing')
209
 
 
210
 
        self.assertStatus([
211
 
                'unknown:\n',
212
 
                '  bye.c\n',
213
 
                '  dir2/\n',
214
 
                '  directory/hello.c\n'
215
 
                ],
216
 
                wt)
217
 
 
218
 
        self.assertStatus([
219
 
                '?   bye.c\n',
220
 
                '?   dir2/\n',
221
 
                '?   directory/hello.c\n'
222
 
                ],
223
 
                wt, short=True)
 
223
        wt.add('missing.c')
 
224
        unlink('missing.c')
 
225
 
 
226
        self.assertStatus([
 
227
            'missing:\n',
 
228
            '  missing.c\n',
 
229
            'unknown:\n',
 
230
            '  bye.c\n',
 
231
            '  dir2/\n',
 
232
            '  directory/hello.c\n'
 
233
            ],
 
234
            wt)
 
235
 
 
236
        self.assertStatus([
 
237
            '?   bye.c\n',
 
238
            '?   dir2/\n',
 
239
            '?   directory/hello.c\n',
 
240
            '+!  missing.c\n',
 
241
            ],
 
242
            wt, short=True)
224
243
 
225
244
        tof = StringIO()
226
245
        self.assertRaises(errors.PathsDoNotExist,
227
246
                          show_tree_status,
228
 
                          wt, specific_files=['bye.c','test.c','absent.c'],
 
247
                          wt, specific_files=['bye.c', 'test.c', 'absent.c'],
229
248
                          to_file=tof)
230
249
 
231
250
        tof = StringIO()
232
251
        show_tree_status(wt, specific_files=['directory'], to_file=tof)
233
252
        tof.seek(0)
234
 
        self.assertEquals(tof.readlines(),
235
 
                          ['unknown:\n',
236
 
                           '  directory/hello.c\n'
237
 
                           ])
 
253
        self.assertEqual(tof.readlines(),
 
254
                         ['unknown:\n',
 
255
                          '  directory/hello.c\n'
 
256
                          ])
238
257
        tof = StringIO()
239
258
        show_tree_status(wt, specific_files=['directory'], to_file=tof,
240
259
                         short=True)
241
260
        tof.seek(0)
242
 
        self.assertEquals(tof.readlines(), ['?   directory/hello.c\n'])
 
261
        self.assertEqual(tof.readlines(), ['?   directory/hello.c\n'])
243
262
 
244
263
        tof = StringIO()
245
264
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
246
265
        tof.seek(0)
247
 
        self.assertEquals(tof.readlines(),
248
 
                          ['unknown:\n',
249
 
                           '  dir2/\n'
250
 
                           ])
 
266
        self.assertEqual(tof.readlines(),
 
267
                         ['unknown:\n',
 
268
                          '  dir2/\n'
 
269
                          ])
251
270
        tof = StringIO()
252
271
        show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
253
272
        tof.seek(0)
254
 
        self.assertEquals(tof.readlines(), ['?   dir2/\n'])
 
273
        self.assertEqual(tof.readlines(), ['?   dir2/\n'])
255
274
 
256
275
        tof = StringIO()
257
276
        revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
258
277
        show_tree_status(wt, specific_files=['test.c'], to_file=tof,
259
278
                         short=True, revision=revs)
260
279
        tof.seek(0)
261
 
        self.assertEquals(tof.readlines(), ['+N  test.c\n'])
 
280
        self.assertEqual(tof.readlines(), ['+N  test.c\n'])
 
281
 
 
282
        tof = StringIO()
 
283
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof)
 
284
        tof.seek(0)
 
285
        self.assertEqual(tof.readlines(),
 
286
                         ['missing:\n',
 
287
                          '  missing.c\n'])
 
288
 
 
289
        tof = StringIO()
 
290
        show_tree_status(wt, specific_files=['missing.c'], to_file=tof,
 
291
                         short=True)
 
292
        tof.seek(0)
 
293
        self.assertEqual(tof.readlines(),
 
294
                         ['+!  missing.c\n'])
262
295
 
263
296
    def test_specific_files_conflicts(self):
264
297
        tree = self.make_branch_and_tree('.')
267
300
        tree.commit('added dir2')
268
301
        tree.set_conflicts(conflicts.ConflictList(
269
302
            [conflicts.ContentsConflict('foo')]))
270
 
        tof = StringIO()
 
303
        tof = BytesIO()
271
304
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
272
 
        self.assertEqualDiff('', tof.getvalue())
 
305
        self.assertEqualDiff(b'', tof.getvalue())
273
306
        tree.set_conflicts(conflicts.ConflictList(
274
307
            [conflicts.ContentsConflict('dir2')]))
275
308
        tof = StringIO()
294
327
        wt.add('FILE_D')
295
328
        wt.add('FILE_E')
296
329
        wt.commit('Create five empty files.')
297
 
        open('FILE_B', 'w').write('Modification to file FILE_B.')
298
 
        open('FILE_C', 'w').write('Modification to file FILE_C.')
 
330
        with open('FILE_B', 'w') as f:
 
331
            f.write('Modification to file FILE_B.')
 
332
        with open('FILE_C', 'w') as f:
 
333
            f.write('Modification to file FILE_C.')
299
334
        unlink('FILE_E')  # FILE_E will be versioned but missing
300
 
        open('FILE_Q', 'w').write('FILE_Q is added but not committed.')
 
335
        with open('FILE_Q', 'w') as f:
 
336
            f.write('FILE_Q is added but not committed.')
301
337
        wt.add('FILE_Q')  # FILE_Q will be added but not committed
302
338
        open('UNVERSIONED_BUT_EXISTING', 'w')
303
339
        return wt
330
366
        # Okay, everything's looking good with the existent files.
331
367
        # Let's see what happens when we throw in non-existent files.
332
368
 
333
 
        # bzr st [--short] NONEXISTENT '
 
369
        # brz st [--short] NONEXISTENT '
334
370
        expected = [
335
 
          'nonexistent:\n',
336
 
          '  NONEXISTENT\n',
337
 
          ]
 
371
            'nonexistent:\n',
 
372
            '  NONEXISTENT\n',
 
373
            ]
338
374
        out, err = self.run_bzr('status NONEXISTENT', retcode=3)
339
375
        self.assertEqual(expected, out.splitlines(True))
340
376
        self.assertContainsRe(err,
341
377
                              r'.*ERROR: Path\(s\) do not exist: '
342
378
                              'NONEXISTENT.*')
343
379
        expected = [
344
 
          'X:   NONEXISTENT\n',
345
 
          ]
 
380
            'X:   NONEXISTENT\n',
 
381
            ]
346
382
        out, err = self.run_bzr('status --short NONEXISTENT', retcode=3)
347
383
        self.assertContainsRe(err,
348
384
                              r'.*ERROR: Path\(s\) do not exist: '
349
385
                              'NONEXISTENT.*')
350
386
 
351
387
    def test_status_nonexistent_file_with_others(self):
352
 
        # bzr st [--short] NONEXISTENT ...others..
 
388
        # brz st [--short] NONEXISTENT ...others..
353
389
        wt = self._prepare_nonexistent()
354
390
        expected = [
355
 
          'removed:\n',
356
 
          '  FILE_E\n',
357
 
          'modified:\n',
358
 
          '  FILE_B\n',
359
 
          '  FILE_C\n',
360
 
          'nonexistent:\n',
361
 
          '  NONEXISTENT\n',
362
 
          ]
 
391
            'removed:\n',
 
392
            '  FILE_E\n',
 
393
            'modified:\n',
 
394
            '  FILE_B\n',
 
395
            '  FILE_C\n',
 
396
            'nonexistent:\n',
 
397
            '  NONEXISTENT\n',
 
398
            ]
363
399
        out, err = self.run_bzr('status NONEXISTENT '
364
400
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
365
401
                                retcode=3)
368
404
                              r'.*ERROR: Path\(s\) do not exist: '
369
405
                              'NONEXISTENT.*')
370
406
        expected = [
371
 
          ' D  FILE_E\n',
372
 
          ' M  FILE_C\n',
373
 
          ' M  FILE_B\n',
374
 
          'X   NONEXISTENT\n',
375
 
          ]
 
407
            ' M  FILE_B\n',
 
408
            ' M  FILE_C\n',
 
409
            ' D  FILE_E\n',
 
410
            'X   NONEXISTENT\n',
 
411
            ]
376
412
        out, err = self.run_bzr('status --short NONEXISTENT '
377
413
                                'FILE_A FILE_B FILE_C FILE_D FILE_E',
378
414
                                retcode=3)
382
418
                              'NONEXISTENT.*')
383
419
 
384
420
    def test_status_multiple_nonexistent_files(self):
385
 
        # bzr st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
 
421
        # brz st [--short] NONEXISTENT ... ANOTHER_NONEXISTENT ...
386
422
        wt = self._prepare_nonexistent()
387
423
        expected = [
388
 
          'removed:\n',
389
 
          '  FILE_E\n',
390
 
          'modified:\n',
391
 
          '  FILE_B\n',
392
 
          '  FILE_C\n',
393
 
          'nonexistent:\n',
394
 
          '  ANOTHER_NONEXISTENT\n',
395
 
          '  NONEXISTENT\n',
396
 
          ]
 
424
            'removed:\n',
 
425
            '  FILE_E\n',
 
426
            'modified:\n',
 
427
            '  FILE_B\n',
 
428
            '  FILE_C\n',
 
429
            'nonexistent:\n',
 
430
            '  ANOTHER_NONEXISTENT\n',
 
431
            '  NONEXISTENT\n',
 
432
            ]
397
433
        out, err = self.run_bzr('status NONEXISTENT '
398
434
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
399
435
                                'FILE_C FILE_D FILE_E', retcode=3)
402
438
                              r'.*ERROR: Path\(s\) do not exist: '
403
439
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
404
440
        expected = [
405
 
          ' D  FILE_E\n',
406
 
          ' M  FILE_C\n',
407
 
          ' M  FILE_B\n',
408
 
          'X   ANOTHER_NONEXISTENT\n',
409
 
          'X   NONEXISTENT\n',
410
 
          ]
 
441
            ' M  FILE_B\n',
 
442
            ' M  FILE_C\n',
 
443
            ' D  FILE_E\n',
 
444
            'X   ANOTHER_NONEXISTENT\n',
 
445
            'X   NONEXISTENT\n',
 
446
            ]
411
447
        out, err = self.run_bzr('status --short NONEXISTENT '
412
448
                                'FILE_A FILE_B ANOTHER_NONEXISTENT '
413
449
                                'FILE_C FILE_D FILE_E', retcode=3)
417
453
                              'ANOTHER_NONEXISTENT NONEXISTENT.*')
418
454
 
419
455
    def test_status_nonexistent_file_with_unversioned(self):
420
 
        # bzr st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
 
456
        # brz st [--short] NONEXISTENT A B UNVERSIONED_BUT_EXISTING C D E Q
421
457
        wt = self._prepare_nonexistent()
422
458
        expected = [
423
 
          'removed:\n',
424
 
          '  FILE_E\n',
425
 
          'added:\n',
426
 
          '  FILE_Q\n',
427
 
          'modified:\n',
428
 
          '  FILE_B\n',
429
 
          '  FILE_C\n',
430
 
          'unknown:\n',
431
 
          '  UNVERSIONED_BUT_EXISTING\n',
432
 
          'nonexistent:\n',
433
 
          '  NONEXISTENT\n',
434
 
          ]
 
459
            'removed:\n',
 
460
            '  FILE_E\n',
 
461
            'added:\n',
 
462
            '  FILE_Q\n',
 
463
            'modified:\n',
 
464
            '  FILE_B\n',
 
465
            '  FILE_C\n',
 
466
            'unknown:\n',
 
467
            '  UNVERSIONED_BUT_EXISTING\n',
 
468
            'nonexistent:\n',
 
469
            '  NONEXISTENT\n',
 
470
            ]
435
471
        out, err = self.run_bzr('status NONEXISTENT '
436
472
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
437
473
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
439
475
        self.assertContainsRe(err,
440
476
                              r'.*ERROR: Path\(s\) do not exist: '
441
477
                              'NONEXISTENT.*')
442
 
        expected = [
443
 
          '+N  FILE_Q\n',
444
 
          '?   UNVERSIONED_BUT_EXISTING\n',
445
 
          ' D  FILE_E\n',
446
 
          ' M  FILE_C\n',
447
 
          ' M  FILE_B\n',
448
 
          'X   NONEXISTENT\n',
449
 
          ]
 
478
        expected = sorted([
 
479
            '+N  FILE_Q\n',
 
480
            '?   UNVERSIONED_BUT_EXISTING\n',
 
481
            ' D  FILE_E\n',
 
482
            ' M  FILE_C\n',
 
483
            ' M  FILE_B\n',
 
484
            'X   NONEXISTENT\n',
 
485
            ])
450
486
        out, err = self.run_bzr('status --short NONEXISTENT '
451
487
                                'FILE_A FILE_B UNVERSIONED_BUT_EXISTING '
452
488
                                'FILE_C FILE_D FILE_E FILE_Q', retcode=3)
453
 
        self.assertEqual(expected, out.splitlines(True))
 
489
        actual = out.splitlines(True)
 
490
        actual.sort()
 
491
        self.assertEqual(expected, actual)
454
492
        self.assertContainsRe(err,
455
493
                              r'.*ERROR: Path\(s\) do not exist: '
456
494
                              'NONEXISTENT.*')
458
496
    def test_status_out_of_date(self):
459
497
        """Simulate status of out-of-date tree after remote push"""
460
498
        tree = self.make_branch_and_tree('.')
461
 
        self.build_tree_contents([('a', 'foo\n')])
 
499
        self.build_tree_contents([('a', b'foo\n')])
462
500
        tree.lock_write()
463
501
        try:
464
502
            tree.add(['a'])
465
503
            tree.commit('add test file')
466
504
            # simulate what happens after a remote push
467
 
            tree.set_last_revision("0")
 
505
            tree.set_last_revision(b"0")
468
506
        finally:
469
507
            # before run another commands we should unlock tree
470
508
            tree.unlock()
471
509
        out, err = self.run_bzr('status')
472
 
        self.assertEqual("working tree is out of date, run 'bzr update'\n",
 
510
        self.assertEqual("working tree is out of date, run 'brz update'\n",
473
511
                         err)
474
512
 
475
513
    def test_status_on_ignored(self):
483
521
        result = self.run_bzr('status')[0]
484
522
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
485
523
        short_result = self.run_bzr('status --short')[0]
486
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
524
        self.assertContainsRe(short_result, "\\?   test1.c\n")
487
525
 
488
526
        result = self.run_bzr('status test1.c')[0]
489
527
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
490
528
        short_result = self.run_bzr('status --short test1.c')[0]
491
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
529
        self.assertContainsRe(short_result, "\\?   test1.c\n")
492
530
 
493
531
        result = self.run_bzr('status test1.c~')[0]
494
532
        self.assertContainsRe(result, "ignored:\n  test1.c~\n")
501
539
        self.assertContainsRe(short_result, "I   test1.c~\nI   test2.c~\n")
502
540
 
503
541
        result = self.run_bzr('status test1.c test1.c~ test2.c~')[0]
504
 
        self.assertContainsRe(result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
505
 
        short_result = self.run_bzr('status --short test1.c test1.c~ test2.c~')[0]
506
 
        self.assertContainsRe(short_result, "\?   test1.c\nI   test1.c~\nI   test2.c~\n")
 
542
        self.assertContainsRe(
 
543
            result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
 
544
        short_result = self.run_bzr(
 
545
            'status --short test1.c test1.c~ test2.c~')[0]
 
546
        self.assertContainsRe(
 
547
            short_result, "\\?   test1.c\nI   test1.c~\nI   test2.c~\n")
507
548
 
508
549
    def test_status_write_lock(self):
509
550
        """Test that status works without fetching history and
515
556
        wt = self.make_branch_and_tree('branch1')
516
557
        b = wt.branch
517
558
        wt.commit('Empty commit 1')
518
 
        wt2 = b.bzrdir.sprout('branch2').open_workingtree()
 
559
        wt2 = b.controldir.sprout('branch2').open_workingtree()
519
560
        wt2.commit('Empty commit 2')
520
561
        out, err = self.run_bzr('status branch1 -rbranch:branch2')
521
562
        self.assertEqual('', out)
522
563
 
 
564
    def test_status_with_shelves(self):
 
565
        """Ensure that _show_shelve_summary handler works.
 
566
        """
 
567
        wt = self.make_branch_and_tree('.')
 
568
        self.build_tree(['hello.c'])
 
569
        wt.add('hello.c')
 
570
        self.run_bzr(['shelve', '--all', '-m', 'foo'])
 
571
        self.build_tree(['bye.c'])
 
572
        wt.add('bye.c')
 
573
        self.assertStatus([
 
574
            'added:\n',
 
575
            '  bye.c\n',
 
576
            '1 shelf exists. See "brz shelve --list" for details.\n',
 
577
            ],
 
578
            wt)
 
579
        self.run_bzr(['shelve', '--all', '-m', 'bar'])
 
580
        self.build_tree(['eggs.c', 'spam.c'])
 
581
        wt.add('eggs.c')
 
582
        wt.add('spam.c')
 
583
        self.assertStatus([
 
584
            'added:\n',
 
585
            '  eggs.c\n',
 
586
            '  spam.c\n',
 
587
            '2 shelves exist. See "brz shelve --list" for details.\n',
 
588
            ],
 
589
            wt)
 
590
        self.assertStatus([
 
591
            'added:\n',
 
592
            '  spam.c\n',
 
593
            ],
 
594
            wt,
 
595
            specific_files=['spam.c'])
 
596
 
523
597
 
524
598
class CheckoutStatus(BranchStatus):
525
599
 
531
605
    def make_branch_and_tree(self, relpath):
532
606
        source = self.make_branch(pathjoin('..', relpath))
533
607
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
534
 
        bzrlib.branch.BranchReferenceFormat().initialize(checkout,
535
 
            target_branch=source)
 
608
        checkout.set_branch_reference(source)
536
609
        return checkout.create_workingtree()
537
610
 
538
611
 
558
631
 
559
632
        self.build_tree(['world.txt'])
560
633
        result = self.run_bzr("status -r 0")[0]
561
 
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
 
634
        self.assertContainsRe(result, "added:\n  hello.txt\n"
562
635
                                      "unknown:\n  world.txt\n")
563
636
        result2 = self.run_bzr("status -r 0..")[0]
564
 
        self.assertEquals(result2, result)
 
637
        self.assertEqual(result2, result)
565
638
 
566
639
    def test_status_short(self):
567
640
        tree = self.make_branch_and_tree('.')
579
652
        self.assertContainsRe(result, "[+]N  hello.txt\n")
580
653
 
581
654
        self.build_tree(['world.txt'])
582
 
        result = self.run_bzr("status --short -r 0")[0]
583
 
        self.assertContainsRe(result, "[+]N  hello.txt\n" \
 
655
        result = self.run_bzr("status -S -r 0")[0]
 
656
        self.assertContainsRe(result, "[+]N  hello.txt\n"
584
657
                                      "[?]   world.txt\n")
585
 
        result2 = self.run_bzr("status --short -r 0..")[0]
586
 
        self.assertEquals(result2, result)
 
658
        result2 = self.run_bzr("status -S -r 0..")[0]
 
659
        self.assertEqual(result2, result)
587
660
 
588
661
    def test_status_versioned(self):
589
662
        tree = self.make_branch_and_tree('.')
605
678
        self.assertContainsRe(result, "added:\n  hello.txt\n")
606
679
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
607
680
        result2 = self.run_bzr("status --versioned -r 0..")[0]
608
 
        self.assertEquals(result2, result)
 
681
        self.assertEqual(result2, result)
609
682
 
610
683
    def test_status_SV(self):
611
684
        tree = self.make_branch_and_tree('.')
627
700
        self.assertContainsRe(result, "[+]N  hello.txt\n")
628
701
 
629
702
        result2 = self.run_bzr("status -SV -r 0..")[0]
630
 
        self.assertEquals(result2, result)
 
703
        self.assertEqual(result2, result)
631
704
 
632
705
    def assertStatusContains(self, pattern, short=False):
633
706
        """Run status, and assert it contains the given pattern"""
644
717
        tree.commit('added file')
645
718
        unlink('file')
646
719
        self.build_tree(['file/'])
647
 
        self.assertStatusContains('kind changed:\n  file \(file => directory\)')
 
720
        self.assertStatusContains(
 
721
            'kind changed:\n  file \\(file => directory\\)')
648
722
        tree.rename_one('file', 'directory')
649
 
        self.assertStatusContains('renamed:\n  file/ => directory/\n' \
 
723
        self.assertStatusContains('renamed:\n  file/ => directory/\n'
650
724
                                  'modified:\n  directory/\n')
651
725
        rmdir('directory')
652
726
        self.assertStatusContains('removed:\n  file\n')
659
733
        unlink('file')
660
734
        self.build_tree(['file/'])
661
735
        self.assertStatusContains('K  file => file/',
662
 
                                   short=True)
 
736
                                  short=True)
663
737
        tree.rename_one('file', 'directory')
664
738
        self.assertStatusContains('RK  file => directory/',
665
 
                                   short=True)
 
739
                                  short=True)
666
740
        rmdir('directory')
667
741
        self.assertStatusContains('RD  file => directory',
668
 
                                   short=True)
 
742
                                  short=True)
669
743
 
670
744
    def test_status_illegal_revision_specifiers(self):
671
745
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
676
750
        self.build_tree(['a/a'])
677
751
        a_tree.add('a')
678
752
        a_tree.commit('a')
679
 
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
753
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
680
754
        self.build_tree(['b/b'])
681
755
        b_tree.add('b')
682
756
        b_tree.commit('b')
683
757
 
684
758
        self.run_bzr('merge ../b', working_dir='a')
685
759
        out, err = self.run_bzr('status --no-pending', working_dir='a')
686
 
        self.assertEquals(out, "added:\n  b\n")
 
760
        self.assertEqual(out, "added:\n  b\n")
687
761
 
688
762
    def test_pending_specific_files(self):
689
763
        """With a specific file list, pending merges are not shown."""
690
764
        tree = self.make_branch_and_tree('tree')
691
 
        self.build_tree_contents([('tree/a', 'content of a\n')])
 
765
        self.build_tree_contents([('tree/a', b'content of a\n')])
692
766
        tree.add('a')
693
767
        r1_id = tree.commit('one')
694
 
        alt = tree.bzrdir.sprout('alt').open_workingtree()
695
 
        self.build_tree_contents([('alt/a', 'content of a\nfrom alt\n')])
 
768
        alt = tree.controldir.sprout('alt').open_workingtree()
 
769
        self.build_tree_contents([('alt/a', b'content of a\nfrom alt\n')])
696
770
        alt_id = alt.commit('alt')
697
771
        tree.merge_from_branch(alt.branch)
698
772
        output = self.make_utf8_encoded_stringio()
699
773
        show_tree_status(tree, to_file=output)
700
 
        self.assertContainsRe(output.getvalue(), 'pending merge')
 
774
        self.assertContainsRe(output.getvalue(), b'pending merge')
701
775
        out, err = self.run_bzr('status tree/a')
702
776
        self.assertNotContainsRe(out, 'pending merge')
703
777
 
704
778
 
705
779
class TestStatusEncodings(TestCaseWithTransport):
706
780
 
707
 
    def setUp(self):
708
 
        TestCaseWithTransport.setUp(self)
709
 
        self.user_encoding = osutils._cached_user_encoding
710
 
        self.stdout = sys.stdout
711
 
 
712
 
    def tearDown(self):
713
 
        osutils._cached_user_encoding = self.user_encoding
714
 
        sys.stdout = self.stdout
715
 
        TestCaseWithTransport.tearDown(self)
716
 
 
717
781
    def make_uncommitted_tree(self):
718
782
        """Build a branch with uncommitted unicode named changes in the cwd."""
719
783
        working_tree = self.make_branch_and_tree(u'.')
720
784
        filename = u'hell\u00d8'
721
785
        try:
722
 
            self.build_tree_contents([(filename, 'contents of hello')])
 
786
            self.build_tree_contents([(filename, b'contents of hello')])
723
787
        except UnicodeEncodeError:
724
788
            raise TestSkipped("can't build unicode working tree in "
725
 
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
789
                              "filesystem encoding %s" % sys.getfilesystemencoding())
726
790
        working_tree.add(filename)
727
791
        return working_tree
728
792
 
729
793
    def test_stdout_ascii(self):
730
 
        sys.stdout = StringIO()
731
 
        osutils._cached_user_encoding = 'ascii'
 
794
        self.overrideAttr(osutils, '_cached_user_encoding', 'ascii')
732
795
        working_tree = self.make_uncommitted_tree()
733
796
        stdout, stderr = self.run_bzr("status")
734
797
 
735
 
        self.assertEquals(stdout, """\
 
798
        self.assertEqual(stdout, """\
736
799
added:
737
800
  hell?
738
801
""")
739
802
 
740
803
    def test_stdout_latin1(self):
741
 
        sys.stdout = StringIO()
742
 
        osutils._cached_user_encoding = 'latin-1'
 
804
        self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1')
743
805
        working_tree = self.make_uncommitted_tree()
744
806
        stdout, stderr = self.run_bzr('status')
745
807
 
746
 
        self.assertEquals(stdout, u"""\
 
808
        expected = u"""\
747
809
added:
748
810
  hell\u00d8
749
 
""".encode('latin-1'))
750
 
 
 
811
"""
 
812
        if not PY3:
 
813
            expected = expected.encode('latin-1')
 
814
        self.assertEqual(stdout, expected)