/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
329 by Martin Pool
- refactor command functions into command classes
1
# Copyright (C) 2004, 2005 by Canonical Ltd
1 by mbp at sourcefrog
import from baz patch-364
2
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
572 by Martin Pool
- trim imports
19
import sys, os
1 by mbp at sourcefrog
import from baz patch-364
20
21
import bzrlib
22
from bzrlib.trace import mutter, note, log_error
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
23
from bzrlib.errors import BzrError, BzrCheckError, BzrCommandError
592 by Martin Pool
- trim imports more
24
from bzrlib.osutils import quotefn
25
from bzrlib import Branch, Inventory, InventoryEntry, BZRDIR, \
1 by mbp at sourcefrog
import from baz patch-364
26
     format_date
27
28
350 by Martin Pool
- refactor command aliases into command classes
29
def _squish_command_name(cmd):
30
    return 'cmd_' + cmd.replace('-', '_')
31
32
33
def _unsquish_command_name(cmd):
34
    assert cmd.startswith("cmd_")
35
    return cmd[4:].replace('_','-')
36
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
37
def _parse_revision_str(revstr):
38
    """This handles a revision string -> revno. 
39
40
    There are several possibilities:
41
42
        '234'       -> 234
43
        '234:345'   -> [234, 345]
44
        ':234'      -> [None, 234]
45
        '234:'      -> [234, None]
46
47
    In the future we will also support:
48
        'uuid:blah-blah-blah'   -> ?
49
        'hash:blahblahblah'     -> ?
50
        potentially:
51
        'tag:mytag'             -> ?
52
    """
53
    if revstr.find(':') != -1:
54
        revs = revstr.split(':')
55
        if len(revs) > 2:
56
            raise ValueError('More than 2 pieces not supported for --revision: %r' % revstr)
57
58
        if not revs[0]:
59
            revs[0] = None
60
        else:
61
            revs[0] = int(revs[0])
62
63
        if not revs[1]:
64
            revs[1] = None
65
        else:
66
            revs[1] = int(revs[1])
67
    else:
68
        revs = int(revstr)
69
    return revs
70
641 by Martin Pool
- improved external-command patch from john
71
def _find_plugins():
72
    """Find all python files which are plugins, and load their commands
73
    to add to the list of "all commands"
74
75
    The environment variable BZRPATH is considered a delimited set of
76
    paths to look through. Each entry is searched for *.py files.
77
    If a directory is found, it is also searched, but they are 
78
    not searched recursively. This allows you to revctl the plugins.
79
    
80
    Inside the plugin should be a series of cmd_* function, which inherit from
81
    the bzrlib.commands.Command class.
82
    """
83
    bzrpath = os.environ.get('BZRPLUGINPATH', '')
84
85
    plugin_cmds = {} 
86
    if not bzrpath:
87
        return plugin_cmds
88
    _platform_extensions = {
89
        'win32':'.pyd',
90
        'cygwin':'.dll',
91
        'darwin':'.dylib',
92
        'linux2':'.so'
93
        }
94
    if _platform_extensions.has_key(sys.platform):
95
        platform_extension = _platform_extensions[sys.platform]
96
    else:
97
        platform_extension = None
98
    for d in bzrpath.split(os.pathsep):
99
        plugin_names = {} # This should really be a set rather than a dict
100
        for f in os.listdir(d):
101
            if f.endswith('.py'):
102
                f = f[:-3]
103
            elif f.endswith('.pyc') or f.endswith('.pyo'):
104
                f = f[:-4]
105
            elif platform_extension and f.endswith(platform_extension):
106
                f = f[:-len(platform_extension)]
107
                if f.endswidth('module'):
108
                    f = f[:-len('module')]
109
            else:
110
                continue
111
            if not plugin_names.has_key(f):
112
                plugin_names[f] = True
113
114
        plugin_names = plugin_names.keys()
115
        plugin_names.sort()
116
        try:
117
            sys.path.insert(0, d)
118
            for name in plugin_names:
119
                try:
120
                    old_module = None
121
                    try:
122
                        if sys.modules.has_key(name):
123
                            old_module = sys.modules[name]
124
                            del sys.modules[name]
125
                        plugin = __import__(name, locals())
126
                        for k in dir(plugin):
127
                            if k.startswith('cmd_'):
128
                                k_unsquished = _unsquish_command_name(k)
129
                                if not plugin_cmds.has_key(k_unsquished):
130
                                    plugin_cmds[k_unsquished] = getattr(plugin, k)
131
                                else:
132
                                    log_error('Two plugins defined the same command: %r' % k)
133
                                    log_error('Not loading the one in %r in dir %r' % (name, d))
134
                    finally:
135
                        if old_module:
136
                            sys.modules[name] = old_module
137
                except ImportError, e:
138
                    log_error('Unable to load plugin: %r from %r\n%s' % (name, d, e))
139
        finally:
140
            sys.path.pop(0)
141
    return plugin_cmds
142
143
def _get_cmd_dict(include_plugins=True):
144
    d = {}
350 by Martin Pool
- refactor command aliases into command classes
145
    for k, v in globals().iteritems():
146
        if k.startswith("cmd_"):
641 by Martin Pool
- improved external-command patch from john
147
            d[_unsquish_command_name(k)] = v
148
    if include_plugins:
149
        d.update(_find_plugins())
150
    return d
151
    
152
def get_all_cmds(include_plugins=True):
153
    """Return canonical name and class for all registered commands."""
154
    for k, v in _get_cmd_dict(include_plugins=include_plugins).iteritems():
155
        yield k,v
156
157
158
def get_cmd_class(cmd,include_plugins=True):
350 by Martin Pool
- refactor command aliases into command classes
159
    """Return the canonical name and command class for a command.
160
    """
161
    cmd = str(cmd)                      # not unicode
162
163
    # first look up this command under the specified name
641 by Martin Pool
- improved external-command patch from john
164
    cmds = _get_cmd_dict(include_plugins=include_plugins)
272 by Martin Pool
- Add command aliases
165
    try:
641 by Martin Pool
- improved external-command patch from john
166
        return cmd, cmds[cmd]
272 by Martin Pool
- Add command aliases
167
    except KeyError:
350 by Martin Pool
- refactor command aliases into command classes
168
        pass
169
170
    # look for any command which claims this as an alias
641 by Martin Pool
- improved external-command patch from john
171
    for cmdname, cmdclass in cmds.iteritems():
350 by Martin Pool
- refactor command aliases into command classes
172
        if cmd in cmdclass.aliases:
173
            return cmdname, cmdclass
422 by Martin Pool
- External-command patch from mpe
174
175
    cmdclass = ExternalCommand.find_command(cmd)
176
    if cmdclass:
177
        return cmd, cmdclass
178
179
    raise BzrCommandError("unknown command %r" % cmd)
272 by Martin Pool
- Add command aliases
180
329 by Martin Pool
- refactor command functions into command classes
181
558 by Martin Pool
- All top-level classes inherit from object
182
class Command(object):
329 by Martin Pool
- refactor command functions into command classes
183
    """Base class for commands.
184
185
    The docstring for an actual command should give a single-line
186
    summary, then a complete description of the command.  A grammar
187
    description will be inserted.
188
189
    takes_args
190
        List of argument forms, marked with whether they are optional,
191
        repeated, etc.
192
193
    takes_options
194
        List of options that may be given for this command.
195
196
    hidden
197
        If true, this command isn't advertised.
198
    """
199
    aliases = []
200
    
201
    takes_args = []
202
    takes_options = []
203
204
    hidden = False
205
    
206
    def __init__(self, options, arguments):
207
        """Construct and run the command.
208
209
        Sets self.status to the return value of run()."""
210
        assert isinstance(options, dict)
211
        assert isinstance(arguments, dict)
212
        cmdargs = options.copy()
213
        cmdargs.update(arguments)
214
        assert self.__doc__ != Command.__doc__, \
215
               ("No help message set for %r" % self)
216
        self.status = self.run(**cmdargs)
217
218
    
219
    def run(self):
220
        """Override this in sub-classes.
221
222
        This is invoked with the options and arguments bound to
223
        keyword parameters.
224
337 by Martin Pool
- Clarify return codes from command objects
225
        Return 0 or None if the command was successful, or a shell
226
        error code if not.
329 by Martin Pool
- refactor command functions into command classes
227
        """
337 by Martin Pool
- Clarify return codes from command objects
228
        return 0
329 by Martin Pool
- refactor command functions into command classes
229
230
422 by Martin Pool
- External-command patch from mpe
231
class ExternalCommand(Command):
232
    """Class to wrap external commands.
233
234
    We cheat a little here, when get_cmd_class() calls us we actually give it back
235
    an object we construct that has the appropriate path, help, options etc for the
236
    specified command.
237
238
    When run_bzr() tries to instantiate that 'class' it gets caught by the __call__
239
    method, which we override to call the Command.__init__ method. That then calls
240
    our run method which is pretty straight forward.
241
242
    The only wrinkle is that we have to map bzr's dictionary of options and arguments
243
    back into command line options and arguments for the script.
244
    """
245
246
    def find_command(cls, cmd):
572 by Martin Pool
- trim imports
247
        import os.path
422 by Martin Pool
- External-command patch from mpe
248
        bzrpath = os.environ.get('BZRPATH', '')
249
641 by Martin Pool
- improved external-command patch from john
250
        for dir in bzrpath.split(os.pathsep):
