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

  • Committer: Robert Collins
  • Date: 2007-04-19 02:27:44 UTC
  • mto: This revision was merged to the branch mainline in revision 2426.
  • Revision ID: robertc@robertcollins.net-20070419022744-pfdqz42kp1wizh43
``make docs`` now creates a man page at ``man1/bzr.1`` fixing bug 107388.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

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