/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: 2008-08-20 02:07:36 UTC
  • mfrom: (3640 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3682.
  • Revision ID: robertc@robertcollins.net-20080820020736-g2xe4921zzxtymle
Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 by Canonical Ltd
2
 
 
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
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
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
7
 
 
 
7
#
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
# GNU General Public License for more details.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
24
 
25
25
from cStringIO import StringIO
26
26
import codecs
27
 
from os import mkdir, chdir
 
27
from os import mkdir, chdir, rmdir, unlink
28
28
import sys
29
29
from tempfile import TemporaryFile
30
30
 
 
31
from bzrlib import (
 
32
    bzrdir,
 
33
    conflicts,
 
34
    errors,
 
35
    )
31
36
import bzrlib.branch
32
 
from bzrlib.builtins import merge
33
 
import bzrlib.bzrdir as bzrdir
34
 
import bzrlib.errors as errors
35
37
from bzrlib.osutils import pathjoin
36
38
from bzrlib.revisionspec import RevisionSpec
37
39
from bzrlib.status import show_tree_status
41
43
 
42
44
class BranchStatus(TestCaseWithTransport):
43
45
    
44
 
    def test_branch_status(self): 
 
46
    def assertStatus(self, expected_lines, working_tree,
 
47
        revision=None, short=False, pending=True):
 
48
        """Run status in working_tree and look for output.
 
49
        
 
50
        :param expected_lines: The lines to look for.
 
51
        :param working_tree: The tree to run status in.
 
52
        """
 
53
        output_string = self.status_string(working_tree, revision, short,
 
54
                pending)
 
55
        self.assertEqual(expected_lines, output_string.splitlines(True))
 
56
    
 
57
    def status_string(self, wt, revision=None, short=False, pending=True):
 
58
        # use a real file rather than StringIO because it doesn't handle
 
59
        # Unicode very well.
 
60
        tof = codecs.getwriter('utf-8')(TemporaryFile())
 
61
        show_tree_status(wt, to_file=tof, revision=revision, short=short,
 
62
                show_pending=pending)
 
63
        tof.seek(0)
 
64
        return tof.read().decode('utf-8')
 
65
 
 
66
    def test_branch_status(self):
45
67
        """Test basic branch status"""
46
68
        wt = self.make_branch_and_tree('.')
47
 
        b = wt.branch
48
 
 
49
 
        # status with nothing
50
 
        tof = StringIO()
51
 
        show_tree_status(wt, to_file=tof)
52
 
        self.assertEquals(tof.getvalue(), "")
53
 
 
54
 
        tof = StringIO()
 
69
 
 
70
        # status with no commits or files - it must
 
71
        # work and show no output. We do this with no
 
72
        # commits to be sure that it's not going to fail
 
73
        # as a corner case.
 
74
        self.assertStatus([], wt)
 
75
 
55
76
        self.build_tree(['hello.c', 'bye.c'])
56
 
        wt.add_pending_merge('pending@pending-0-0')
57
 
        show_tree_status(wt, to_file=tof)
58
 
        tof.seek(0)
59
 
        self.assertEquals(tof.readlines(),
60
 
                          ['unknown:\n',
61
 
                           '  bye.c\n',
62
 
                           '  hello.c\n',
63
 
                           'pending merges:\n',
64
 
                           '  pending@pending-0-0\n'
65
 
                           ])
 
77
        self.assertStatus([
 
78
                'unknown:\n',
 
79
                '  bye.c\n',
 
80
                '  hello.c\n',
 
81
            ],
 
82
            wt)
 
83
        self.assertStatus([
 
84
                '?   bye.c\n',
 
85
                '?   hello.c\n',
 
86
            ],
 
87
            wt, short=True)
 
88
 
 
89
        # add a commit to allow showing pending merges.
 
90
        wt.commit('create a parent to allow testing merge output')
 
91
 
 
92
        wt.add_parent_tree_id('pending@pending-0-0')
 
93
        self.assertStatus([
 
94
                'unknown:\n',
 
95
                '  bye.c\n',
 
96
                '  hello.c\n',
 
97
                'pending merges:\n',
 
98
                '  (ghost) pending@pending-0-0\n',
 
99
            ],
 
100
            wt)
 
101
        self.assertStatus([
 
102
                '?   bye.c\n',
 
103
                '?   hello.c\n',
 
104
                'P   (ghost) pending@pending-0-0\n',
 
105
            ],
 
106
            wt, short=True)
 
107
        self.assertStatus([
 
108
                'unknown:\n',
 
109
                '  bye.c\n',
 
110
                '  hello.c\n',
 
111
            ],
 
112
            wt, pending=False)
 
113
        self.assertStatus([
 
114
                '?   bye.c\n',
 
115
                '?   hello.c\n',
 
116
            ],
 
117
            wt, short=True, pending=False)
66
118
 
67
119
    def test_branch_status_revisions(self):
68
120
        """Tests branch status with revisions"""
69
121
        wt = self.make_branch_and_tree('.')
70
 
        b = wt.branch
71
122
 
72
 
        tof = StringIO()
73
123
        self.build_tree(['hello.c', 'bye.c'])
74
124
        wt.add('hello.c')
75
125
        wt.add('bye.c')
76
126
        wt.commit('Test message')
77
127
 
78
 
        tof = StringIO()
79
 
        revs =[]
80
 
        revs.append(RevisionSpec(0))
81
 
        
82
 
        show_tree_status(wt, to_file=tof, revision=revs)
83
 
        
84
 
        tof.seek(0)
85
 
        self.assertEquals(tof.readlines(),
86
 
                          ['added:\n',
87
 
                           '  bye.c\n',
88
 
                           '  hello.c\n'])
 
128
        revs = [RevisionSpec.from_string('0')]
 
129
        self.assertStatus([
 
130
                'added:\n',
 
131
                '  bye.c\n',
 
132
                '  hello.c\n'
 
133
            ],
 
134
            wt,
 
135
            revision=revs)
89
136
 
90
137
        self.build_tree(['more.c'])
91
138
        wt.add('more.c')
92
139
        wt.commit('Another test message')
93
140
        
94
 
        tof = StringIO()
95
 
        revs.append(RevisionSpec(1))
96
 
        
97
 
        show_tree_status(wt, to_file=tof, revision=revs)
98
 
        
99
 
        tof.seek(0)
100
 
        self.assertEquals(tof.readlines(),
101
 
                          ['added:\n',
102
 
                           '  bye.c\n',
103
 
                           '  hello.c\n'])
104
 
 
105
 
    def status_string(self, wt):
106
 
        # use a real file rather than StringIO because it doesn't handle
107
 
        # Unicode very well.
108
 
        tof = codecs.getwriter('utf-8')(TemporaryFile())
109
 
        show_tree_status(wt, to_file=tof)
110
 
        tof.seek(0)
111
 
        return tof.read().decode('utf-8')
 
141
        revs.append(RevisionSpec.from_string('1'))
 
142
        self.assertStatus([
 
143
                'added:\n',
 
144
                '  bye.c\n',
 
145
                '  hello.c\n',
 
146
            ],
 
147
            wt,
 
148
            revision=revs)
112
149
 
113
150
    def test_pending(self):
114
151
        """Pending merges display works, including Unicode"""
120
157
        b_2 = b_2_dir.open_branch()
121
158
        wt2 = b_2_dir.open_workingtree()
122
159
        wt.commit(u"\N{TIBETAN DIGIT TWO} Empty commit 2")
123
 
        merge(["./branch", -1], [None, None], this_dir = './copy')
 
160
        wt2.merge_from_branch(wt.branch)
124
161
        message = self.status_string(wt2)
125
 
        self.assert_(message.startswith("pending merges:\n"))
126
 
        self.assert_(message.endswith("Empty commit 2\n")) 
 
162
        self.assertStartsWith(message, "pending merges:\n")
 
163
        self.assertEndsWith(message, "Empty commit 2\n")
127
164
        wt2.commit("merged")
128
165
        # must be long to make sure we see elipsis at the end
129
 
        wt.commit("Empty commit 3 " + 
130
 
                   "blah blah blah blah " * 10)
131
 
        merge(["./branch", -1], [None, None], this_dir = './copy')
 
166
        wt.commit("Empty commit 3 " +
 
167
                   "blah blah blah blah " * 100)
 
168
        wt2.merge_from_branch(wt.branch)
132
169
        message = self.status_string(wt2)
133
 
        self.assert_(message.startswith("pending merges:\n"))
 
170
        self.assertStartsWith(message, "pending merges:\n")
134
171
        self.assert_("Empty commit 3" in message)
135
 
        self.assert_(message.endswith("...\n")) 
136
 
 
137
 
    def test_branch_status_specific_files(self): 
 
172
        self.assertEndsWith(message, "...\n")
 
173
 
 
174
    def test_tree_status_ignores(self):
 
175
        """Tests branch status with ignores"""
 
176
        wt = self.make_branch_and_tree('.')
 
177
        self.run_bzr('ignore *~')
 
178
        wt.commit('commit .bzrignore')
 
179
        self.build_tree(['foo.c', 'foo.c~'])
 
180
        self.assertStatus([
 
181
                'unknown:\n',
 
182
                '  foo.c\n',
 
183
                ],
 
184
                wt)
 
185
        self.assertStatus([
 
186
                '?   foo.c\n',
 
187
                ],
 
188
                wt, short=True)
 
189
 
 
190
    def test_tree_status_specific_files(self):
138
191
        """Tests branch status with given specific files"""
139
192
        wt = self.make_branch_and_tree('.')
140
193
        b = wt.branch
144
197
        wt.add('test.c')
145
198
        wt.commit('testing')
146
199
        
 
200
        self.assertStatus([
 
201
                'unknown:\n',
 
202
                '  bye.c\n',
 
203
                '  dir2/\n',
 
204
                '  directory/hello.c\n'
 
205
                ],
 
206
                wt)
 
207
 
 
208
        self.assertStatus([
 
209
                '?   bye.c\n',
 
210
                '?   dir2/\n',
 
211
                '?   directory/hello.c\n'
 
212
                ],
 
213
                wt, short=True)
 
214
 
147
215
        tof = StringIO()
148
 
        show_tree_status(wt, to_file=tof)
149
 
        tof.seek(0)
150
 
        self.assertEquals(tof.readlines(),
151
 
                          ['unknown:\n',
152
 
                           '  bye.c\n',
153
 
                           '  dir2\n',
154
 
                           '  directory/hello.c\n'
155
 
                           ])
156
 
 
157
216
        self.assertRaises(errors.PathsDoNotExist,
158
217
                          show_tree_status,
159
218
                          wt, specific_files=['bye.c','test.c','absent.c'], 
167
226
                           '  directory/hello.c\n'
168
227
                           ])