422 by Martin Pool
- External-command patch from mpe
251
            path = os.path.join(dir, cmd)
252
            if os.path.isfile(path):
253
                return ExternalCommand(path)
254
255
        return None
256
257
    find_command = classmethod(find_command)
258
259
    def __init__(self, path):
260
        self.path = path
261
262
        pipe = os.popen('%s --bzr-usage' % path, 'r')
263
        self.takes_options = pipe.readline().split()
687 by Martin Pool
- trap more errors from external commands
264
265
        for opt in self.takes_options:
266
            if not opt in OPTIONS:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
267
                raise BzrError("Unknown option '%s' returned by external command %s"
268
                               % (opt, path))
687 by Martin Pool
- trap more errors from external commands
269
270
        # TODO: Is there any way to check takes_args is valid here?
422 by Martin Pool
- External-command patch from mpe
271
        self.takes_args = pipe.readline().split()
687 by Martin Pool
- trap more errors from external commands
272
273
        if pipe.close() is not None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
274
            raise BzrError("Failed funning '%s --bzr-usage'" % path)
422 by Martin Pool
- External-command patch from mpe
275
276
        pipe = os.popen('%s --bzr-help' % path, 'r')
277
        self.__doc__ = pipe.read()
687 by Martin Pool
- trap more errors from external commands
278
        if pipe.close() is not None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
279
            raise BzrError("Failed funning '%s --bzr-help'" % path)
422 by Martin Pool
- External-command patch from mpe
280
281
    def __call__(self, options, arguments):
282
        Command.__init__(self, options, arguments)
283
        return self
284
285
    def run(self, **kargs):
286
        opts = []
287
        args = []
288
289
        keys = kargs.keys()
290
        keys.sort()
291
        for name in keys:
689 by Martin Pool
- make options with - work with external commands
292
            optname = name.replace('_','-')
422 by Martin Pool
- External-command patch from mpe
293
            value = kargs[name]
689 by Martin Pool
- make options with - work with external commands
294
            if OPTIONS.has_key(optname):
422 by Martin Pool
- External-command patch from mpe
295
                # it's an option
689 by Martin Pool
- make options with - work with external commands
296
                opts.append('--%s' % optname)
422 by Martin Pool
- External-command patch from mpe
297
                if value is not None and value is not True:
298
                    opts.append(str(value))
299
            else:
300
                # it's an arg, or arg list
301
                if type(value) is not list:
302
                    value = [value]
303
                for v in value:
304
                    if v is not None:
305
                        args.append(str(v))
306
307
        self.status = os.spawnv(os.P_WAIT, self.path, [self.path] + opts + args)
308
        return self.status
309
329 by Martin Pool
- refactor command functions into command classes
310
311
class cmd_status(Command):
1 by mbp at sourcefrog
import from baz patch-364
312
    """Display status summary.
313
466 by Martin Pool
- doc for status command
314
    This reports on versioned and unknown files, reporting them
315
    grouped by state.  Possible states are:
316
317
    added
318
        Versioned in the working copy but not in the previous revision.
319
320
    removed
467 by Martin Pool
- doc for status command
321
        Versioned in the previous revision but removed or deleted
466 by Martin Pool
- doc for status command
322
        in the working copy.
323
324
    renamed
325
        Path of this file changed from the previous revision;
326
        the text may also have changed.  This includes files whose
467 by Martin Pool
- doc for status command
327
        parent directory was renamed.
466 by Martin Pool
- doc for status command
328
329
    modified
330
        Text has changed since the previous revision.
331
332
    unchanged
467 by Martin Pool
- doc for status command
333
        Nothing about this file has changed since the previous revision.
334
        Only shown with --all.
466 by Martin Pool
- doc for status command
335
336
    unknown
337
        Not versioned and not matching an ignore pattern.
338
339
    To see ignored files use 'bzr ignored'.  For details in the
340
    changes to file texts, use 'bzr diff'.
468 by Martin Pool
- Interpret arguments to bzr status
341
342
    If no arguments are specified, the status of the entire working
343
    directory is shown.  Otherwise, only the status of the specified
344
    files or directories is reported.  If a directory is given, status
345
    is reported for everything inside that directory.
1 by mbp at sourcefrog
import from baz patch-364
346
    """
404 by Martin Pool
- bzr status now optionally takes filenames to check
347
    takes_args = ['file*']
465 by Martin Pool
- Move show_status() out of Branch into a new function in
348
    takes_options = ['all', 'show-ids']
350 by Martin Pool
- refactor command aliases into command classes
349
    aliases = ['st', 'stat']
329 by Martin Pool
- refactor command functions into command classes
350
    
465 by Martin Pool
- Move show_status() out of Branch into a new function in
351
    def run(self, all=False, show_ids=False, file_list=None):
468 by Martin Pool
- Interpret arguments to bzr status
352
        if file_list:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
353
            b = Branch(file_list[0])
468 by Martin Pool
- Interpret arguments to bzr status
354
            file_list = [b.relpath(x) for x in file_list]
355
            # special case: only one path was given and it's the root
356
            # of the branch
357
            if file_list == ['']:
358
                file_list = None
359
        else:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
360
            b = Branch('.')
465 by Martin Pool
- Move show_status() out of Branch into a new function in
361
        import status
362
        status.show_status(b, show_unchanged=all, show_ids=show_ids,
483 by Martin Pool
- change 'file_list' to more explanatory 'specific_files'
363
                           specific_files=file_list)
329 by Martin Pool
- refactor command functions into command classes
364
365
366
class cmd_cat_revision(Command):
367
    """Write out metadata for a revision."""
368
369
    hidden = True
370
    takes_args = ['revision_id']
371
    
372
    def run(self, revision_id):
373
        Branch('.').get_revision(revision_id).write_xml(sys.stdout)
374
375
376
class cmd_revno(Command):
377
    """Show current revision number.
378
379
    This is equal to the number of revisions on this branch."""
380
    def run(self):
381
        print Branch('.').revno()
382
383
    
384
class cmd_add(Command):
70 by mbp at sourcefrog
Prepare for smart recursive add.
385
    """Add specified files or directories.
386
387
    In non-recursive mode, all the named items are added, regardless
388
    of whether they were previously ignored.  A warning is given if
389
    any of the named files are already versioned.
390
391
    In recursive mode (the default), files are treated the same way
392
    but the behaviour for directories is different.  Directories that
393
    are already versioned do not give a warning.  All directories,
394
    whether already versioned or not, are searched for files or
395
    subdirectories that are neither versioned or ignored, and these
396
    are added.  This search proceeds recursively into versioned
397
    directories.
398
399
    Therefore simply saying 'bzr add .' will version all files that
400
    are currently unknown.
279 by Martin Pool
todo
401
402
    TODO: Perhaps adding a file whose directly is not versioned should
403
    recursively add that parent, rather than giving an error?
70 by mbp at sourcefrog
Prepare for smart recursive add.
404
    """
329 by Martin Pool
- refactor command functions into command classes
405
    takes_args = ['file+']
594 by Martin Pool
- add --no-recurse option for add command
406
    takes_options = ['verbose', 'no-recurse']
329 by Martin Pool
- refactor command functions into command classes
407
    
594 by Martin Pool
- add --no-recurse option for add command
408
    def run(self, file_list, verbose=False, no_recurse=False):
409
        bzrlib.add.smart_add(file_list, verbose, not no_recurse)
329 by Martin Pool
- refactor command functions into command classes
410
411
386 by Martin Pool
- Typo (reported by uws)
412
class cmd_relpath(Command):
329 by Martin Pool
- refactor command functions into command classes
413
    """Show path of a file relative to root"""
392 by Martin Pool
- fix relpath and add tests
414
    takes_args = ['filename']
584 by Martin Pool
- make relpath and revision-history hidden commands
415
    hidden = True
329 by Martin Pool
- refactor command functions into command classes
416
    
392 by Martin Pool
- fix relpath and add tests
417
    def run(self, filename):
418
        print Branch(filename).relpath(filename)
329 by Martin Pool
- refactor command functions into command classes
419
420
421
422
class cmd_inventory(Command):
423
    """Show inventory of the current working copy or a revision."""
588 by Martin Pool
- change inventory command to not show ids by default
424
    takes_options = ['revision', 'show-ids']
329 by Martin Pool
- refactor command functions into command classes
425
    
588 by Martin Pool
- change inventory command to not show ids by default
426
    def run(self, revision=None, show_ids=False):
329 by Martin Pool
- refactor command functions into command classes
427
        b = Branch('.')
428
        if revision == None:
429
            inv = b.read_working_inventory()
430
        else:
431
            inv = b.get_revision_inventory(b.lookup_revision(revision))
432
556 by Martin Pool
- fix up Inventory.entries()
433
        for path, entry in inv.entries():
588 by Martin Pool
- change inventory command to not show ids by default
434
            if show_ids:
435
                print '%-50s %s' % (path, entry.file_id)
436
            else:
437
                print path
329 by Martin Pool
- refactor command functions into command classes
438
439
440
class cmd_move(Command):
441
    """Move files to a different directory.
442
443
    examples:
444
        bzr move *.txt doc
445
446
    The destination must be a versioned directory in the same branch.
447
    """
448
    takes_args = ['source$', 'dest']
449
    def run(self, source_list, dest):
450
        b = Branch('.')
451
452
        b.move([b.relpath(s) for s in source_list], b.relpath(dest))
