Merge lp:~mbp/bzr/scripts into lp:bzr

Proposed by Martin Pool
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merged at revision: 5476
Proposed branch: lp:~mbp/bzr/scripts
Merge into: lp:bzr
Diff against target: 582 lines (+167/-86)
11 files modified
NEWS (+4/-0)
bzrlib/commands.py (+6/-1)
bzrlib/tests/__init__.py (+4/-0)
bzrlib/tests/blackbox/test_bound_branches.py (+3/-0)
bzrlib/tests/blackbox/test_dpush.py (+2/-0)
bzrlib/tests/blackbox/test_shelve.py (+8/-0)
bzrlib/tests/script.py (+18/-8)
bzrlib/tests/test_conflicts.py (+73/-73)
bzrlib/tests/test_delta.py (+1/-2)
bzrlib/tests/test_script.py (+42/-2)
doc/developers/testing.txt (+6/-0)
To merge this branch: bzr merge lp:~mbp/bzr/scripts
Reviewer Review Type Date Requested Status
John A Meinel Approve
Vincent Ladeuil Needs Fixing
Review via email: mp+35386@code.launchpad.net

Commit message

empty output in shell-like tests is no longer a wildcard

Description of the change

This changes the scriptrunner behaviour so that

"""
$ echo foo
"""

will fail, because it asserts echo doesn't produce output.

I think this is less confusing. If you want to allow for a command that might produce output but you don't care, you can say '...'. It's also more consistent with regular doctest.

This is going to put on a slight extra burden that you need to think about commands that may produce output, and if we change a command that is initially silent to produce output, we may need to update a bunch of tests. However I think this is much safer than not letting people check things actually are silent.

test_resolve is a bit messy, but I think it's actually better after the changes: more clear about which bits it actually is or isn't testing, and it points out the usefulness of -q when you don't want to see the output for a particular command.

To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

I agree, having the test writer think about -q and '...' sounds like a good plan.
The only drawback I could think of is that it will require a bit more expertise
than a mere copy/paste. No big loss here, I'm still waiting for bug reporters to
do that anyway :-D

127 - test_case.assertEqualDiff(expected, actual)
128 + test_case.assertEquals(expected, actual)

Why ??? EqualDiff provides valuable info, please don't remove that !

review: Needs Fixing
Revision history for this message
Martin Pool (mbp) wrote :

On 15 September 2010 03:29, Vincent Ladeuil <email address hidden> wrote:
> Review: Needs Fixing
> I agree, having the test writer think about -q and '...' sounds like a good plan.
> The only drawback I could think of is that it will require a bit more expertise
> than a mere copy/paste. No big loss here, I'm still waiting for bug reporters to
> do that anyway :-D
>
> 127     - test_case.assertEqualDiff(expected, actual)
> 128     + test_case.assertEquals(expected, actual)
>
> Why ??? EqualDiff provides valuable info, please don't remove that !

The diff is nicer to read, but it's less precise when there are
differences of whitespace etc, to the extent that I couldn't work out
what was going wrong. Perhaps I'll write a separate method that tries
to get the best of both, in a followon patch. For now I'll just
revert that.

--
Martin

Revision history for this message
Martin Pool (mbp) wrote :

sent to pqm by email

Revision history for this message
Martin Pool (mbp) wrote :

sent to pqm by email

Revision history for this message
Andrew Bennetts (spiv) wrote :

sent to pqm by email

Revision history for this message
John A Meinel (jameinel) wrote :

sent to pqm by email

Revision history for this message
John A Meinel (jameinel) wrote :

Manually updated to resolve NEWS and submitted to pqm via pqm-submit.

Revision history for this message
John A Meinel (jameinel) wrote :

The tests are failing, not just a NEWS conflict, so I'm bouncing this back to Martin.

Revision history for this message
Martin Pool (mbp) wrote :

The script failures are fixed by <https://code.edge.launchpad.net/~mbp/bzr/656694-verbosity/+merge/37933>. The problem was that if you set -q or -v in a script command, it was inherited by the whole process. Thanks spiv, vila!

Revision history for this message
John A Meinel (jameinel) wrote :