169
228
        tof = StringIO()
 
229
        show_tree_status(wt, specific_files=['directory'], to_file=tof,
 
230
                         short=True)
 
231
        tof.seek(0)
 
232
        self.assertEquals(tof.readlines(), ['?   directory/hello.c\n'])
 
233
 
 
234
        tof = StringIO()
170
235
        show_tree_status(wt, specific_files=['dir2'], to_file=tof)
171
236
        tof.seek(0)
172
237
        self.assertEquals(tof.readlines(),
173
238
                          ['unknown:\n',
174
 
                           '  dir2\n'
 
239
                           '  dir2/\n'
175
240
                           ])
 
241
        tof = StringIO()
 
242
        show_tree_status(wt, specific_files=['dir2'], to_file=tof, short=True)
 
243
        tof.seek(0)
 
244
        self.assertEquals(tof.readlines(), ['?   dir2/\n'])
 
245
 
 
246
        tof = StringIO()
 
247
        revs = [RevisionSpec.from_string('0'), RevisionSpec.from_string('1')]
 
248
        show_tree_status(wt, specific_files=['test.c'], to_file=tof,
 
249
                         short=True, revision=revs)
 
250
        tof.seek(0)
 
251
        self.assertEquals(tof.readlines(), ['+N  test.c\n'])
 