453
454
455
class cmd_rename(Command):
168 by mbp at sourcefrog
new "rename" command
456
    """Change the name of an entry.
457
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
458
    examples:
459
      bzr rename frob.c frobber.c
460
      bzr rename src/frob.c lib/frob.c
461
462
    It is an error if the destination name exists.
463
464
    See also the 'move' command, which moves files into a different
465
    directory without changing their name.
466
467
    TODO: Some way to rename multiple files without invoking bzr for each
468
    one?"""
329 by Martin Pool
- refactor command functions into command classes
469
    takes_args = ['from_name', 'to_name']
168 by mbp at sourcefrog
new "rename" command
470
    
329 by Martin Pool
- refactor command functions into command classes
471
    def run(self, from_name, to_name):
472
        b = Branch('.')
473
        b.rename_one(b.relpath(from_name), b.relpath(to_name))
474
475
476
628 by Martin Pool
- merge aaron's updated merge/pull code
477
478
479
class cmd_pull(Command):
480
    """Pull any changes from another branch into the current one.
481
482
    If the location is omitted, the last-used location will be used.
483
    Both the revision history and the working directory will be
484
    updated.
485
486
    This command only works on branches that have not diverged.  Branches are
487
    considered diverged if both branches have had commits without first
488
    pulling from the other.
489
490
    If branches have diverged, you can use 'bzr merge' to pull the text changes
491
    from one into the other.
492
    """
493
    takes_args = ['location?']
494
495
    def run(self, location=None):
496
        from bzrlib.merge import merge
497
        import errno
498
        
499
        br_to = Branch('.')
500
        stored_loc = None
501
        try:
502
            stored_loc = br_to.controlfile("x-pull", "rb").read().rstrip('\n')
503
        except IOError, e:
504
            if errno == errno.ENOENT:
505
                raise
506
        if location is None:
729 by Martin Pool
- pull shows location being used
507
            if stored_loc is None:
508
                raise BzrCommandError("No pull location known or specified.")
509
            else:
510
                print "Using last location: %s" % stored_loc
511
                location = stored_loc
628 by Martin Pool
- merge aaron's updated merge/pull code
512
        from branch import find_branch, DivergedBranches
513
        br_from = find_branch(location)
514
        location = pull_loc(br_from)
515
        old_revno = br_to.revno()
516
        try:
517
            br_to.update_revisions(br_from)
518
        except DivergedBranches:
519
            raise BzrCommandError("These branches have diverged.  Try merge.")
520
            
640 by Martin Pool
- bzr pull should not check that the tree is clean
521
        merge(('.', -1), ('.', old_revno), check_clean=False)
628 by Martin Pool
- merge aaron's updated merge/pull code
522
        if location != stored_loc:
523
            br_to.controlfile("x-pull", "wb").write(location + "\n")
524
525
526
527
class cmd_branch(Command):
528
    """Create a new copy of a branch.
529
685 by Martin Pool
- add -r option to the branch command
530
    If the TO_LOCATION is omitted, the last component of the FROM_LOCATION will
531
    be used.  In other words, "branch ../foo/bar" will attempt to create ./bar.
532
533
    To retrieve the branch as of a particular revision, supply the --revision
534
    parameter, as in "branch foo/bar -r 5".
628 by Martin Pool
- merge aaron's updated merge/pull code
535
    """
536
    takes_args = ['from_location', 'to_location?']
685 by Martin Pool
- add -r option to the branch command
537
    takes_options = ['revision']
628 by Martin Pool
- merge aaron's updated merge/pull code
538
685 by Martin Pool
- add -r option to the branch command
539
    def run(self, from_location, to_location=None, revision=None):
628 by Martin Pool
- merge aaron's updated merge/pull code
540
        import errno
541
        from bzrlib.merge import merge
685 by Martin Pool
- add -r option to the branch command
542
        from branch import find_branch, DivergedBranches, NoSuchRevision
543
        from shutil import rmtree
671 by Martin Pool
- Don't create an empty destination directory when
544
        try:
545
            br_from = find_branch(from_location)
546
        except OSError, e:
547
            if e.errno == errno.ENOENT:
548
                raise BzrCommandError('Source location "%s" does not exist.' %
549
                                      to_location)
550
            else:
551
                raise
552
628 by Martin Pool
- merge aaron's updated merge/pull code
553
        if to_location is None:
684 by Martin Pool
- Strip any number of trailing slashes and backslashes from the path name
554
            to_location = os.path.basename(from_location.rstrip("/\\"))
628 by Martin Pool
- merge aaron's updated merge/pull code
555
556
        try:
557
            os.mkdir(to_location)
558
        except OSError, e:
559
            if e.errno == errno.EEXIST:
560
                raise BzrCommandError('Target directory "%s" already exists.' %
561
                                      to_location)
562
            if e.errno == errno.ENOENT:
563
                raise BzrCommandError('Parent of "%s" does not exist.' %
564
                                      to_location)
565
            else:
566
                raise
567
        br_to = Branch(to_location, init=True)
568
685 by Martin Pool
- add -r option to the branch command
569
        try:
570
            br_to.update_revisions(br_from, stop_revision=revision)
571
        except NoSuchRevision:
572
            rmtree(to_location)
573
            msg = "The branch %s has no revision %d." % (from_location,
574
                                                         revision)
575
            raise BzrCommandError(msg)
628 by Martin Pool
- merge aaron's updated merge/pull code
576
        merge((to_location, -1), (to_location, 0), this_dir=to_location,
698 by Martin Pool
- bzr branch shouldn't say "0 conflicts"
577
              check_clean=False, ignore_zero=True)
685 by Martin Pool
- add -r option to the branch command
578
        from_location = pull_loc(br_from)
628 by Martin Pool
- merge aaron's updated merge/pull code
579
        br_to.controlfile("x-pull", "wb").write(from_location + "\n")
580
581
582
def pull_loc(branch):
583
    # TODO: Should perhaps just make attribute be 'base' in
584
    # RemoteBranch and Branch?
585
    if hasattr(branch, "baseurl"):
586
        return branch.baseurl
587
    else:
588
        return branch.base
589
590
591
329 by Martin Pool
- refactor command functions into command classes
592
class cmd_renames(Command):
164 by mbp at sourcefrog
new 'renames' command
593
    """Show list of renamed files.
594
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
595
    TODO: Option to show renames between two historical versions.
596
597
    TODO: Only show renames under dir, rather than in the whole branch.
598
    """
329 by Martin Pool
- refactor command functions into command classes
599
    takes_args = ['dir?']
600
601
    def run(self, dir='.'):
602
        b = Branch(dir)
603
        old_inv = b.basis_tree().inventory
604
        new_inv = b.read_working_inventory()
605
606
        renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
607
        renames.sort()
608
        for old_name, new_name in renames:
609
            print "%s => %s" % (old_name, new_name)        
610
611
612
class cmd_info(Command):
472 by Martin Pool
- Optional branch parameter to info command
613
    """Show statistical information about a branch."""
614
    takes_args = ['branch?']
615
    
616
    def run(self, branch=None):
329 by Martin Pool
- refactor command functions into command classes
617
        import info
472 by Martin Pool
- Optional branch parameter to info command
618
619
        from branch import find_branch
620
        b = find_branch(branch)
621
        info.show_info(b)
329 by Martin Pool
- refactor command functions into command classes
622
623
624
class cmd_remove(Command):
625
    """Make a file unversioned.
626
627
    This makes bzr stop tracking changes to a versioned file.  It does
628
    not delete the working copy.
629
    """
630
    takes_args = ['file+']
631
    takes_options = ['verbose']
632
    
633
    def run(self, file_list, verbose=False):
634
        b = Branch(file_list[0])
635
        b.remove([b.relpath(f) for f in file_list], verbose=verbose)
636
637
638
class cmd_file_id(Command):
178 by mbp at sourcefrog
- Use a non-null file_id for the branch root directory. At the moment
639
    """Print file_id of a particular file or directory.
640
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
641
    The file_id is assigned when the file is first added and remains the
642
    same through all revisions where the file exists, even when it is
643
    moved or renamed.
644
    """
329 by Martin Pool
- refactor command functions into command classes
645
    hidden = True
646
    takes_args = ['filename']
647
    def run(self, filename):
648
        b = Branch(filename)
649
        i = b.inventory.path2id(b.relpath(filename))
650
        if i == None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
651
            raise BzrError("%r is not a versioned file" % filename)
329 by Martin Pool
- refactor command functions into command classes
652
        else:
653
            print i
654
655
656
class cmd_file_path(Command):
178 by mbp at sourcefrog
- Use a non-null file_id for the branch root directory. At the moment
657
    """Print path of file_ids to a file or directory.
658
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
659
    This prints one line for each directory down to the target,
660
    starting at the branch root."""
329 by Martin Pool
- refactor command functions into command classes
661
    hidden = True
662
    takes_args = ['filename']
663
    def run(self, filename):
664
        b = Branch(filename)
665
        inv = b.inventory
666
        fid = inv.path2id(b.relpath(filename))
667
        if fid == None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
668
            raise BzrError("%r is not a versioned file" % filename)
329 by Martin Pool
- refactor command functions into command classes
669
        for fip in inv.get_idpath(fid):
670
            print fip
671
672
673
class cmd_revision_history(Command):
674
    """Display list of revision ids on this branch."""
584 by Martin Pool
- make relpath and revision-history hidden commands
675
    hidden = True
