/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: 2020-04-05 19:11:34 UTC
  • mto: (7490.7.16 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200405191134-0aebh8ikiwygxma5
Populate the .gitignore file.

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')])
462
 
        tree.lock_write()
463
 
        try:
 
499
        self.build_tree_contents([('a', b'foo\n')])
 
500
        with tree.lock_write():
464
501
            tree.add(['a'])
465
502
            tree.commit('add test file')
466
503
            # simulate what happens after a remote push
467
 
            tree.set_last_revision("0")
468
 
        finally:
469
 
            # before run another commands we should unlock tree
470
 
            tree.unlock()
 
504
            tree.set_last_revision(b"0")
471
505
        out, err = self.run_bzr('status')
472
 
        self.assertEqual("working tree is out of date, run 'bzr update'\n",
 
506
        self.assertEqual("working tree is out of date, run 'brz update'\n",
473
507
                         err)
474
508
 
475
509
    def test_status_on_ignored(self):
483
517
        result = self.run_bzr('status')[0]
484
518
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
485
519
        short_result = self.run_bzr('status --short')[0]
486
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
520
        self.assertContainsRe(short_result, "\\?   test1.c\n")
487
521
 
488
522
        result = self.run_bzr('status test1.c')[0]
489
523
        self.assertContainsRe(result, "unknown:\n  test1.c\n")
490
524
        short_result = self.run_bzr('status --short test1.c')[0]
491
 
        self.assertContainsRe(short_result, "\?   test1.c\n")
 
525
        self.assertContainsRe(short_result, "\\?   test1.c\n")
492
526
 
493
527
        result = self.run_bzr('status test1.c~')[0]
494
528
        self.assertContainsRe(result, "ignored:\n  test1.c~\n")
501
535
        self.assertContainsRe(short_result, "I   test1.c~\nI   test2.c~\n")
502
536
 
503
537
        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")
 
538
        self.assertContainsRe(
 
539
            result, "unknown:\n  test1.c\nignored:\n  test1.c~\n  test2.c~\n")
 
540
        short_result = self.run_bzr(
 
541
            'status --short test1.c test1.c~ test2.c~')[0]
 
542
        self.assertContainsRe(
 
543
            short_result, "\\?   test1.c\nI   test1.c~\nI   test2.c~\n")
507
544
 
508
545
    def test_status_write_lock(self):
509
546
        """Test that status works without fetching history and
515
552
        wt = self.make_branch_and_tree('branch1')
516
553
        b = wt.branch
517
554
        wt.commit('Empty commit 1')
518
 
        wt2 = b.bzrdir.sprout('branch2').open_workingtree()
 
555
        wt2 = b.controldir.sprout('branch2').open_workingtree()
519
556
        wt2.commit('Empty commit 2')
520
557
        out, err = self.run_bzr('status branch1 -rbranch:branch2')
521
558
        self.assertEqual('', out)
522
559
 
 
560
    def test_status_with_shelves(self):
 
561
        """Ensure that _show_shelve_summary handler works.
 
562
        """
 
563
        wt = self.make_branch_and_tree('.')
 
564
        self.build_tree(['hello.c'])
 
565
        wt.add('hello.c')
 
566
        self.run_bzr(['shelve', '--all', '-m', 'foo'])
 
567
        self.build_tree(['bye.c'])
 
568
        wt.add('bye.c')
 
569
        self.assertStatus([
 
570
            'added:\n',
 
571
            '  bye.c\n',
 
572
            '1 shelf exists. See "brz shelve --list" for details.\n',
 
573
            ],
 
574
            wt)
 
575
        self.run_bzr(['shelve', '--all', '-m', 'bar'])
 
576
        self.build_tree(['eggs.c', 'spam.c'])
 
577
        wt.add('eggs.c')
 
578
        wt.add('spam.c')
 
579
        self.assertStatus([
 
580
            'added:\n',
 
581
            '  eggs.c\n',
 
582
            '  spam.c\n',
 
583
            '2 shelves exist. See "brz shelve --list" for details.\n',
 
584
            ],
 
585
            wt)
 
586
        self.assertStatus([
 
587
            'added:\n',
 
588
            '  spam.c\n',
 
589
            ],
 
590
            wt,
 
591
            specific_files=['spam.c'])
 
592
 
523
593
 
524
594
class CheckoutStatus(BranchStatus):
525
595
 
531
601
    def make_branch_and_tree(self, relpath):
532
602
        source = self.make_branch(pathjoin('..', relpath))
533
603
        checkout = bzrdir.BzrDirMetaFormat1().initialize(relpath)
534
 
        bzrlib.branch.BranchReferenceFormat().initialize(checkout,
535
 
            target_branch=source)
 
604
        checkout.set_branch_reference(source)
536
605
        return checkout.create_workingtree()
537
606
 
538
607
 
558
627
 
559
628
        self.build_tree(['world.txt'])
560
629
        result = self.run_bzr("status -r 0")[0]
561
 
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
 
630
        self.assertContainsRe(result, "added:\n  hello.txt\n"
562
631
                                      "unknown:\n  world.txt\n")
563
632
        result2 = self.run_bzr("status -r 0..")[0]
564
 
        self.assertEquals(result2, result)
 
633
        self.assertEqual(result2, result)
565
634
 
566
635
    def test_status_short(self):
567
636
        tree = self.make_branch_and_tree('.')
579
648
        self.assertContainsRe(result, "[+]N  hello.txt\n")
580
649
 
581
650
        self.build_tree(['world.txt'])
582
 
        result = self.run_bzr("status --short -r 0")[0]
583
 
        self.assertContainsRe(result, "[+]N  hello.txt\n" \
 
651
        result = self.run_bzr("status -S -r 0")[0]
 
652
        self.assertContainsRe(result, "[+]N  hello.txt\n"
584
653
                                      "[?]   world.txt\n")
585
 
        result2 = self.run_bzr("status --short -r 0..")[0]
586
 
        self.assertEquals(result2, result)
 
654
        result2 = self.run_bzr("status -S -r 0..")[0]
 
655
        self.assertEqual(result2, result)
587
656
 
588
657
    def test_status_versioned(self):
589
658
        tree = self.make_branch_and_tree('.')
605
674
        self.assertContainsRe(result, "added:\n  hello.txt\n")
606
675
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
607
676
        result2 = self.run_bzr("status --versioned -r 0..")[0]
608
 
        self.assertEquals(result2, result)
 
677
        self.assertEqual(result2, result)
609
678
 
610
679
    def test_status_SV(self):
611
680
        tree = self.make_branch_and_tree('.')
627
696
        self.assertContainsRe(result, "[+]N  hello.txt\n")
628
697
 
629
698
        result2 = self.run_bzr("status -SV -r 0..")[0]
630
 
        self.assertEquals(result2, result)
 
699
        self.assertEqual(result2, result)
631
700
 
632
701
    def assertStatusContains(self, pattern, short=False):
633
702
        """Run status, and assert it contains the given pattern"""
644
713
        tree.commit('added file')
645
714
        unlink('file')
646
715
        self.build_tree(['file/'])
647
 
        self.assertStatusContains('kind changed:\n  file \(file => directory\)')
 
716
        self.assertStatusContains(
 
717
            'kind changed:\n  file \\(file => directory\\)')
648
718
        tree.rename_one('file', 'directory')
649
 
        self.assertStatusContains('renamed:\n  file/ => directory/\n' \
 
719
        self.assertStatusContains('renamed:\n  file => directory/\n'
650
720
                                  'modified:\n  directory/\n')
651
721
        rmdir('directory')
652
722
        self.assertStatusContains('removed:\n  file\n')
659
729
        unlink('file')
660
730
        self.build_tree(['file/'])
661
731
        self.assertStatusContains('K  file => file/',
662
 
                                   short=True)
 
732
                                  short=True)
663
733
        tree.rename_one('file', 'directory')
664
734
        self.assertStatusContains('RK  file => directory/',
665
 
                                   short=True)
 
735
                                  short=True)
666
736
        rmdir('directory')
667
737
        self.assertStatusContains('RD  file => directory',
668
 
                                   short=True)
 
738
                                  short=True)
669
739
 
670
740
    def test_status_illegal_revision_specifiers(self):
671
741
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
676
746
        self.build_tree(['a/a'])
677
747
        a_tree.add('a')
678
748
        a_tree.commit('a')
679
 
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
749
        b_tree = a_tree.controldir.sprout('b').open_workingtree()
680
750
        self.build_tree(['b/b'])
681
751
        b_tree.add('b')
682
752
        b_tree.commit('b')
683
753
 
684
754
        self.run_bzr('merge ../b', working_dir='a')
685
755
        out, err = self.run_bzr('status --no-pending', working_dir='a')
686
 
        self.assertEquals(out, "added:\n  b\n")
 
756
        self.assertEqual(out, "added:\n  b\n")
687
757
 
688
758
    def test_pending_specific_files(self):
689
759
        """With a specific file list, pending merges are not shown."""
690
760
        tree = self.make_branch_and_tree('tree')
691
 
        self.build_tree_contents([('tree/a', 'content of a\n')])
 
761
        self.build_tree_contents([('tree/a', b'content of a\n')])
692
762
        tree.add('a')
693
763
        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')])
 
764
        alt = tree.controldir.sprout('alt').open_workingtree()
 
765
        self.build_tree_contents([('alt/a', b'content of a\nfrom alt\n')])
696
766
        alt_id = alt.commit('alt')
697
767
        tree.merge_from_branch(alt.branch)
698
768
        output = self.make_utf8_encoded_stringio()
699
769
        show_tree_status(tree, to_file=output)
700
 
        self.assertContainsRe(output.getvalue(), 'pending merge')
 
770
        self.assertContainsRe(output.getvalue(), b'pending merge')
701
771
        out, err = self.run_bzr('status tree/a')
702
772
        self.assertNotContainsRe(out, 'pending merge')
703
773
 
704
774
 
705
775
class TestStatusEncodings(TestCaseWithTransport):
706
776
 
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
777
    def make_uncommitted_tree(self):
718
778
        """Build a branch with uncommitted unicode named changes in the cwd."""
719
779
        working_tree = self.make_branch_and_tree(u'.')
720
780
        filename = u'hell\u00d8'
721
781
        try:
722
 
            self.build_tree_contents([(filename, 'contents of hello')])
 
782
            self.build_tree_contents([(filename, b'contents of hello')])
723
783
        except UnicodeEncodeError:
724
784
            raise TestSkipped("can't build unicode working tree in "
725
 
                "filesystem encoding %s" % sys.getfilesystemencoding())
 
785
                              "filesystem encoding %s" % sys.getfilesystemencoding())
726
786
        working_tree.add(filename)
727
787
        return working_tree
728
788
 
729
789
    def test_stdout_ascii(self):
730
 
        sys.stdout = StringIO()
731
 
        osutils._cached_user_encoding = 'ascii'
 
790
        self.overrideAttr(osutils, '_cached_user_encoding', 'ascii')
732
791
        working_tree = self.make_uncommitted_tree()
733
792
        stdout, stderr = self.run_bzr("status")
734
793
 
735
 
        self.assertEquals(stdout, """\
 
794
        self.assertEqual(stdout, """\
736
795
added:
737
796
  hell?
738
797
""")
739
798
 
740
799
    def test_stdout_latin1(self):
741
 
        sys.stdout = StringIO()
742
 
        osutils._cached_user_encoding = 'latin-1'
 
800
        self.overrideAttr(osutils, '_cached_user_encoding', 'latin-1')
743
801
        working_tree = self.make_uncommitted_tree()
744
802
        stdout, stderr = self.run_bzr('status')
745
803
 
746
 
        self.assertEquals(stdout, u"""\
 
804
        expected = u"""\
747
805
added:
748
806
  hell\u00d8
749
 
""".encode('latin-1'))
750
 
 
 
807
"""
 
808
        if not PY3:
 
809
            expected = expected.encode('latin-1')
 
810
        self.assertEqual(stdout, expected)