252
 
 
253
    def test_specific_files_conflicts(self):
 
254
        tree = self.make_branch_and_tree('.')
 
255
        self.build_tree(['dir2/'])
 
256
        tree.add('dir2')
 
257
        tree.commit('added dir2')
 
258
        tree.set_conflicts(conflicts.ConflictList(
 
259
            [conflicts.ContentsConflict('foo')]))
 
260
        tof = StringIO()
 
261
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
 
262
        self.assertEqualDiff('', tof.getvalue())
 
263
        tree.set_conflicts(conflicts.ConflictList(
 
264
            [conflicts.ContentsConflict('dir2')]))
 
265
        tof = StringIO()
 
266
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
 
267
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2\n',
 
268
                             tof.getvalue())
 
269
 
 
270
        tree.set_conflicts(conflicts.ConflictList(
 
271
            [conflicts.ContentsConflict('dir2/file1')]))
 
272
        tof = StringIO()
 
273
        show_tree_status(tree, specific_files=['dir2'], to_file=tof)
 
274
        self.assertEqualDiff('conflicts:\n  Contents conflict in dir2/file1\n',
 
275
                             tof.getvalue())
176
276
 
177
277
    def test_status_nonexistent_file(self):
178
278
        # files that don't exist in either the basis tree or working tree
179
279
        # should give an error
180
280
        wt = self.make_branch_and_tree('.')
181
 
        out, err = self.run_bzr('status', 'does-not-exist', retcode=3)
 