329 by Martin Pool
- refactor command functions into command classes
676
    def run(self):
677
        for patchid in Branch('.').revision_history():
678
            print patchid
679
680
681
class cmd_directories(Command):
682
    """Display list of versioned directories in this branch."""
683
    def run(self):
684
        for name, ie in Branch('.').read_working_inventory().directories():
685
            if name == '':
686
                print '.'
687
            else:
688
                print name
689
690
691
class cmd_init(Command):
692
    """Make a directory into a versioned branch.
693
694
    Use this to create an empty branch, or before importing an
695
    existing project.
696
697
    Recipe for importing a tree of files:
698
        cd ~/project
699
        bzr init
700
        bzr add -v .
701
        bzr status
702
        bzr commit -m 'imported project'
703
    """
704
    def run(self):
705
        Branch('.', init=True)
706
707
708
class cmd_diff(Command):
709
    """Show differences in working tree.
710
    
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
711
    If files are listed, only the changes in those files are listed.
712
    Otherwise, all changes for the tree are listed.
713
714
    TODO: Given two revision arguments, show the difference between them.
715
716
    TODO: Allow diff across branches.
717
718
    TODO: Option to use external diff command; could be GNU diff, wdiff,
719
          or a graphical diff.
720
276 by Martin Pool
Doc
721
    TODO: Python difflib is not exactly the same as unidiff; should
722
          either fix it up or prefer to use an external diff.
723
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
724
    TODO: If a directory is given, diff everything under that.
725
276 by Martin Pool
Doc
726
    TODO: Selected-file diff is inefficient and doesn't show you
727
          deleted files.
278 by Martin Pool
- Better workaround for trailing newlines in diffs
728
729
    TODO: This probably handles non-Unix newlines poorly.
329 by Martin Pool
- refactor command functions into command classes
730
    """
731
    
732
    takes_args = ['file*']
571 by Martin Pool
- new --diff-options to pass options through to external
733
    takes_options = ['revision', 'diff-options']
638 by Martin Pool
- add 'dif' as alias for 'diff' command
734
    aliases = ['di', 'dif']
329 by Martin Pool
- refactor command functions into command classes
735
571 by Martin Pool
- new --diff-options to pass options through to external
736
    def run(self, revision=None, file_list=None, diff_options=None):
329 by Martin Pool
- refactor command functions into command classes
737
        from bzrlib.diff import show_diff
547 by Martin Pool
- bzr diff finds a branch from the first parameter,
738
        from bzrlib import find_branch
739
740
        if file_list:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
741
            b = find_branch(file_list[0])
547 by Martin Pool
- bzr diff finds a branch from the first parameter,
742
            file_list = [b.relpath(f) for f in file_list]
743
            if file_list == ['']:
744
                # just pointing to top-of-tree
745
                file_list = None
746
        else:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
747
            b = Branch('.')
329 by Martin Pool
- refactor command functions into command classes
748
    
571 by Martin Pool
- new --diff-options to pass options through to external
749
        show_diff(b, revision, specific_files=file_list,
750
                  external_diff_options=diff_options)
329 by Martin Pool
- refactor command functions into command classes
751
752
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
753
        
754
755
329 by Martin Pool
- refactor command functions into command classes
756
class cmd_deleted(Command):
135 by mbp at sourcefrog
Simple new 'deleted' command
757
    """List files deleted in the working tree.
758
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
759
    TODO: Show files deleted since a previous revision, or between two revisions.
135 by mbp at sourcefrog
Simple new 'deleted' command
760
    """
329 by Martin Pool
- refactor command functions into command classes
761
    def run(self, show_ids=False):
762
        b = Branch('.')
763
        old = b.basis_tree()
764
        new = b.working_tree()
765
766
        ## TODO: Much more efficient way to do this: read in new
767
        ## directories with readdir, rather than stating each one.  Same
768
        ## level of effort but possibly much less IO.  (Or possibly not,
769
        ## if the directories are very large...)
770
771
        for path, ie in old.inventory.iter_entries():
772
            if not new.has_id(ie.file_id):
773
                if show_ids:
774
                    print '%-50s %s' % (path, ie.file_id)
775
                else:
776
                    print path
777
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
778
779
class cmd_modified(Command):
780
    """List files modified in working tree."""
781
    hidden = True
782
    def run(self):
783
        import statcache
784
        b = Branch('.')
438 by Martin Pool
- Avoid calling Inventory.iter_entries() when finding modified
785
        inv = b.read_working_inventory()
786
        sc = statcache.update_cache(b, inv)
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
787
        basis = b.basis_tree()
788
        basis_inv = basis.inventory
438 by Martin Pool
- Avoid calling Inventory.iter_entries() when finding modified
789
        
790
        # We used to do this through iter_entries(), but that's slow
791
        # when most of the files are unmodified, as is usually the
792
        # case.  So instead we iterate by inventory entry, and only
793
        # calculate paths as necessary.
794
795
        for file_id in basis_inv:
796
            cacheentry = sc.get(file_id)
797
            if not cacheentry:                 # deleted
798
                continue
799
            ie = basis_inv[file_id]
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
800
            if cacheentry[statcache.SC_SHA1] != ie.text_sha1:
438 by Martin Pool
- Avoid calling Inventory.iter_entries() when finding modified
801
                path = inv.id2path(file_id)
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
802
                print path
439 by Martin Pool
- new command 'bzr added'
803
804
805
806
class cmd_added(Command):
807
    """List files added in working tree."""
808
    hidden = True
809
    def run(self):
810
        b = Branch('.')
811
        wt = b.working_tree()
812
        basis_inv = b.basis_tree().inventory
813
        inv = wt.inventory
814
        for file_id in inv:
815
            if file_id in basis_inv:
816
                continue
817
            path = inv.id2path(file_id)
818
            if not os.access(b.abspath(path), os.F_OK):
819
                continue
820
            print path
437 by Martin Pool
- new command 'bzr modified' to exercise the statcache
821
                
822
        
823
329 by Martin Pool
- refactor command functions into command classes
824
class cmd_root(Command):
825
    """Show the tree root directory.
826
827
    The root is the nearest enclosing directory with a .bzr control
828
    directory."""
829
    takes_args = ['filename?']
830
    def run(self, filename=None):
831
        """Print the branch root."""
416 by Martin Pool
- bzr log and bzr root now accept an http URL
832
        from branch import find_branch
833
        b = find_branch(filename)
834
        print getattr(b, 'base', None) or getattr(b, 'baseurl')
329 by Martin Pool
- refactor command functions into command classes
835
836
837
class cmd_log(Command):
1 by mbp at sourcefrog
import from baz patch-364
838
    """Show log of this branch.
839
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
840
    To request a range of logs, you can use the command -r begin:end
841
    -r revision requests a specific revision, -r :end or -r begin: are
842
    also valid.
843
844
    TODO: Make --revision support uuid: and hash: [future tag:] notation.
845
  
545 by Martin Pool
- --forward option for log
846
    """
367 by Martin Pool
- New --show-ids option for bzr log
847
378 by Martin Pool
- New usage bzr log FILENAME
848
    takes_args = ['filename?']
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
849
    takes_options = ['forward', 'timezone', 'verbose', 'show-ids', 'revision']
545 by Martin Pool
- --forward option for log
850
    
851
    def run(self, filename=None, timezone='original',
852
            verbose=False,
853
            show_ids=False,
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
854
            forward=False,
855
            revision=None):
527 by Martin Pool
- refactor log command
856
        from bzrlib import show_log, find_branch
562 by Martin Pool
- bug fix for printing logs containing unicode
857
        import codecs
545 by Martin Pool
- --forward option for log
858
859
        direction = (forward and 'forward') or 'reverse'
527 by Martin Pool
- refactor log command
860
        
378 by Martin Pool
- New usage bzr log FILENAME
861
        if filename:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
862
            b = find_branch(filename)
527 by Martin Pool
- refactor log command
863
            fp = b.relpath(filename)
533 by Martin Pool
- fix up asking for the log for the root of a remote branch
864
            if fp:
865
                file_id = b.read_working_inventory().path2id(fp)
866
            else:
867
                file_id = None  # points to branch root
527 by Martin Pool
- refactor log command
868
        else:
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
869
            b = find_branch('.')
527 by Martin Pool
- refactor log command
870
            file_id = None
871
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
872
        if revision == None:
873
            revision = [None, None]
874
        elif isinstance(revision, int):
875
            revision = [revision, revision]
876
        else:
877
            # pair of revisions?
878
            pass
879
            
880
        assert len(revision) == 2
881
562 by Martin Pool
- bug fix for printing logs containing unicode
882
        mutter('encoding log as %r' % bzrlib.user_encoding)
610 by Martin Pool
- replace Branch.lock(mode) with separate lock_read and lock_write
883
884
        # use 'replace' so that we don't abort if trying to write out
885
        # in e.g. the default C locale.
886
        outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
562 by Martin Pool
- bug fix for printing logs containing unicode
887
527 by Martin Pool
- refactor log command
888
        show_log(b, file_id,
889
                 show_timezone=timezone,
890
                 verbose=verbose,
891
                 show_ids=show_ids,
562 by Martin Pool
- bug fix for printing logs containing unicode
892
                 to_file=outf,
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
893
                 direction=direction,
894
                 start_revision=revision[0],
895
                 end_revision=revision[1])