seems fine to me

review: Approve
Revision history for this message
Martin Pool (mbp) wrote :

sent to pqm by email

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2010-10-08 01:47:43 +0000
3+++ NEWS 2010-10-08 06:36:46 +0000
4@@ -504,6 +504,10 @@
5 Testing
6 *******
7
8+* Blank output section in scriptrunner tests no longer match any output.
9+ Instead, use '...' as a wildcard if you don't care about the output.
10+ (Martin Pool, #637830)
11+
12 * ``build_tree_contents`` can create symlinks.
13 (Martin Pool, John Arbash Meinel)
14
15
16=== modified file 'bzrlib/commands.py'
17--- bzrlib/commands.py 2010-08-13 07:56:06 +0000
18+++ bzrlib/commands.py 2010-10-08 06:36:46 +0000
19@@ -687,7 +687,12 @@
20
21 self._setup_outf()
22
23- return self.run(**all_cmd_args)
24+ try:
25+ return self.run(**all_cmd_args)
26+ finally:
27+ # reset it, so that other commands run in the same process won't
28+ # inherit state
29+ trace.set_verbosity_level(0)
30
31 def _setup_run(self):
32 """Wrap the defined run method on self with a cleanup.
33
34=== modified file 'bzrlib/tests/__init__.py'
35--- bzrlib/tests/__init__.py 2010-10-08 01:43:13 +0000
36+++ bzrlib/tests/__init__.py 2010-10-08 06:36:46 +0000
37@@ -858,6 +858,10 @@
38 self._track_transports()
39 self._track_locks()
40 self._clear_debug_flags()
41+ # Isolate global verbosity level, to make sure it's reproducible
42+ # between tests. We should get rid of this altogether: bug 656694. --
43+ # mbp 20101008
44+ self.overrideAttr(bzrlib.trace, '_verbosity_level', 0)
45
46 def debug(self):
47 # debug a frame up.
48
49=== modified file 'bzrlib/tests/blackbox/test_bound_branches.py'
50--- bzrlib/tests/blackbox/test_bound_branches.py 2010-05-02 20:10:25 +0000
51+++ bzrlib/tests/blackbox/test_bound_branches.py 2010-10-08 06:36:46 +0000
52@@ -443,7 +443,9 @@
53 def test_bind_when_bound(self):
54 self.run_script("""
55 $ bzr init trunk
56+...
57 $ bzr init copy
58+...
59 $ cd copy
60 $ bzr bind ../trunk
61 $ bzr bind
62@@ -453,6 +455,7 @@
63 def test_bind_before_bound(self):
64 self.run_script("""
65 $ bzr init trunk
66+...
67 $ cd trunk
68 $ bzr bind
69 2>bzr: ERROR: No location supplied and no previous location known
70
71=== modified file 'bzrlib/tests/blackbox/test_dpush.py'
72--- bzrlib/tests/blackbox/test_dpush.py 2010-06-23 08:19:28 +0000
73+++ bzrlib/tests/blackbox/test_dpush.py 2010-10-08 06:36:46 +0000
74@@ -104,6 +104,7 @@
75
76 script.run_script(self, '''
77 $ bzr dpush -d dc d
78+ 2>Pushed up to revision 2.
79 $ bzr revno dc
80 2
81 $ bzr status dc
82@@ -121,6 +122,7 @@
83 self.build_tree_contents([("dc/foofile", "blaaaal")])
84 script.run_script(self, '''
85 $ bzr dpush -d dc d --no-strict
86+ 2>Pushed up to revision 2.
87 ''')
88 self.assertFileEqual("blaaaal", "dc/foofile")
89 # if the dummy vcs wasn't that dummy we could uncomment the line below
90
91=== modified file 'bzrlib/tests/blackbox/test_shelve.py'
92--- bzrlib/tests/blackbox/test_shelve.py 2010-09-29 12:58:17 +0000
93+++ bzrlib/tests/blackbox/test_shelve.py 2010-10-08 06:36:46 +0000
94@@ -77,10 +77,18 @@
95 sr = ScriptRunner()
96 sr.run_script(self, '''
97 $ bzr add file
98+adding file
99 $ bzr shelve --all -m Foo
100+2>Selected changes:
101+2>-D file
102+2>Changes shelved with id "1".
103 $ bzr shelve --list
104 1: Foo
105 $ bzr unshelve --keep
106+2>Using changes with id "1".
107+2>Message: Foo
108+2>+N file
109+2>All changes applied successfully.
110 $ bzr shelve --list
111 1: Foo
112 $ cat file
113
114=== modified file 'bzrlib/tests/script.py'
115--- bzrlib/tests/script.py 2010-09-13 08:14:44 +0000
116+++ bzrlib/tests/script.py 2010-10-08 06:36:46 +0000
117@@ -221,20 +221,30 @@
118 retcode, actual_output, actual_error = method(test_case,
119 str_input, args)
120
121- self._check_output(output, actual_output, test_case)
122- self._check_output(error, actual_error, test_case)
123+ try:
124+ self._check_output(output, actual_output, test_case)
125+ except AssertionError, e:
126+ raise AssertionError(str(e) + " in stdout of command %s" % cmd)
127+ try:
128+ self._check_output(error, actual_error, test_case)
129+ except AssertionError, e:
130+ raise AssertionError(str(e) +
131+ " in stderr of running command %s" % cmd)
132 if retcode and not error and actual_error:
133 test_case.fail('In \n\t%s\nUnexpected error: %s'
134 % (' '.join(cmd), actual_error))
135 return retcode, actual_output, actual_error
136
137 def _check_output(self, expected, actual, test_case):
138- if expected is None:
139- # Specifying None means: any output is accepted
140- return
141- if actual is None:
142- test_case.fail('We expected output: %r, but found None'
143- % (expected,))
144+ if not actual:
145+ if expected is None:
146+ return
147+ elif expected == '...\n':
148+ return
149+ else:
150+ test_case.fail('expected output: %r, but found nothing'
151+ % (expected,))
152+ expected = expected or ''
153 matching = self.output_checker.check_output(
154 expected, actual, self.check_options)
155 if not matching:
156
157=== modified file 'bzrlib/tests/test_conflicts.py'
158--- bzrlib/tests/test_conflicts.py 2010-04-06 10:12:42 +0000
159+++ bzrlib/tests/test_conflicts.py 2010-10-08 06:36:46 +0000
160@@ -625,20 +625,18 @@
161 # tests MissingParent resolution :-/
162 preamble = """
163 $ bzr init trunk
164+...
165 $ cd trunk
166 $ mkdir dir
167-$ bzr add dir
168-$ bzr commit -m 'Create trunk'
169-
170+$ bzr add -q dir
171+$ bzr commit -m 'Create trunk' -q
172 $ echo 'trunk content' >dir/file
173-$ bzr add dir/file
174-$ bzr commit -m 'Add dir/file in trunk'
175-
176-$ bzr branch . -r 1 ../branch
177+$ bzr add -q dir/file
178+$ bzr commit -q -m 'Add dir/file in trunk'
179+$ bzr branch -q . -r 1 ../branch
180 $ cd ../branch
181-$ bzr rm dir
182-$ bzr commit -m 'Remove dir in branch'
183-
184+$ bzr rm dir -q
185+$ bzr commit -q -m 'Remove dir in branch'
186 $ bzr merge ../trunk
187 2>+N dir/
188 2>+N dir/file
189@@ -649,15 +647,15 @@
190
191 def test_take_this(self):
192 self.run_script("""
193-$ bzr rm dir --force
194+$ bzr rm -q dir --force
195 $ bzr resolve dir
196-$ bzr commit --strict -m 'No more conflicts nor unknown files'
197+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
198 """)
199
200 def test_take_other(self):
201 self.run_script("""
202 $ bzr resolve dir
203-$ bzr commit --strict -m 'No more conflicts nor unknown files'
204+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
205 """)
206
207
208@@ -665,22 +663,20 @@
209
210 preamble = """
211 $ bzr init trunk
212+...
213 $ cd trunk
214 $ mkdir dir
215 $ echo 'trunk content' >dir/file
216-$ bzr add
217-$ bzr commit -m 'Create trunk'
218-
219+$ bzr add -q
220+$ bzr commit -m 'Create trunk' -q
221 $ echo 'trunk content' >dir/file2
222-$ bzr add dir/file2
223-$ bzr commit -m 'Add dir/file2 in branch'
224-
225-$ bzr branch . -r 1 ../branch
226+$ bzr add -q dir/file2
227+$ bzr commit -q -m 'Add dir/file2 in branch'
228+$ bzr branch -q . -r 1 ../branch
229 $ cd ../branch
230-$ bzr rm dir/file --force
231-$ bzr rm dir
232-$ bzr commit -m 'Remove dir/file'
233-
234+$ bzr rm -q dir/file --force
235+$ bzr rm -q dir
236+$ bzr commit -q -m 'Remove dir/file'
237 $ bzr merge ../trunk
238 2>+N dir/
239 2>+N dir/file2
240@@ -692,34 +688,36 @@
241 def test_keep_them_all(self):
242 self.run_script("""
243 $ bzr resolve dir
244-$ bzr commit --strict -m 'No more conflicts nor unknown files'
245+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
246 """)
247
248 def test_adopt_child(self):
249 self.run_script("""
250-$ bzr mv dir/file2 file2
251-$ bzr rm dir --force
252+$ bzr mv -q dir/file2 file2
253+$ bzr rm -q dir --force
254 $ bzr resolve dir
255-$ bzr commit --strict -m 'No more conflicts nor unknown files'
256+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
257 """)
258
259 def test_kill_them_all(self):
260 self.run_script("""
261-$ bzr rm dir --force
262+$ bzr rm -q dir --force
263 $ bzr resolve dir
264-$ bzr commit --strict -m 'No more conflicts nor unknown files'
265+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
266 """)
267
268 def test_resolve_taking_this(self):
269 self.run_script("""
270 $ bzr resolve --take-this dir
271-$ bzr commit --strict -m 'No more conflicts nor unknown files'
272+2>...
273+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
274 """)
275
276 def test_resolve_taking_other(self):
277 self.run_script("""
278 $ bzr resolve --take-other dir
279-$ bzr commit --strict -m 'No more conflicts nor unknown files'
280+2>...
281+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
282 """)
283
284
285@@ -727,22 +725,20 @@
286
287 preamble = """
288 $ bzr init trunk
289+...
290 $ cd trunk
291 $ mkdir dir
292 $ echo 'trunk content' >dir/file
293-$ bzr add
294-$ bzr commit -m 'Create trunk'
295-
296-$ bzr rm dir/file --force
297-$ bzr rm dir --force
298-$ bzr commit -m 'Remove dir/file'
299-
300-$ bzr branch . -r 1 ../branch
301+$ bzr add -q
302+$ bzr commit -m 'Create trunk' -q
303+$ bzr rm -q dir/file --force
304+$ bzr rm -q dir --force
305+$ bzr commit -q -m 'Remove dir/file'
306+$ bzr branch -q . -r 1 ../branch
307 $ cd ../branch
308 $ echo 'branch content' >dir/file2
309-$ bzr add dir/file2
310-$ bzr commit -m 'Add dir/file2 in branch'
311-
312+$ bzr add -q dir/file2
313+$ bzr commit -q -m 'Add dir/file2 in branch'
314 $ bzr merge ../trunk
315 2>-D dir/file
316 2>Conflict: can't delete dir because it is not empty. Not deleting.
317@@ -753,34 +749,36 @@
318 def test_keep_them_all(self):
319 self.run_script("""
320 $ bzr resolve dir
321-$ bzr commit --strict -m 'No more conflicts nor unknown files'
322+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
323 """)
324
325 def test_adopt_child(self):
326 self.run_script("""
327-$ bzr mv dir/file2 file2
328-$ bzr rm dir --force
329+$ bzr mv -q dir/file2 file2
330+$ bzr rm -q dir --force
331 $ bzr resolve dir
332-$ bzr commit --strict -m 'No more conflicts nor unknown files'
333+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
334 """)
335
336 def test_kill_them_all(self):
337 self.run_script("""
338-$ bzr rm dir --force
339+$ bzr rm -q dir --force
340 $ bzr resolve dir
341-$ bzr commit --strict -m 'No more conflicts nor unknown files'
342+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
343 """)
344
345 def test_resolve_taking_this(self):
346 self.run_script("""
347 $ bzr resolve --take-this dir
348-$ bzr commit --strict -m 'No more conflicts nor unknown files'
349+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
350 """)
351
352 def test_resolve_taking_other(self):
353 self.run_script("""
354 $ bzr resolve --take-other dir
355-$ bzr commit --strict -m 'No more conflicts nor unknown files'
356+2>deleted dir/file2
357+2>deleted dir
358+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
359 """)
360
361
362@@ -882,19 +880,19 @@
363
364 preamble = """
365 $ bzr init trunk
366+...
367 $ cd trunk
368 $ bzr mkdir foo
369-$ bzr commit -m 'Create trunk'
370+...
371+$ bzr commit -m 'Create trunk' -q
372 $ echo "Boing" >foo/bar
373-$ bzr add foo/bar
374-$ bzr commit -m 'Add foo/bar'
375-
376-$ bzr branch . -r 1 ../branch
377+$ bzr add -q foo/bar
378+$ bzr commit -q -m 'Add foo/bar'
379+$ bzr branch -q . -r 1 ../branch
380 $ cd ../branch
381 $ rm -r foo
382 $ echo "Boo!" >foo
383-$ bzr commit -m 'foo is now a file'
384-
385+$ bzr commit -q -m 'foo is now a file'
386 $ bzr merge ../trunk
387 2>+N foo.new/bar
388 2>RK foo => foo.new/
389@@ -906,32 +904,34 @@
390
391 def test_take_this(self):
392 self.run_script("""
393-$ bzr rm foo.new --force
394+$ bzr rm -q foo.new --force
395 # FIXME: Isn't it weird that foo is now unkown even if foo.new has been put
396 # aside ? -- vila 090916
397-$ bzr add foo
398+$ bzr add -q foo
399 $ bzr resolve foo.new
400-$ bzr commit --strict -m 'No more conflicts nor unknown files'
401+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
402 """)
403
404 def test_take_other(self):
405 self.run_script("""
406-$ bzr rm foo --force
407-$ bzr mv foo.new foo
408+$ bzr rm -q foo --force
409+$ bzr mv -q foo.new foo
410 $ bzr resolve foo
411-$ bzr commit --strict -m 'No more conflicts nor unknown files'
412+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
413 """)
414
415 def test_resolve_taking_this(self):
416 self.run_script("""
417 $ bzr resolve --take-this foo.new
418-$ bzr commit --strict -m 'No more conflicts nor unknown files'
419+2>...
420+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
421 """)
422
423 def test_resolve_taking_other(self):
424 self.run_script("""
425 $ bzr resolve --take-other foo.new
426-$ bzr commit --strict -m 'No more conflicts nor unknown files'
427+2>...
428+$ bzr commit -q --strict -m 'No more conflicts nor unknown files'
429 """)
430
431
432@@ -943,19 +943,19 @@
433 # conflict.
434 self.run_script("""
435 $ bzr init trunk
436+...
437 $ cd trunk
438 $ bzr mkdir foo
439-$ bzr commit -m 'Create trunk'
440+...
441+$ bzr commit -m 'Create trunk' -q
442 $ rm -r foo
443 $ echo "Boo!" >foo
444-$ bzr commit -m 'foo is now a file'
445-
446-$ bzr branch . -r 1 ../branch
447+$ bzr commit -m 'foo is now a file' -q
448+$ bzr branch -q . -r 1 ../branch -q
449 $ cd ../branch
450 $ echo "Boing" >foo/bar
451-$ bzr add foo/bar
452-$ bzr commit -m 'Add foo/bar'
453-
454+$ bzr add -q foo/bar -q
455+$ bzr commit -m 'Add foo/bar' -q
456 $ bzr merge ../trunk
457 2>bzr: ERROR: Tree transform is malformed [('unversioned executability', 'new-1')]
458 """)
459
460=== modified file 'bzrlib/tests/test_delta.py'
461--- bzrlib/tests/test_delta.py 2010-04-26 16:59:56 +0000
462+++ bzrlib/tests/test_delta.py 2010-10-08 06:36:46 +0000
463@@ -65,8 +65,7 @@
464 reporter.report(file_id, (old_path, path), versioned_change, renamed,
465 modified, exe_change, kind)
466 if expected_lines is not None:
467- for i in range(len(expected_lines)):
468- self.assertEqualDiff(expected_lines[i], result[i])
469+ self.assertEqualDiff('\n'.join(expected_lines), '\n'.join(result))
470 else:
471 self.assertEqual([], result)
472
473
474=== modified file 'bzrlib/tests/test_script.py'
475--- bzrlib/tests/test_script.py 2010-09-13 09:00:03 +0000
476+++ bzrlib/tests/test_script.py 2010-10-08 06:36:46 +0000
477@@ -19,6 +19,7 @@
478 commands,
479 osutils,
480 tests,
481+ trace,
482 ui,
483 )
484 from bzrlib.tests import script
485@@ -162,6 +163,31 @@
486 def test_unknown_command(self):
487 self.assertRaises(SyntaxError, self.run_script, 'foo')
488
489+ def test_blank_output_mismatches_output(self):
490+ """If you give output, the output must actually be blank.
491+
492+ See <https://bugs.launchpad.net/bzr/+bug/637830>: previously blank
493+ output was a wildcard. Now you must say ... if you want that.
494+ """
495+ self.assertRaises(AssertionError,
496+ self.run_script,
497+ """
498+ $ echo foo
499+ """)
500+
501+ def test_ellipsis_everything(self):
502+ """A simple ellipsis matches everything."""
503+ self.run_script("""
504+ $ echo foo
505+ ...
506+ """)
507+
508+ def test_ellipsis_matches_empty(self):
509+ self.run_script("""
510+ $ cd .
511+ ...
512+ """)
513+
514 def test_stops_on_unexpected_output(self):
515 story = """
516 $ mkdir dir
517@@ -170,7 +196,6 @@
518 """
519 self.assertRaises(AssertionError, self.run_script, story)
520
521-
522 def test_stops_on_unexpected_error(self):
523 story = """
524 $ cat
525@@ -190,10 +215,13 @@
526 # The status matters, not the output
527 story = """
528 $ bzr init
529+...
530 $ cat >file
531 <Hello
532 $ bzr add file
533+...
534 $ bzr commit -m 'adding file'
535+2>...
536 """
537 self.run_script(story)
538
539@@ -245,6 +273,15 @@
540 cat dog "chicken" 'dragon'
541 """)
542
543+ def test_verbosity_isolated(self):
544+ """Global verbosity is isolated from commands run in scripts.
545+ """
546+ # see also 656694; we should get rid of global verbosity
547+ self.run_script("""
548+ $ bzr init --quiet a
549+ """)
550+ self.assertEquals(trace.is_quiet(), False)
551+
552
553 class TestCat(script.TestCaseWithTransportAndScript):
554
555@@ -356,7 +393,10 @@
556 class TestBzr(script.TestCaseWithTransportAndScript):
557
558 def test_bzr_smoke(self):
559- self.run_script('$ bzr init branch')
560+ self.run_script("""
561+ $ bzr init branch
562+ Created a standalone tree (format: ...)
563+ """)
564 self.failUnlessExists('branch')
565
566
567
568=== modified file 'doc/developers/testing.txt'
569--- doc/developers/testing.txt 2010-09-23 09:54:51 +0000
570+++ doc/developers/testing.txt 2010-10-08 06:36:46 +0000
571@@ -388,6 +388,12 @@
572 If you want the command to succeed for any output, just use::
573
574 $ bzr add file
575+ ...
576+ 2>...
577+
578+or use the ``--quiet`` option::
579+
580+ $ bzr add -q file
581
582 The following will stop with an error::
583