281
        out, err = self.run_bzr('status does-not-exist', retcode=3)
182
282
        self.assertContainsRe(err, r'do not exist.*does-not-exist')
183
283
 
 
284
    def test_status_out_of_date(self):
 
285
        """Simulate status of out-of-date tree after remote push"""
 
286
        tree = self.make_branch_and_tree('.')
 
287
        self.build_tree_contents([('a', 'foo\n')])
 
288
        tree.lock_write()
 
289
        try:
 
290
            tree.add(['a'])
 
291
            tree.commit('add test file')
 
292
            # simulate what happens after a remote push
 
293
            tree.set_last_revision("0")
 
294
        finally:
 
295
            # before run another commands we should unlock tree
 
296
            tree.unlock()
 
297
        out, err = self.run_bzr('status')
 
298
        self.assertEqual("working tree is out of date, run 'bzr update'\n",
 
299
                         err)
 
300
 
184
301
 
185
302
class CheckoutStatus(BranchStatus):
186
303
 
198
315
 
199
316
class TestStatus(TestCaseWithTransport):
200
317
 
201
 
    def test_status(self):
202
 
        self.run_bzr("init")
203
 
        self.build_tree(['hello.txt'])
204
 
        result = self.run_bzr("status")[0]
205
 
        self.assert_("unknown:\n  hello.txt\n" in result, result)
206
 
        self.run_bzr("add", "hello.txt")
207
 
        result = self.run_bzr("status")[0]
208
 
        self.assert_("added:\n  hello.txt\n" in result, result)
209
 
        self.run_bzr("commit", "-m", "added")
210
 
        result = self.run_bzr("status", "-r", "0..1")[0]
211
 
        self.assert_("added:\n  hello.txt\n" in result, result)
212
 
        self.build_tree(['world.txt'])
213
 
        result = self.run_bzr("status", "-r", "0")[0]
214
 
        self.assert_("added:\n  hello.txt\n" \
215
 
                     "unknown:\n  world.txt\n" in result, result)
216
 
 
217
 
        result2 = self.run_bzr("status", "-r", "0..")[0]
218
 
        self.assertEquals(result2, result)
 
318
    def test_status_plain(self):
 
319
        tree = self.make_branch_and_tree('.')
 
320
 
 
321
        self.build_tree(['hello.txt'])
 
322
        result = self.run_bzr("status")[0]
 
323
        self.assertContainsRe(result, "unknown:\n  hello.txt\n")
 
324
 
 
325
        tree.add("hello.txt")
 
326
        result = self.run_bzr("status")[0]
 
327
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
328
 
 
329
        tree.commit(message="added")
 
330
        result = self.run_bzr("status -r 0..1")[0]
 
331
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
332
 
 
333
        result = self.run_bzr("status -c 1")[0]
 
334
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
335
 
 
336
        self.build_tree(['world.txt'])
 
337
        result = self.run_bzr("status -r 0")[0]
 
338
        self.assertContainsRe(result, "added:\n  hello.txt\n" \
 
339
                                      "unknown:\n  world.txt\n")
 
340
        result2 = self.run_bzr("status -r 0..")[0]
 
341
        self.assertEquals(result2, result)
 
342
 
 
343
    def test_status_short(self):
 
344
        tree = self.make_branch_and_tree('.')
 
345
 
 
346
        self.build_tree(['hello.txt'])
 
347
        result = self.run_bzr("status --short")[0]
 
348
        self.assertContainsRe(result, "[?]   hello.txt\n")
 
349
 
 
350
        tree.add("hello.txt")
 
351
        result = self.run_bzr("status --short")[0]
 
352
        self.assertContainsRe(result, "[+]N  hello.txt\n")
 
353
 
 
354
        tree.commit(message="added")
 
355
        result = self.run_bzr("status --short -r 0..1")[0]
 
356
        self.assertContainsRe(result, "[+]N  hello.txt\n")
 
357
 
 
358
        self.build_tree(['world.txt'])
 
359
        result = self.run_bzr("status --short -r 0")[0]
 
360
        self.assertContainsRe(result, "[+]N  hello.txt\n" \
 
361
                                      "[?]   world.txt\n")
 
362
        result2 = self.run_bzr("status --short -r 0..")[0]
 
363
        self.assertEquals(result2, result)
 
364
 
 
365
    def test_status_versioned(self):
 
366
        tree = self.make_branch_and_tree('.')
 
367
 
 
368
        self.build_tree(['hello.txt'])
 
369
        result = self.run_bzr("status --versioned")[0]
 
370
        self.assertNotContainsRe(result, "unknown:\n  hello.txt\n")
 