329 by Martin Pool
- refactor command functions into command classes
896
897
375 by Martin Pool
- New command touching-revisions and function to trace
898
899
class cmd_touching_revisions(Command):
523 by Martin Pool
doc
900
    """Return revision-ids which affected a particular file.
901
902
    A more user-friendly interface is "bzr log FILE"."""
375 by Martin Pool
- New command touching-revisions and function to trace
903
    hidden = True
904
    takes_args = ["filename"]
905
    def run(self, filename):
580 by Martin Pool
- Use explicit lock methods on a branch, rather than doing it
906
        b = Branch(filename)
375 by Martin Pool
- New command touching-revisions and function to trace
907
        inv = b.read_working_inventory()
908
        file_id = inv.path2id(b.relpath(filename))
909
        for revno, revision_id, what in bzrlib.log.find_touching_revisions(b, file_id):
910
            print "%6d %s" % (revno, what)
911
912
329 by Martin Pool
- refactor command functions into command classes
913
class cmd_ls(Command):
1 by mbp at sourcefrog
import from baz patch-364
914
    """List files in a tree.
915
254 by Martin Pool
- Doc cleanups from Magnus Therning
916
    TODO: Take a revision or remote path and list that tree instead.
1 by mbp at sourcefrog
import from baz patch-364
917
    """
329 by Martin Pool
- refactor command functions into command classes
918
    hidden = True
919
    def run(self, revision=None, verbose=False):
920
        b = Branch('.')
921
        if revision == None:
922
            tree = b.working_tree()
923
        else:
924
            tree = b.revision_tree(b.lookup_revision(revision))
925
926
        for fp, fc, kind, fid in tree.list_files():
927
            if verbose:
928
                if kind == 'directory':
929
                    kindch = '/'
930
                elif kind == 'file':
931
                    kindch = ''
932
                else:
933
                    kindch = '???'
934
935
                print '%-8s %s%s' % (fc, fp, kindch)
1 by mbp at sourcefrog
import from baz patch-364
936
            else:
329 by Martin Pool
- refactor command functions into command classes
937
                print fp
938
939
940
941
class cmd_unknowns(Command):
634 by Martin Pool
- Tidy help messages
942
    """List unknown files."""
329 by Martin Pool
- refactor command functions into command classes
943
    def run(self):
944
        for f in Branch('.').unknowns():
945
            print quotefn(f)
946
947
948
949
class cmd_ignore(Command):
634 by Martin Pool
- Tidy help messages
950
    """Ignore a command or pattern.
420 by Martin Pool
Doc
951
952
    To remove patterns from the ignore list, edit the .bzrignore file.
953
954
    If the pattern contains a slash, it is compared to the whole path
955
    from the branch root.  Otherwise, it is comapred to only the last
956
    component of the path.
957
958
    Ignore patterns are case-insensitive on case-insensitive systems.
959
960
    Note: wildcards must be quoted from the shell on Unix.
961
962
    examples:
963
        bzr ignore ./Makefile
964
        bzr ignore '*.class'
965
    """
329 by Martin Pool
- refactor command functions into command classes
966
    takes_args = ['name_pattern']
310 by Martin Pool
- new 'bzr ignored' command!
967
    
329 by Martin Pool
- refactor command functions into command classes
968
    def run(self, name_pattern):
409 by Martin Pool
- New AtomicFile class
969
        from bzrlib.atomicfile import AtomicFile
575 by Martin Pool
- cleanup imports
970
        import os.path
409 by Martin Pool
- New AtomicFile class
971
329 by Martin Pool
- refactor command functions into command classes
972
        b = Branch('.')
410 by Martin Pool
- Fix ignore command and add tests
973
        ifn = b.abspath('.bzrignore')
329 by Martin Pool
- refactor command functions into command classes
974
410 by Martin Pool
- Fix ignore command and add tests
975
        if os.path.exists(ifn):
498 by Martin Pool
bugfix for bzr ignore reported by ddaa:
976
            f = open(ifn, 'rt')
977
            try:
978
                igns = f.read().decode('utf-8')
979
            finally:
980
                f.close()
409 by Martin Pool
- New AtomicFile class
981
        else:
982
            igns = ''
983
575 by Martin Pool
- cleanup imports
984
        # TODO: If the file already uses crlf-style termination, maybe
985
        # we should use that for the newly added lines?
986
409 by Martin Pool
- New AtomicFile class
987
        if igns and igns[-1] != '\n':
988
            igns += '\n'
989
        igns += name_pattern + '\n'
990
498 by Martin Pool
bugfix for bzr ignore reported by ddaa:
991
        try:
992
            f = AtomicFile(ifn, 'wt')
993
            f.write(igns.encode('utf-8'))
994
            f.commit()
995
        finally:
996
            f.close()
329 by Martin Pool
- refactor command functions into command classes
997
998
        inv = b.working_tree().inventory
999
        if inv.path2id('.bzrignore'):
1000
            mutter('.bzrignore is already versioned')
1001
        else:
1002
            mutter('need to make new .bzrignore file versioned')
1003
            b.add(['.bzrignore'])
1004
1005
1006
1007
class cmd_ignored(Command):
421 by Martin Pool
doc
1008
    """List ignored files and the patterns that matched them.
1009
1010
    See also: bzr ignore"""
329 by Martin Pool
- refactor command functions into command classes
1011
    def run(self):
1012
        tree = Branch('.').working_tree()
1013
        for path, file_class, kind, file_id in tree.list_files():
1014
            if file_class != 'I':
1015
                continue
1016
            ## XXX: Slightly inefficient since this was already calculated
1017
            pat = tree.is_ignored(path)
1018
            print '%-50s %s' % (path, pat)
1019
1020
1021
class cmd_lookup_revision(Command):
1022
    """Lookup the revision-id from a revision-number
1023
1024
    example:
1025
        bzr lookup-revision 33
421 by Martin Pool
doc
1026
    """
329 by Martin Pool
- refactor command functions into command classes
1027
    hidden = True
338 by Martin Pool
- cleanup of some imports
1028
    takes_args = ['revno']
1029
    
329 by Martin Pool
- refactor command functions into command classes
1030
    def run(self, revno):
1031
        try:
1032
            revno = int(revno)
1033
        except ValueError:
338 by Martin Pool
- cleanup of some imports
1034
            raise BzrCommandError("not a valid revision-number: %r" % revno)
1035
1036
        print Branch('.').lookup_revision(revno)
329 by Martin Pool
- refactor command functions into command classes
1037
1038
1039
class cmd_export(Command):
1040
    """Export past revision to destination directory.
1041
678 by Martin Pool
- export to tarballs
1042
    If no revision is specified this exports the last committed revision.
1043
1044
    Format may be an "exporter" name, such as tar, tgz, tbz2.  If none is
1045
    given, exports to a directory (equivalent to --format=dir)."""
1046
    # TODO: list known exporters
329 by Martin Pool
- refactor command functions into command classes
1047
    takes_args = ['dest']
678 by Martin Pool
- export to tarballs
1048
    takes_options = ['revision', 'format']
1049
    def run(self, dest, revision=None, format='dir'):
329 by Martin Pool
- refactor command functions into command classes
1050
        b = Branch('.')
394 by Martin Pool
- Fix argument handling in export command
1051
        if revision == None:
1052
            rh = b.revision_history()[-1]
329 by Martin Pool
- refactor command functions into command classes
1053
        else:
394 by Martin Pool
- Fix argument handling in export command
1054
            rh = b.lookup_revision(int(revision))
329 by Martin Pool
- refactor command functions into command classes
1055
        t = b.revision_tree(rh)
678 by Martin Pool
- export to tarballs
1056
        t.export(dest, format)
329 by Martin Pool
- refactor command functions into command classes
1057
1058
1059
class cmd_cat(Command):
1060
    """Write a file's text from a previous revision."""
1061
1062
    takes_options = ['revision']
1063
    takes_args = ['filename']
1064
1065
    def run(self, filename, revision=None):
1066
        if revision == None:
1067
            raise BzrCommandError("bzr cat requires a revision number")
1068
        b = Branch('.')
1069
        b.print_file(b.relpath(filename), int(revision))
1070
1071
1072
class cmd_local_time_offset(Command):
1073
    """Show the offset in seconds from GMT to local time."""
1074
    hidden = True    
1075
    def run(self):
1076
        print bzrlib.osutils.local_time_offset()
1077
1078
1079
1080
class cmd_commit(Command):
1081
    """Commit changes into a new revision.
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
1082
491 by Martin Pool
- Selective commit!
1083
    If selected files are specified, only changes to those files are
1084
    committed.  If a directory is specified then its contents are also
1085
    committed.
1086
1087
    A selected-file commit may fail in some cases where the committed
1088
    tree would be invalid, such as trying to commit a file in a
1089
    newly-added directory that is not itself committed.
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
1090
1091
    TODO: Run hooks on tree to-be-committed, and after commit.
1092
1093
    TODO: Strict commit that fails if there are unknown or deleted files.
1094
    """
491 by Martin Pool
- Selective commit!
1095
    takes_args = ['selected*']
389 by Martin Pool
- new commit --file option!
1096
    takes_options = ['message', 'file', 'verbose']
350 by Martin Pool
- refactor command aliases into command classes
1097
    aliases = ['ci', 'checkin']
1098
505 by Martin Pool
- commit is verbose by default
1099
    def run(self, message=None, file=None, verbose=True, selected_list=None):