371
 
 
372
        tree.add("hello.txt")
 
373
        result = self.run_bzr("status --versioned")[0]
 
374
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
375
 
 
376
        tree.commit("added")
 
377
        result = self.run_bzr("status --versioned -r 0..1")[0]
 
378
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
379
 
 
380
        self.build_tree(['world.txt'])
 
381
        result = self.run_bzr("status --versioned -r 0")[0]
 
382
        self.assertContainsRe(result, "added:\n  hello.txt\n")
 
383
        self.assertNotContainsRe(result, "unknown:\n  world.txt\n")
 
384
        result2 = self.run_bzr("status --versioned -r 0..")[0]
 
385
        self.assertEquals(result2, result)
 
386
 
 
387
    def test_status_SV(self):
 
388
        tree = self.make_branch_and_tree('.')
 
389
 
 
390
        self.build_tree(['hello.txt'])
 
391
        result = self.run_bzr("status -SV")[0]
 
392
        self.assertNotContainsRe(result, "hello.txt")
 
393
 
 
394
        tree.add("hello.txt")
 
395
        result = self.run_bzr("status -SV")[0]
 
396
        self.assertContainsRe(result, "[+]N  hello.txt\n")
 
397
 
 
398
        tree.commit(message="added")
 
399
        result = self.run_bzr("status -SV -r 0..1")[0]
 
400
        self.assertContainsRe(result, "[+]N  hello.txt\n")
 
401
 
 
402
        self.build_tree(['world.txt'])
 
403
        result = self.run_bzr("status -SV -r 0")[0]
 
404
        self.assertContainsRe(result, "[+]N  hello.txt\n")
 
405
 
 
406
        result2 = self.run_bzr("status -SV -r 0..")[0]
 
407
        self.assertEquals(result2, result)
 
408
 
 
409
    def assertStatusContains(self, pattern):
 
410
        """Run status, and assert it contains the given pattern"""
 
411
        result = self.run_bzr("status --short")[0]
 
412
        self.assertContainsRe(result, pattern)
 
413
 
 
414
    def test_kind_change_short(self):
 
415
        tree = self.make_branch_and_tree('.')
 
416
        self.build_tree(['file'])
 
417
        tree.add('file')
 
418
        tree.commit('added file')
 
419
        unlink('file')
 
420
        self.build_tree(['file/'])
 
421
        self.assertStatusContains('K  file => file/')
 
422
        tree.rename_one('file', 'directory')
 
423
        self.assertStatusContains('RK  file => directory/')
 
424
        rmdir('directory')
 
425
        self.assertStatusContains('RD  file => directory')
 
426
 
 
427
    def test_status_illegal_revision_specifiers(self):
 
428
        out, err = self.run_bzr('status -r 1..23..123', retcode=3)
 
429
        self.assertContainsRe(err, 'one or two revision specifiers')
 
430
 
 
431
    def test_status_no_pending(self):
 
432
        a_tree = self.make_branch_and_tree('a')
 
433
        self.build_tree(['a/a'])
 
434
        a_tree.add('a')
 
435
        a_tree.commit('a')
 
436
        b_tree = a_tree.bzrdir.sprout('b').open_workingtree()
 
437
        self.build_tree(['b/b'])
 
438
        b_tree.add('b')
 
439
        b_tree.commit('b')
 
440
 
 
441
        self.run_bzr('merge ../b', working_dir='a')
 
442
        out, err = self.run_bzr('status --no-pending', working_dir='a')
 
443
        self.assertEquals(out, "added:\n  b\n")
 
444
 
 
445
    def test_pending_specific_files(self):
 
446
        """With a specific file list, pending merges are not shown."""
 
447
        tree = self.make_branch_and_tree('tree')
 
448
        self.build_tree_contents([('tree/a', 'content of a\n')])
 
449
        tree.add('a')
 
450
        r1_id = tree.commit('one')
 
451
        alt = tree.bzrdir.sprout('alt').open_workingtree()
 
452
        self.build_tree_contents([('alt/a', 'content of a\nfrom alt\n')])
 
453
        alt_id = alt.commit('alt')
 
454
        tree.merge_from_branch(alt.branch)
 
455
        output = StringIO()
 
456
        show_tree_status(tree, to_file=output)
 
457
        self.assertContainsRe(output.getvalue(), 'pending merges:')
 
458
        out, err = self.run_bzr('status tree/a')
 
459
        self.assertNotContainsRe(out, 'pending merges:')
219
460
 
220
461
 
221
462
class TestStatusEncodings(TestCaseWithTransport):