485 by Martin Pool
- move commit code into its own module
1100
        from bzrlib.commit import commit
1101
389 by Martin Pool
- new commit --file option!
1102
        ## Warning: shadows builtin file()
1103
        if not message and not file:
1104
            raise BzrCommandError("please specify a commit message",
1105
                                  ["use either --message or --file"])
1106
        elif message and file:
1107
            raise BzrCommandError("please specify either --message or --file")
1108
        
1109
        if file:
1110
            import codecs
1111
            message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1112
485 by Martin Pool
- move commit code into its own module
1113
        b = Branch('.')
491 by Martin Pool
- Selective commit!
1114
        commit(b, message, verbose=verbose, specific_files=selected_list)
329 by Martin Pool
- refactor command functions into command classes
1115
1116
1117
class cmd_check(Command):
1118
    """Validate consistency of branch history.
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
1119
1120
    This command checks various invariants about the branch storage to
1121
    detect data corruption or bzr bugs.
674 by Martin Pool
- check command now also checks new inventory_sha1 and
1122
1123
    If given the --update flag, it will update some optional fields
1124
    to help ensure data consistency.
232 by mbp at sourcefrog
Allow docstrings for help to be in PEP0257 format.
1125
    """
329 by Martin Pool
- refactor command functions into command classes
1126
    takes_args = ['dir?']
674 by Martin Pool
- check command now also checks new inventory_sha1 and
1127
703 by Martin Pool
- split out a new 'bzr upgrade' command separate from
1128
    def run(self, dir='.'):
329 by Martin Pool
- refactor command functions into command classes
1129
        import bzrlib.check
703 by Martin Pool
- split out a new 'bzr upgrade' command separate from
1130
        bzrlib.check.check(Branch(dir))
1131
1132
1133
1134
class cmd_upgrade(Command):
1135
    """Upgrade branch storage to current format.
1136
1137
    This should normally be used only after the check command tells
1138
    you to run it.
1139
    """
1140
    takes_args = ['dir?']
1141
1142
    def run(self, dir='.'):
1143
        from bzrlib.upgrade import upgrade
1144
        upgrade(Branch(dir))
329 by Martin Pool
- refactor command functions into command classes
1145
1146
1147
1148
class cmd_whoami(Command):
1149
    """Show bzr user id."""
1150
    takes_options = ['email']
286 by Martin Pool
- New bzr whoami --email option
1151
    
329 by Martin Pool
- refactor command functions into command classes
1152
    def run(self, email=False):
1153
        if email:
1154
            print bzrlib.osutils.user_email()
1155
        else:
1156
            print bzrlib.osutils.username()
1157
1158
1159
class cmd_selftest(Command):
55 by mbp at sourcefrog
bzr selftest shows some counts of tests
1160
    """Run internal test suite"""
329 by Martin Pool
- refactor command functions into command classes
1161
    hidden = True
1162
    def run(self):
608 by Martin Pool
- Split selftests out into a new module and start changing them
1163
        from bzrlib.selftest import selftest
723 by Martin Pool
- move whitebox/blackbox modules into bzrlib.selftest subdirectory
1164
        return int(not selftest())
329 by Martin Pool
- refactor command functions into command classes
1165
1166
1167
class cmd_version(Command):
634 by Martin Pool
- Tidy help messages
1168
    """Show version of bzr."""
329 by Martin Pool
- refactor command functions into command classes
1169
    def run(self):
1170
        show_version()
1171
1172
def show_version():
1173
    print "bzr (bazaar-ng) %s" % bzrlib.__version__
605 by Martin Pool
- patch from Lalo Martins to show version of bzr itself
1174
    # is bzrlib itself in a branch?
606 by Martin Pool
- new bzrlib.get_bzr_revision() tells about the history of
1175
    bzrrev = bzrlib.get_bzr_revision()
1176
    if bzrrev:
1177
        print "  (bzr checkout, revision %d {%s})" % bzrrev
329 by Martin Pool
- refactor command functions into command classes
1178
    print bzrlib.__copyright__
1179
    print "http://bazaar-ng.org/"
1180
    print
1181
    print "bzr comes with ABSOLUTELY NO WARRANTY.  bzr is free software, and"
1182
    print "you may use, modify and redistribute it under the terms of the GNU"
1183
    print "General Public License version 2 or later."
1184
1185
1186
class cmd_rocks(Command):
1187
    """Statement of optimism."""
1188
    hidden = True
1189
    def run(self):
1190
        print "it sure does!"
1191
493 by Martin Pool
- Merge aaron's merge command
1192
def parse_spec(spec):
622 by Martin Pool
Updated merge patch from Aaron
1193
    """
1194
    >>> parse_spec(None)
1195
    [None, None]
1196
    >>> parse_spec("./")
1197
    ['./', None]
1198
    >>> parse_spec("../@")
1199
    ['..', -1]
1200
    >>> parse_spec("../f/@35")
1201
    ['../f', 35]
1202
    """
1203
    if spec is None:
1204
        return [None, None]
493 by Martin Pool
- Merge aaron's merge command
1205
    if '/@' in spec:
1206
        parsed = spec.split('/@')
1207
        assert len(parsed) == 2
1208
        if parsed[1] == "":
1209
            parsed[1] = -1
1210
        else:
1211
            parsed[1] = int(parsed[1])
1212
            assert parsed[1] >=0
1213
    else:
1214
        parsed = [spec, None]
1215
    return parsed
1216
628 by Martin Pool
- merge aaron's updated merge/pull code
1217
1218
493 by Martin Pool
- Merge aaron's merge command
1219
class cmd_merge(Command):
622 by Martin Pool
Updated merge patch from Aaron
1220
    """Perform a three-way merge of trees.
1221
    
1222
    The SPEC parameters are working tree or revision specifiers.  Working trees
1223
    are specified using standard paths or urls.  No component of a directory
1224
    path may begin with '@'.
1225
    
1226
    Working tree examples: '.', '..', 'foo@', but NOT 'foo/@bar'
1227
1228
    Revisions are specified using a dirname/@revno pair, where dirname is the
1229
    branch directory and revno is the revision within that branch.  If no revno
1230
    is specified, the latest revision is used.
1231
1232
    Revision examples: './@127', 'foo/@', '../@1'
1233
1234
    The OTHER_SPEC parameter is required.  If the BASE_SPEC parameter is
1235
    not supplied, the common ancestor of OTHER_SPEC the current branch is used
1236
    as the BASE.
628 by Martin Pool
- merge aaron's updated merge/pull code
1237
1238
    merge refuses to run if there are any uncommitted changes, unless
1239
    --force is given.
622 by Martin Pool
Updated merge patch from Aaron
1240
    """
1241
    takes_args = ['other_spec', 'base_spec?']
628 by Martin Pool
- merge aaron's updated merge/pull code
1242
    takes_options = ['force']
622 by Martin Pool
Updated merge patch from Aaron
1243
628 by Martin Pool
- merge aaron's updated merge/pull code
1244
    def run(self, other_spec, base_spec=None, force=False):
591 by Martin Pool
- trim imports
1245
        from bzrlib.merge import merge
628 by Martin Pool
- merge aaron's updated merge/pull code
1246
        merge(parse_spec(other_spec), parse_spec(base_spec),
1247
              check_clean=(not force))
329 by Martin Pool
- refactor command functions into command classes
1248
622 by Martin Pool
Updated merge patch from Aaron
1249
1250
class cmd_revert(Command):
628 by Martin Pool
- merge aaron's updated merge/pull code
1251
    """Reverse all changes since the last commit.
1252
1253
    Only versioned files are affected.
1254
1255
    TODO: Store backups of any files that will be reverted, so
1256
          that the revert can be undone.          
622 by Martin Pool
Updated merge patch from Aaron
1257
    """
1258
    takes_options = ['revision']
1259
1260
    def run(self, revision=-1):
636 by Martin Pool
- fix missing import in revert
1261
        from bzrlib.merge import merge
628 by Martin Pool
- merge aaron's updated merge/pull code
1262
        merge(('.', revision), parse_spec('.'),
1263
              check_clean=False,
1264
              ignore_zero=True)
622 by Martin Pool
Updated merge patch from Aaron
1265
1266
329 by Martin Pool
- refactor command functions into command classes
1267
class cmd_assert_fail(Command):
1268
    """Test reporting of assertion failures"""
1269
    hidden = True
1270
    def run(self):
1271
        assert False, "always fails"
1272
1273
1274
class cmd_help(Command):
1275
    """Show help on a command or other topic.
1276
1277
    For a list of all available commands, say 'bzr help commands'."""
1278
    takes_args = ['topic?']
350 by Martin Pool
- refactor command aliases into command classes
1279
    aliases = ['?']
329 by Martin Pool
- refactor command functions into command classes
1280
    
1281
    def run(self, topic=None):
351 by Martin Pool
- Split out help functions into bzrlib.help
1282
        import help
1283
        help.help(topic)
1284
1 by mbp at sourcefrog
import from baz patch-364
1285
429 by Martin Pool
- New command update-stat-cache for testing
1286
class cmd_update_stat_cache(Command):
1287
    """Update stat-cache mapping inodes to SHA-1 hashes.
1288
1289
    For testing only."""
1290
    hidden = True
1291
    def run(self):
1292
        import statcache
1293
        b = Branch('.')
454 by Martin Pool
- fix update-stat-cache command
1294
        statcache.update_cache(b.base, b.read_working_inventory())
429 by Martin Pool
- New command update-stat-cache for testing
1295
1296
1 by mbp at sourcefrog
import from baz patch-364
1297
1298
# list of all available options; the rhs can be either None for an
1299
# option that takes no argument, or a constructor function that checks
1300
# the type.
1301
OPTIONS = {
1302
    'all':                    None,
571 by Martin Pool
- new --diff-options to pass options through to external
1303
    'diff-options':           str,
1 by mbp at sourcefrog
import from baz patch-364
1304
    'help':                   None,
389 by Martin Pool
- new commit --file option!
1305
    'file':                   unicode,
628 by Martin Pool
- merge aaron's updated merge/pull code
1306
    'force':                  None,
678 by Martin Pool
- export to tarballs
1307
    'format':                 unicode,
545 by Martin Pool
- --forward option for log
1308
    'forward':                None,
1 by mbp at sourcefrog
import from baz patch-364
1309
    'message':                unicode,
594 by Martin Pool
- add --no-recurse option for add command
1310
    'no-recurse':             None,
137 by mbp at sourcefrog
new --profile option
1311
    'profile':                None,
567 by Martin Pool
- New form 'bzr log -r FROM:TO'
1312
    'revision':               _parse_revision_str,
1 by mbp at sourcefrog
import from baz patch-364
1313
    'show-ids':               None,
12 by mbp at sourcefrog
new --timezone option for bzr log
1314
    'timezone':               str,
1 by mbp at sourcefrog
import from baz patch-364
1315
    'verbose':                None,
1316
    'version':                None,
286 by Martin Pool
- New bzr whoami --email option
1317
    'email':                  None,
674 by Martin Pool
- check command now also checks new inventory_sha1 and
1318
    'update':                 None,
1 by mbp at sourcefrog
import from baz patch-364
1319
    }
1320
1321
SHORT_OPTIONS = {
583 by Martin Pool
- add -h as short name for --help
1322
    'F':                      'file', 
1323
    'h':                      'help',
1 by mbp at sourcefrog
import from baz patch-364
1324
    'm':                      'message',
1325
    'r':                      'revision',
1326
    'v':                      'verbose',
1327
}
1328
1329
1330
def parse_args(argv):
1331
    """Parse command line.
1332
    
1333
    Arguments and options are parsed at this level before being passed
1334
    down to specific command handlers.  This routine knows, from a
1335
    lookup table, something about the available options, what optargs
1336
    they take, and which commands will accept them.
1337
31 by Martin Pool
fix up parse_args doctest
1338
    >>> parse_args('--help'.split())
1 by mbp at sourcefrog
import from baz patch-364
1339
    ([], {'help': True})
31 by Martin Pool
fix up parse_args doctest
1340
    >>> parse_args('--version'.split())
1 by mbp at sourcefrog
import from baz patch-364
1341
    ([], {'version': True})
31 by Martin Pool
fix up parse_args doctest
1342
    >>> parse_args('status --all'.split())
1 by mbp at sourcefrog
import from baz patch-364
1343
    (['status'], {'all': True})
31 by Martin Pool
fix up parse_args doctest
1344
    >>> parse_args('commit --message=biter'.split())
17 by mbp at sourcefrog
allow --option=ARG syntax
1345
    (['commit'], {'message': u'biter'})
683 by Martin Pool
- short option stacking patch from John A Meinel
1346
    >>> parse_args('log -r 500'.split())
1347
    (['log'], {'revision': 500})
1348
    >>> parse_args('log -r500:600'.split())
1349
    (['log'], {'revision': [500, 600]})
1350
    >>> parse_args('log -vr500:600'.split())
1351
    (['log'], {'verbose': True, 'revision': [500, 600]})
1352
    >>> parse_args('log -rv500:600'.split()) #the r takes an argument
1353
    Traceback (most recent call last):
1354
    ...
1355
    ValueError: invalid literal for int(): v500
1 by mbp at sourcefrog
import from baz patch-364
1356
    """
1357
    args = []
1358
    opts = {}
1359
1360
    # TODO: Maybe handle '--' to end options?
1361
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
1362
    while argv:
1363
        a = argv.pop(0)
1 by mbp at sourcefrog
import from baz patch-364
1364
        if a[0] == '-':
264 by Martin Pool
parse_args: option names must be ascii
1365
            # option names must not be unicode
1366
            a = str(a)
17 by mbp at sourcefrog
allow --option=ARG syntax
1367
            optarg = None
1 by mbp at sourcefrog
import from baz patch-364
1368
            if a[1] == '-':
1369
                mutter("  got option %r" % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
1370
                if '=' in a:
1371
                    optname, optarg = a[2:].split('=', 1)
1372
                else:
1373
                    optname = a[2:]
1 by mbp at sourcefrog
import from baz patch-364
1374
                if optname not in OPTIONS:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
1375
                    raise BzrError('unknown long option %r' % a)
1 by mbp at sourcefrog
import from baz patch-364
1376
            else:
1377
                shortopt = a[1:]
683 by Martin Pool
- short option stacking patch from John A Meinel
1378
                if shortopt in SHORT_OPTIONS:
1379
                    # Multi-character options must have a space to delimit
1380
                    # their value
1381
                    optname = SHORT_OPTIONS[shortopt]
1382
                else:
1383
                    # Single character short options, can be chained,
1384
                    # and have their value appended to their name
1385
                    shortopt = a[1:2]
1386
                    if shortopt not in SHORT_OPTIONS:
1387
                        # We didn't find the multi-character name, and we
1388
                        # didn't find the single char name
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
1389
                        raise BzrError('unknown short option %r' % a)
683 by Martin Pool
- short option stacking patch from John A Meinel
1390
                    optname = SHORT_OPTIONS[shortopt]
1391
1392
                    if a[2:]:
1393
                        # There are extra things on this option
1394
                        # see if it is the value, or if it is another
1395
                        # short option
1396
                        optargfn = OPTIONS[optname]
1397
                        if optargfn is None:
1398
                            # This option does not take an argument, so the
1399
                            # next entry is another short option, pack it back
1400
                            # into the list
1401
                            argv.insert(0, '-' + a[2:])
1402
                        else:
1403
                            # This option takes an argument, so pack it
1404
                            # into the array
1405
                            optarg = a[2:]
1 by mbp at sourcefrog
import from baz patch-364
1406
            
1407
            if optname in opts:
1408
                # XXX: Do we ever want to support this, e.g. for -r?
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
1409
                raise BzrError('repeated option %r' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
1410
                
1 by mbp at sourcefrog
import from baz patch-364
1411
            optargfn = OPTIONS[optname]
1412
            if optargfn:
17 by mbp at sourcefrog
allow --option=ARG syntax
1413
                if optarg == None:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
1414
                    if not argv:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
1415
                        raise BzrError('option %r needs an argument' % a)
17 by mbp at sourcefrog
allow --option=ARG syntax
1416
                    else:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
1417
                        optarg = argv.pop(0)
17 by mbp at sourcefrog
allow --option=ARG syntax
1418
                opts[optname] = optargfn(optarg)
1 by mbp at sourcefrog
import from baz patch-364
1419
            else:
17 by mbp at sourcefrog
allow --option=ARG syntax
1420
                if optarg != None:
694 by Martin Pool
- weed out all remaining calls to bailout() and remove the function
1421
                    raise BzrError('option %r takes no argument' % optname)
1 by mbp at sourcefrog
import from baz patch-364
1422
                opts[optname] = True
1423
        else:
1424
            args.append(a)
1425
1426
    return args, opts
1427
1428
1429
1430
329 by Martin Pool
- refactor command functions into command classes
1431
def _match_argform(cmd, takes_args, args):
1 by mbp at sourcefrog
import from baz patch-364
1432
    argdict = {}
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
1433
329 by Martin Pool
- refactor command functions into command classes
1434
    # step through args and takes_args, allowing appropriate 0-many matches
1435
    for ap in takes_args:
1 by mbp at sourcefrog
import from baz patch-364
1436
        argname = ap[:-1]
1437
        if ap[-1] == '?':
62 by mbp at sourcefrog
- new find_branch_root function; based on suggestion from aaron
1438
            if args:
1439
                argdict[argname] = args.pop(0)
196 by mbp at sourcefrog
selected-file diff
1440
        elif ap[-1] == '*': # all remaining arguments
1441
            if args:
1442
                argdict[argname + '_list'] = args[:]
1443
                args = []
1444
            else:
1445
                argdict[argname + '_list'] = None
1 by mbp at sourcefrog
import from baz patch-364
1446
        elif ap[-1] == '+':
1447
            if not args:
329 by Martin Pool
- refactor command functions into command classes
1448
                raise BzrCommandError("command %r needs one or more %s"
1 by mbp at sourcefrog
import from baz patch-364
1449
                        % (cmd, argname.upper()))
1450
            else:
1451
                argdict[argname + '_list'] = args[:]
1452
                args = []
160 by mbp at sourcefrog
- basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think
1453
        elif ap[-1] == '$': # all but one
1454
            if len(args) < 2:
329 by Martin Pool
- refactor command functions into command classes
1455
                raise BzrCommandError("command %r needs one or more %s"
160 by mbp at sourcefrog
- basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think
1456
                        % (cmd, argname.upper()))
1457
            argdict[argname + '_list'] = args[:-1]
1458
            args[:-1] = []                
1 by mbp at sourcefrog
import from baz patch-364
1459
        else:
1460
            # just a plain arg
1461
            argname = ap
1462
            if not args:
329 by Martin Pool
- refactor command functions into command classes
1463
                raise BzrCommandError("command %r requires argument %s"
1 by mbp at sourcefrog
import from baz patch-364
1464
                        % (cmd, argname.upper()))
1465
            else:
1466
                argdict[argname] = args.pop(0)
1467
            
1468
    if args:
329 by Martin Pool
- refactor command functions into command classes
1469
        raise BzrCommandError("extra argument to command %s: %s"
1470
                              % (cmd, args[0]))
1 by mbp at sourcefrog
import from baz patch-364
1471
1472
    return argdict
1473
1474
1475
1476
def run_bzr(argv):
1477
    """Execute a command.
1478
1479
    This is similar to main(), but without all the trappings for
245 by mbp at sourcefrog
- control files always in utf-8-unix format
1480
    logging and error handling.  
1 by mbp at sourcefrog
import from baz patch-364
1481
    """
251 by mbp at sourcefrog
- factor out locale.getpreferredencoding()
1482
    argv = [a.decode(bzrlib.user_encoding) for a in argv]
245 by mbp at sourcefrog
- control files always in utf-8-unix format
1483
    
641 by Martin Pool
- improved external-command patch from john
1484
    include_plugins=True
1 by mbp at sourcefrog
import from baz patch-364
1485
    try:
26 by mbp at sourcefrog
fix StopIteration error on python2.3(?)
1486
        args, opts = parse_args(argv[1:])
1 by mbp at sourcefrog
import from baz patch-364
1487
        if 'help' in opts:
351 by Martin Pool
- Split out help functions into bzrlib.help
1488
            import help
159 by mbp at sourcefrog
bzr commit --help now works
1489
            if args:
351 by Martin Pool
- Split out help functions into bzrlib.help
1490
                help.help(args[0])
159 by mbp at sourcefrog
bzr commit --help now works
1491
            else:
351 by Martin Pool
- Split out help functions into bzrlib.help
1492
                help.help()
1 by mbp at sourcefrog
import from baz patch-364
1493
            return 0
1494
        elif 'version' in opts:
336 by Martin Pool
- fix up 'bzr --version'
1495
            show_version()
1 by mbp at sourcefrog
import from baz patch-364
1496
            return 0
641 by Martin Pool
- improved external-command patch from john
1497
        elif args and args[0] == 'builtin':
1498
            include_plugins=False
1499
            args = args[1:]
265 by Martin Pool
parse_args: command names must also be ascii
1500
        cmd = str(args.pop(0))
1 by mbp at sourcefrog
import from baz patch-364
1501
    except IndexError:
448 by Martin Pool
- bzr with no command now shows help, not just an error
1502
        import help
1503
        help.help()
1 by mbp at sourcefrog
import from baz patch-364
1504
        return 1
448 by Martin Pool
- bzr with no command now shows help, not just an error
1505
          
115 by mbp at sourcefrog
todo
1506
641 by Martin Pool
- improved external-command patch from john
1507
    canonical_cmd, cmd_class = get_cmd_class(cmd,include_plugins=include_plugins)
1 by mbp at sourcefrog
import from baz patch-364
1508
137 by mbp at sourcefrog
new --profile option
1509
    # global option
1510
    if 'profile' in opts:
1511
        profile = True
1512
        del opts['profile']
1513
    else:
1514
        profile = False
1 by mbp at sourcefrog
import from baz patch-364
1515
1516
    # check options are reasonable
329 by Martin Pool
- refactor command functions into command classes
1517
    allowed = cmd_class.takes_options
1 by mbp at sourcefrog
import from baz patch-364
1518
    for oname in opts:
1519
        if oname not in allowed:
381 by Martin Pool
- Better message when a wrong argument is given
1520
            raise BzrCommandError("option '--%s' is not allowed for command %r"
329 by Martin Pool
- refactor command functions into command classes
1521
                                  % (oname, cmd))
176 by mbp at sourcefrog
New cat command contributed by janmar.
1522
137 by mbp at sourcefrog
new --profile option
1523
    # mix arguments and options into one dictionary
329 by Martin Pool
- refactor command functions into command classes
1524
    cmdargs = _match_argform(cmd, cmd_class.takes_args, args)
1525
    cmdopts = {}
136 by mbp at sourcefrog
new --show-ids option for 'deleted' command
1526
    for k, v in opts.items():
329 by Martin Pool
- refactor command functions into command classes
1527
        cmdopts[k.replace('-', '_')] = v
1 by mbp at sourcefrog
import from baz patch-364
1528
137 by mbp at sourcefrog
new --profile option
1529
    if profile:
338 by Martin Pool
- cleanup of some imports
1530
        import hotshot, tempfile
239 by mbp at sourcefrog
- remove profiler temporary file when done
1531
        pffileno, pfname = tempfile.mkstemp()
1532
        try:
1533
            prof = hotshot.Profile(pfname)
329 by Martin Pool
- refactor command functions into command classes
1534
            ret = prof.runcall(cmd_class, cmdopts, cmdargs) or 0
239 by mbp at sourcefrog
- remove profiler temporary file when done
1535
            prof.close()
1536
1537
            import hotshot.stats
1538
            stats = hotshot.stats.load(pfname)
1539
            #stats.strip_dirs()
1540
            stats.sort_stats('time')
1541
            ## XXX: Might like to write to stderr or the trace file instead but
1542
            ## print_stats seems hardcoded to stdout
1543
            stats.print_stats(20)
1544
            
337 by Martin Pool
- Clarify return codes from command objects
1545
            return ret.status
239 by mbp at sourcefrog
- remove profiler temporary file when done
1546
1547
        finally:
1548
            os.close(pffileno)
1549
            os.remove(pfname)
137 by mbp at sourcefrog
new --profile option
1550
    else:
500 by Martin Pool
- fix return value from run_bzr
1551
        return cmd_class(cmdopts, cmdargs).status 
1 by mbp at sourcefrog
import from baz patch-364
1552
1553
359 by Martin Pool
- pychecker fixups
1554
def _report_exception(summary, quiet=False):
267 by Martin Pool
- better reporting of errors
1555
    import traceback
1556
    log_error('bzr: ' + summary)
359 by Martin Pool
- pychecker fixups
1557
    bzrlib.trace.log_exception()
317 by Martin Pool
- better error message for broken pipe
1558
1559
    if not quiet:
1560
        tb = sys.exc_info()[2]
1561
        exinfo = traceback.extract_tb(tb)
1562
        if exinfo:
1563
            sys.stderr.write('  at %s:%d in %s()\n' % exinfo[-1][:3])
1564
        sys.stderr.write('  see ~/.bzr.log for debug information\n')
267 by Martin Pool
- better reporting of errors
1565
1566
1567
1 by mbp at sourcefrog
import from baz patch-364
1568
def main(argv):
317 by Martin Pool
- better error message for broken pipe
1569
    import errno
1570
    
344 by Martin Pool
- It's not an error to use the library without
1571
    bzrlib.open_tracefile(argv)
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1572
1 by mbp at sourcefrog
import from baz patch-364
1573
    try:
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1574
        try:
337 by Martin Pool
- Clarify return codes from command objects
1575
            try:
1576
                return run_bzr(argv)
1577
            finally:
1578
                # do this here inside the exception wrappers to catch EPIPE
1579
                sys.stdout.flush()
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1580
        except BzrError, e:
329 by Martin Pool
- refactor command functions into command classes
1581
            quiet = isinstance(e, (BzrCommandError))
359 by Martin Pool
- pychecker fixups
1582
            _report_exception('error: ' + e.args[0], quiet=quiet)
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1583
            if len(e.args) > 1:
1584
                for h in e.args[1]:
267 by Martin Pool
- better reporting of errors
1585
                    # some explanation or hints
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1586
                    log_error('  ' + h)
1587
            return 1
267 by Martin Pool
- better reporting of errors
1588
        except AssertionError, e:
1589
            msg = 'assertion failed'
1590
            if str(e):
1591
                msg += ': ' + str(e)
359 by Martin Pool
- pychecker fixups
1592
            _report_exception(msg)
318 by Martin Pool
- better error message for Ctrl-c
1593
            return 2
1594
        except KeyboardInterrupt, e:
359 by Martin Pool
- pychecker fixups
1595
            _report_exception('interrupted', quiet=True)
318 by Martin Pool
- better error message for Ctrl-c
1596
            return 2
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1597
        except Exception, e:
317 by Martin Pool
- better error message for broken pipe
1598
            quiet = False
419 by Martin Pool
- RemoteBranch.__str__ and repr
1599
            if (isinstance(e, IOError) 
1600
                and hasattr(e, 'errno')
1601
                and e.errno == errno.EPIPE):
317 by Martin Pool
- better error message for broken pipe
1602
                quiet = True
1603
                msg = 'broken pipe'
1604
            else:
1605
                msg = str(e).rstrip('\n')
359 by Martin Pool
- pychecker fixups
1606
            _report_exception(msg, quiet)
318 by Martin Pool
- better error message for Ctrl-c
1607
            return 2
260 by Martin Pool
- remove atexit() dependency for writing out execution times
1608
    finally:
1609
        bzrlib.trace.close_trace()
1 by mbp at sourcefrog
import from baz patch-364
1610
1611
1612
if __name__ == '__main__':
1613
    sys.exit(main(sys.argv))