~abentley/bzrtools/bzrtools.dev

246 by Aaron Bentley
Merged shelf_v2
1
"""\
2
Various useful plugins for working with bzr.
3
"""
428 by Aaron Bentley
Add version number, check against bzrlib version
4
5
import bzrlib
6
7
429 by Aaron Bentley
Update version number to 0.10.0
8
__version__ = '0.10.0'
428 by Aaron Bentley
Add version number, check against bzrlib version
9
10
11
version_info = tuple(int(n) for n in __version__.split('.'))
12
13
14
def check_bzrlib_version(desired):
15
    """Check that bzrlib is compatible.
16
17
    If version is < bzrtools version, assume incompatible.
18
    If version == bzrtools version, assume completely compatible
19
    If version == bzrtools version + 1, assume compatible, with deprecations
20
    Otherwise, assume incompatible.
21
    """
22
    desired_plus = (desired[0], desired[1]+1)
23
    bzrlib_version = bzrlib.version_info[:2]
24
    if bzrlib_version == desired:
25
        return
26
    try:
27
        from bzrlib.trace import warning
28
    except ImportError:
29
        # get the message out any way we can
30
        from warnings import warn as warning
31
    if bzrlib_version < desired:
32
        warning('Installed bzr version %s is too old to be used with bzrtools'
33
                ' %s.' % (bzrlib.__version__, __version__))
34
        # Not using BzrNewError, because it may not exist.
35
        raise Exception, 'Version mismatch', version_info
36
    else:
37
        warning('Bzrtools is not up to date with installed bzr version'
38
                ' %s. Please upgrade to bzrtools %i.%i.' 
39
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
40
        if bzrlib_version != desired_plus:
41
            raise Exception, 'Version mismatch'
42
43
44
check_bzrlib_version(version_info[:2])
45
46
364.1.4 by Aaron Bentley
Changed rpush to rspush
47
import rspush
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
48
from errors import CommandError
49
from patchsource import BzrPatchSource
246 by Aaron Bentley
Merged shelf_v2
50
from shelf import Shelf
360.1.1 by Aaron Bentley
Add switch command
51
from switch import cmd_switch
246 by Aaron Bentley
Merged shelf_v2
52
import sys
53
import os.path
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
54
55
import bzrlib.builtins
0.1.22 by Michael Ellerman
Add __init__.py, put cmd_shelve/unshelve in there.
56
import bzrlib.branch
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
57
import bzrlib.commands
410 by Aaron Bentley
Ensure the option settings come from the right 'diff' in colordiff
58
from bzrlib.commands import get_cmd_object
0.1.39 by Michael Ellerman
Fix shelve and unshelve to pass location to Shelf().
59
from bzrlib.errors import BzrCommandError
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
60
from bzrlib.help import command_usage
423 by Aaron Bentley
Add runtime ignores for shelf
61
import bzrlib.ignores
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
62
from bzrlib.option import Option
147.1.41 by Aaron Bentley
Merge from mainline
63
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), 
147.4.37 by Robert Collins
Convert push to rpush.
64
                                                 "external")))
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
65
0.7.2 by Michael Ellerman
Convert from DEFAULT_IGNORES to bzrlib.ignores.add_runtime_ignores().
66
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
67
246 by Aaron Bentley
Merged shelf_v2
68
69
class cmd_clean_tree(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
70
    """Remove unwanted files from working tree.
417 by Aaron Bentley
Update clean-tree docs
71
72
    By default, only unknown files, not ignored files, are deleted.  Versioned
73
    files are never deleted.
74
75
    Another class is 'detritus', which includes files emitted by bzr during
76
    normal operations and selftests.  (The value of these files decreases with
77
    time.)
78
79
    If no options are specified, unknown files are deleted.  Otherwise, option
80
    flags are respected, and may be combined.
81
82
    To check what clean-tree will do, use --dry-run.
246 by Aaron Bentley
Merged shelf_v2
83
    """
386 by Aaron Bentley
Stop adding global options
84
    takes_options = [Option('ignored', help='delete all ignored files.'), 
417 by Aaron Bentley
Update clean-tree docs
85
                     Option('detritus', help='delete conflict files, merge'
86
                            ' backups, and failed selftest dirs.'), 
416 by Aaron Bentley
clean-tree --detritus no longer implies --unknown
87
                     Option('unknown', 
88
                            help='delete files unknown to bzr.  (default)'),
386 by Aaron Bentley
Stop adding global options
89
                     Option('dry-run', help='show files to delete instead of'
90
                            ' deleting them.')]
415.1.1 by Adeodato Simó
Make clean-tree --detritus or --ignored not delete also unknown files,
91
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False):
246 by Aaron Bentley
Merged shelf_v2
92
        from clean_tree import clean_tree
415.1.1 by Adeodato Simó
Make clean-tree --detritus or --ignored not delete also unknown files,
93
        if not (unknown or ignored or detritus):
94
            unknown = True
416 by Aaron Bentley
clean-tree --detritus no longer implies --unknown
95
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus, 
96
                   dry_run=dry_run)
246 by Aaron Bentley
Merged shelf_v2
97
98
class cmd_graph_ancestry(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
99
    """Produce ancestry graphs using dot.
246 by Aaron Bentley
Merged shelf_v2
100
    
101
    Output format is detected according to file extension.  Some of the more
296 by Aaron Bentley
Updated graph-ancestry help
102
    common output formats are html, png, gif, svg, ps.  An extension of '.dot'
103
    will cause a dot graph file to be produced.  HTML output has mouseovers
104
    that show the commit message.
246 by Aaron Bentley
Merged shelf_v2
105
106
    Branches are labeled r?, where ? is the revno.  If they have no revno,
107
    with the last 5 characters of their revision identifier are used instead.
296 by Aaron Bentley
Updated graph-ancestry help
108
109
    The value starting with d is "(maximum) distance from the null revision".
246 by Aaron Bentley
Merged shelf_v2
110
    
111
    If --merge-branch is specified, the two branches are compared and a merge
112
    base is selected.
113
    
114
    Legend:
115
    white    normal revision
116
    yellow   THIS  history
117
    red      OTHER history
118
    orange   COMMON history
119
    blue     COMMON non-history ancestor
296 by Aaron Bentley
Updated graph-ancestry help
120
    green    Merge base (COMMON ancestor farthest from the null revision)
121
    dotted   Ghost revision (missing from branch storage)
246 by Aaron Bentley
Merged shelf_v2
122
296 by Aaron Bentley
Updated graph-ancestry help
123
    Ancestry is usually collapsed by skipping revisions with a single parent
246 by Aaron Bentley
Merged shelf_v2
124
    and descendant.  The number of skipped revisions is shown on the arrow.
125
    This feature can be disabled with --no-collapse.
126
127
    By default, revisions are ordered by distance from root, but they can be
128
    clustered instead using --cluster.
129
130
    If available, rsvg is used to antialias PNG and JPEG output, but this can
131
    be disabled with --no-antialias.
132
    """
133
    takes_args = ['branch', 'file']
296 by Aaron Bentley
Updated graph-ancestry help
134
    takes_options = [Option('no-collapse', help="Do not skip simple nodes"), 
135
                     Option('no-antialias',
136
                     help="Do not use rsvg to produce antialiased output"), 
137
                     Option('merge-branch', type=str, 
138
                     help="Use this branch to calcuate a merge base"), 
139
                     Option('cluster', help="Use clustered output.")]
246 by Aaron Bentley
Merged shelf_v2
140
    def run(self, branch, file, no_collapse=False, no_antialias=False,
141
        merge_branch=None, cluster=False):
142
        import graph
143
        if cluster:
144
            ranking = "cluster"
145
        else:
146
            ranking = "forced"
147
        graph.write_ancestry_file(branch, file, not no_collapse, 
148
                                  not no_antialias, merge_branch, ranking)
149
150
class cmd_fetch_ghosts(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
151
    """Attempt to retrieve ghosts from another branch.
246 by Aaron Bentley
Merged shelf_v2
152
    If the other branch is not supplied, the last-pulled branch is used.
153
    """
154
    aliases = ['fetch-missing']
155
    takes_args = ['branch?']
275.1.3 by Daniel Silverstone
Fix up fetch_ghosts to lock the branches, and to invoke bzr fix if it fetches any ghosts into the tree
156
    takes_options = [Option('no-fix')]
157
    def run(self, branch=None, no_fix=False):
246 by Aaron Bentley
Merged shelf_v2
158
        from fetch_ghosts import fetch_ghosts
275.1.3 by Daniel Silverstone
Fix up fetch_ghosts to lock the branches, and to invoke bzr fix if it fetches any ghosts into the tree
159
        fetch_ghosts(branch, no_fix)
246 by Aaron Bentley
Merged shelf_v2
160
161
strip_help="""Strip the smallest prefix containing num leading slashes  from \
162
each file name found in the patch file."""
321.2.1 by ghigo
add support for bazaar diff
163
Option.OPTIONS['bzrdiff'] = Option('bzrdiff',type=None,
164
                                help="""Handle extra bzr tags""")
246 by Aaron Bentley
Merged shelf_v2
165
class cmd_patch(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
166
    """Apply a named patch to the current tree.
246 by Aaron Bentley
Merged shelf_v2
167
    """
168
    takes_args = ['filename?']
386 by Aaron Bentley
Stop adding global options
169
    takes_options = [Option('strip', type=int, help=strip_help)]
321.2.1 by ghigo
add support for bazaar diff
170
    def run(self, filename=None, strip=-1, bzrdiff=0):
246 by Aaron Bentley
Merged shelf_v2
171
        from patch import patch
340 by Aaron Bentley
Fixed patch on checkouts
172
        from bzrlib.workingtree import WorkingTree
173
        wt = WorkingTree.open_containing('.')[0]
321.2.1 by ghigo
add support for bazaar diff
174
        if strip == -1:
175
            if bzrdiff: strip = 0
369 by Aaron Bentley
Treat patches as p0 by default
176
            else:       strip = 0
321.2.1 by ghigo
add support for bazaar diff
177
340 by Aaron Bentley
Fixed patch on checkouts
178
        return patch(wt, filename, strip, legacy= not bzrdiff)
246 by Aaron Bentley
Merged shelf_v2
179
427 by Aaron Bentley
Merge latest changes from Shelf
180
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
181
class cmd_shelve(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
182
    """Temporarily set aside some changes from the current tree.
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
183
184
    Shelve allows you to temporarily put changes you've made "on the shelf",
185
    ie. out of the way, until a later time when you can bring them back from
186
    the shelf with the 'unshelve' command.
187
289 by Aaron Bentley
Updated shelf help
188
    Shelve is intended to help separate several sets of text changes that have
189
    been inappropriately mingled.  If you just want to get rid of all changes
190
    (text and otherwise) and you don't need to restore them later, use revert.
191
    If you want to shelve all text changes at once, use shelve --all.
192
0.1.90 by Michael Ellerman
Update help text to try and be clearer, some stolen from bzrtools.
193
    By default shelve asks you what you want to shelve, press '?' at the
194
    prompt to get help. To shelve everything run shelve --all.
195
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
196
    If filenames are specified, only the changes to those files will be
197
    shelved, other files will be left untouched.
198
199
    If a revision is specified, changes since that revision will be shelved.
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
200
201
    You can put multiple items on the shelf. Normally each time you run
202
    unshelve the most recently shelved changes will be reinstated. However,
203
    you can also unshelve changes in a different order by explicitly
204
    specifiying which changes to unshelve. This works best when the changes
205
    don't depend on each other.
0.7.3 by Michael Ellerman
Add a reference from 'shelve' help to 'shelf'.
206
207
    While you have patches on the shelf you can view and manipulate them with
208
    the 'shelf' command. Run 'bzr shelf -h' for more info.
0.1.90 by Michael Ellerman
Update help text to try and be clearer, some stolen from bzrtools.
209
    """
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
210
211
    takes_args = ['file*']
0.1.90 by Michael Ellerman
Update help text to try and be clearer, some stolen from bzrtools.
212
    takes_options = ['message', 'revision',
423.1.4 by Aaron Bentley
Add --no-color option to shelf
213
            Option('all', help='Shelve all changes without prompting'), 
214
            Option('no-color', help='Never display changes in color')]
0.1.90 by Michael Ellerman
Update help text to try and be clearer, some stolen from bzrtools.
215
423.1.4 by Aaron Bentley
Add --no-color option to shelf
216
    def run(self, all=False, file_list=None, message=None, revision=None,
217
            no_color=False):
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
218
        if revision is not None and revision:
219
            if len(revision) == 1:
220
                revision = revision[0]
221
            else:
222
                raise CommandError("shelve only accepts a single revision "
223
                                  "parameter.")
224
225
        source = BzrPatchSource(revision, file_list)
0.1.74 by Michael Ellerman
Adapt to BzrDir changes and deprecation of show_diff().
226
        s = Shelf(source.base)
423.1.4 by Aaron Bentley
Add --no-color option to shelf
227
        s.shelve(source, all, message, no_color)
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
228
        return 0
229
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
230
231
# The following classes are only used as subcommands for 'shelf', they're
232
# not to be registered directly with bzr.
233
234
class cmd_shelf_list(bzrlib.commands.Command):
235
    """List the patches on the current shelf."""
236
    aliases = ['list', 'ls']
237
    def run(self):
238
        self.shelf.list()
239
240
241
class cmd_shelf_delete(bzrlib.commands.Command):
242
    """Delete the patch from the current shelf."""
243
    aliases = ['delete', 'del']
244
    takes_args = ['patch']
245
    def run(self, patch):
246
        self.shelf.delete(patch)
247
248
249
class cmd_shelf_switch(bzrlib.commands.Command):
250
    """Switch to the other shelf, create it if necessary."""
251
    aliases = ['switch']
0.1.117 by Michael Ellerman
Arg names with hyphens don't seem to work (broke shelf switch).
252
    takes_args = ['othershelf']
253
    def run(self, othershelf):
254
        s = Shelf(self.shelf.base, othershelf)
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
255
        s.make_default()
256
257
258
class cmd_shelf_show(bzrlib.commands.Command):
0.1.110 by Michael Ellerman
Make the patch argument to 'shelf show' optional.
259
    """Show the contents of the specified or topmost patch."""
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
260
    aliases = ['show', 'cat', 'display']
0.1.110 by Michael Ellerman
Make the patch argument to 'shelf show' optional.
261
    takes_args = ['patch?']
262
    def run(self, patch=None):
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
263
        self.shelf.display(patch)
264
265
266
class cmd_shelf_upgrade(bzrlib.commands.Command):
267
    """Upgrade old format shelves."""
268
    aliases = ['upgrade']
269
    def run(self):
270
        self.shelf.upgrade()
271
272
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
273
class cmd_shelf(bzrlib.commands.Command):
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
274
    """Perform various operations on your shelved patches. See also shelve."""
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
275
    takes_args = ['subcommand', 'args*']
276
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
277
    subcommands = [cmd_shelf_list, cmd_shelf_delete, cmd_shelf_switch,
278
        cmd_shelf_show, cmd_shelf_upgrade]
279
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
280
    def run(self, subcommand, args_list):
281
        import sys
282
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
283
        cmd = self._get_cmd_object(subcommand)
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
284
        source = BzrPatchSource()
0.1.74 by Michael Ellerman
Adapt to BzrDir changes and deprecation of show_diff().
285
        s = Shelf(source.base)
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
286
        cmd.shelf = s
287
        return cmd.run_argv_aliases(args_list)
288
289
    def _get_cmd_object(self, cmd_name):
290
        for cmd_class in self.subcommands:
291
            for alias in cmd_class.aliases:
292
                if alias == cmd_name:
293
                    return cmd_class()
294
        raise CommandError("Unknown shelf subcommand '%s'" % cmd_name)
295
296
    def help(self):
0.1.111 by Michael Ellerman
Make help for subcommands more readable, print options in help also.
297
        text = ["%s\n\nSubcommands:\n" % self.__doc__]
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
298
299
        for cmd_class in self.subcommands:
0.1.111 by Michael Ellerman
Make help for subcommands more readable, print options in help also.
300
            text.extend(self.sub_help(cmd_class) + ['\n'])
301
302
        return ''.join(text)
303
304
    def sub_help(self, cmd_class):
305
        text = []
306
        cmd_obj = cmd_class()
307
        indent = 2 * ' '
308
309
        usage = command_usage(cmd_obj)
310
        usage = usage.replace('bzr shelf-', '')
311
        text.append('%s%s\n' % (indent, usage))
312
313
        text.append('%s%s\n' % (2 * indent, cmd_class.__doc__))
314
315
        # Somewhat copied from bzrlib.help.help_on_command_options
316
        option_help = []
317
        for option_name, option in sorted(cmd_obj.options().items()):
318
            if option_name == 'help':
319
                continue
320
            option_help.append('%s--%s' % (3 * indent, option_name))
321
            if option.type is not None:
322
                option_help.append(' %s' % option.argname.upper())
323
            if option.short_name():
324
                option_help.append(', -%s' % option.short_name())
325
            option_help.append('%s%s\n' % (2 * indent, option.help))
326
327
        if len(option_help) > 0:
328
            text.append('%soptions:\n' % (2 * indent))
329
            text.extend(option_help)
330
331
        return text
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
332
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
333
246 by Aaron Bentley
Merged shelf_v2
334
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
335
class cmd_unshelve(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
336
    """Restore shelved changes.
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
337
338
    By default the most recently shelved changes are restored. However if you
339
    specify a patch by name those changes will be restored instead.
340
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
341
    See 'shelve' for more information.
342
    """
0.1.91 by Michael Ellerman
Add --force option to unshelve, which runs the shelved changes through
343
    takes_options = [
344
            Option('all', help='Unshelve all changes without prompting'),
345
            Option('force', help='Force unshelving even if errors occur'),
423.1.4 by Aaron Bentley
Add --no-color option to shelf
346
            Option('no-color', help='Never display changes in color')
347
        ]
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
348
    takes_args = ['patch?']
423.1.4 by Aaron Bentley
Add --no-color option to shelf
349
    def run(self, patch=None, all=False, force=False, no_color=False):
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
350
        source = BzrPatchSource()
0.1.74 by Michael Ellerman
Adapt to BzrDir changes and deprecation of show_diff().
351
        s = Shelf(source.base)
423.1.4 by Aaron Bentley
Add --no-color option to shelf
352
        s.unshelve(source, patch, all, force, no_color)
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
353
        return 0
354
0.1.22 by Michael Ellerman
Add __init__.py, put cmd_shelve/unshelve in there.
355
249 by Aaron Bentley
Got the shell basics working properly
356
class cmd_shell(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
357
    """Begin an interactive shell tailored for bzr.
287 by Aaron Bentley
Added shell docstring
358
    Bzr commands can be used without typing bzr first, and will be run natively
359
    when possible.  Tab completion is tailored for bzr.  The shell prompt shows
360
    the branch nick, revno, and path.
361
362
    If it encounters any moderately complicated shell command, it will punt to
363
    the system shell.
364
365
    Example:
366
    $ bzr shell
367
    bzr bzrtools:287/> status
368
    modified:
369
      __init__.py
370
    bzr bzrtools:287/> status --[TAB][TAB]
371
    --all        --help       --revision   --show-ids
372
    bzr bzrtools:287/> status --
373
    """
249 by Aaron Bentley
Got the shell basics working properly
374
    def run(self):
375
        import shell
281 by Aaron Bentley
Handled whitespace branch names better
376
        return shell.run_shell()
246 by Aaron Bentley
Merged shelf_v2
377
292 by Aaron Bentley
Introduced branch-history command
378
class cmd_branch_history(bzrlib.commands.Command):
379
    """\
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
380
    Display the development history of a branch.
292 by Aaron Bentley
Introduced branch-history command
381
293 by Aaron Bentley
Updated help
382
    Each different committer or branch nick is considered a different line of
383
    development.  Committers are treated as the same if they have the same
384
    name, or if they have the same email address.
292 by Aaron Bentley
Introduced branch-history command
385
    """
386
    takes_args = ["branch?"]
387
    def run(self, branch=None):
388
        from branchhistory import branch_history 
389
        return branch_history(branch)
390
345 by Aaron Bentley
Added zap command
391
392
class cmd_zap(bzrlib.commands.Command):
393
    """\
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
394
    Remove a lightweight checkout, if it can be done safely.
411 by Aaron Bentley
Update zap documentation
395
396
    This command will remove a lightweight checkout without losing data.  That
397
    means it only removes lightweight checkouts, and only if they have no
398
    uncommitted changes.
399
400
    If --branch is specified, the branch will be deleted too, but only if the
401
    the branch has no new commits (relative to its parent).
345 by Aaron Bentley
Added zap command
402
    """
355.1.1 by Aaron Bentley
Provided --branch option to for zapping branches
403
    takes_options = [Option("branch", help="Remove associtated branch from"
404
                                           " repository")]
345 by Aaron Bentley
Added zap command
405
    takes_args = ["checkout"]
355.1.1 by Aaron Bentley
Provided --branch option to for zapping branches
406
    def run(self, checkout, branch=False):
345 by Aaron Bentley
Added zap command
407
        from zap import zap
355.1.1 by Aaron Bentley
Provided --branch option to for zapping branches
408
        return zap(checkout, remove_branch=branch)
345 by Aaron Bentley
Added zap command
409
410
349 by Aaron Bentley
Added cbranch command
411
class cmd_cbranch(bzrlib.commands.Command):
412
    """
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
413
    Create a new checkout, associated with a new repository branch.
349 by Aaron Bentley
Added cbranch command
414
    
415
    When you cbranch, bzr looks up the repository associated with your current
416
    directory in branches.conf.  It creates a new branch in that repository
417
    with the same name and relative path as the checkout you request.
351 by Aaron Bentley
Improved cbranch docs
418
419
    The branches.conf parameter is "cbranch_root".  So if you want 
420
    cbranch operations in /home/jrandom/bigproject to produce branches in 
421
    /home/jrandom/bigproject/repository, you'd add this:
422
423
    [/home/jrandom/bigproject]
424
    cbranch_root = /home/jrandom/bigproject/repository
425
426
    Note that if "/home/jrandom/bigproject/repository" isn't a repository,
427
    standalone branches will be produced.  Standalone branches will also
428
    be produced if the source branch is in 0.7 format (or earlier).
349 by Aaron Bentley
Added cbranch command
429
    """
355.1.2 by Aaron Bentley
cbranch mimics checkout wrt --lightweight
430
    takes_options = [Option("lightweight", 
418 by Aaron Bentley
Cbranch takes a revision option
431
                            help="Create a lightweight checkout"), 'revision']
355.1.2 by Aaron Bentley
cbranch mimics checkout wrt --lightweight
432
    takes_args = ["source", "target?"]
418 by Aaron Bentley
Cbranch takes a revision option
433
    def run(self, source, target=None, lightweight=False, revision=None):
349 by Aaron Bentley
Added cbranch command
434
        from cbranch import cbranch
418 by Aaron Bentley
Cbranch takes a revision option
435
        return cbranch(source, target, lightweight=lightweight, 
436
                       revision=revision)
355.1.2 by Aaron Bentley
cbranch mimics checkout wrt --lightweight
437
349 by Aaron Bentley
Added cbranch command
438
352 by Aaron Bentley
Added branches subcommand
439
class cmd_branches(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
440
    """Scan a location for branches"""
352 by Aaron Bentley
Added branches subcommand
441
    takes_args = ["location?"]
442
    def run(self, location=None):
443
        from branches import branches
444
        return branches(location)
445
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
446
447
class cmd_multi_pull(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
448
    """Pull all the branches under a location, e.g. a repository.
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
449
    
450
    Both branches present in the directory and the branches of checkouts are
451
    pulled.
452
    """
453
    takes_args = ["location?"]
454
    def run(self, location=None):
455
        from bzrlib.branch import Branch
456
        from bzrlib.transport import get_transport
457
        from bzrtools import iter_branch_tree
458
        if location is None:
459
            location = '.'
460
        t = get_transport(location)
461
        if not t.listable():
462
            print "Can't list this type of location."
463
            return 3
464
        for branch, wt in iter_branch_tree(t):
465
            if wt is None:
466
                pullable = branch
467
            else:
468
                pullable = wt
469
            parent = branch.get_parent()
470
            if parent is None:
471
                continue
472
            if wt is not None:
473
                base = wt.basedir
474
            else:
475
                base = branch.base
476
            if base.startswith(t.base):
477
                relpath = base[len(t.base):].rstrip('/')
478
            else:
479
                relpath = base
480
            print "Pulling %s from %s" % (relpath, parent)
481
            try:
482
                pullable.pull(Branch.open(parent))
483
            except Exception, e:
484
                print e
485
486
360.1.3 by Aaron Bentley
Add experimental branch-mark command
487
class cmd_branch_mark(bzrlib.commands.Command):
488
    """
489
    Add, view or list branch markers <EXPERIMENTAL>
490
491
    To add a mark, do 'bzr branch-mark MARK'.
492
    To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
493
    repository).
494
    To delete a mark, do 'bzr branch-mark --delete MARK'
495
496
    These marks can be used to track a branch's status.
497
    """
498
    takes_args = ['mark?', 'branch?']
499
    takes_options = [Option('delete', help='Delete this mark')]
500
    def run(self, mark=None, branch=None, delete=False):
501
        from branch_mark import branch_mark
502
        branch_mark(mark, branch, delete)
503
377 by Aaron Bentley
Got import command working
504
class cmd_import(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
505
    """Import sources from a tarball
380 by Aaron Bentley
Got import working decently
506
    
507
    This command will import a tarball into a bzr tree, replacing any versioned
508
    files already present.  If a directory is specified, it is used as the
509
    target.  If the directory does not exist, or is not versioned, it is
510
    created.
511
512
    Tarballs may be gzip or bzip2 compressed.  This is autodetected.
513
514
    If the tarball has a single root directory, that directory is stripped
515
    when extracting the tarball.
516
    """
517
    
518
    takes_args = ['source', 'tree?']
519
    def run(self, source, tree=None):
377 by Aaron Bentley
Got import command working
520
        from upstream_import import do_import
380 by Aaron Bentley
Got import working decently
521
        do_import(source, tree)
377 by Aaron Bentley
Got import command working
522
392.1.1 by Aaron Bentley
Implement 'shove' for moving changes to other trees
523
class cmd_shove(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
524
    """Apply uncommitted changes to another tree
392.1.1 by Aaron Bentley
Implement 'shove' for moving changes to other trees
525
    
526
    This is useful when you start to make changes in one tree, then realize
527
    they should really be done in a different tree.
528
529
    Shove is implemented using merge, so:
530
     - All changes, including renames and adds, will be applied.
531
     - No changes that have already been applied will be applied.
532
     - If the target is significantly different from the source, conflicts may
533
       be produced.
534
    """
535
408 by Aaron Bentley
Revert shove to previous argument order
536
    takes_args = ['target', 'source?']
392.1.1 by Aaron Bentley
Implement 'shove' for moving changes to other trees
537
    def run(self, target, source='.'):
538
        from shove import do_shove
539
        do_shove(source, target)
540
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
541
class cmd_cdiff(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
542
    """A color version of bzr's diff"""
410 by Aaron Bentley
Ensure the option settings come from the right 'diff' in colordiff
543
    takes_args = property(lambda x: get_cmd_object('diff').takes_args)
544
    takes_options = property(lambda x: get_cmd_object('diff').takes_options)
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
545
    def run(*args, **kwargs):
546
        from colordiff import colordiff
547
        colordiff(*args, **kwargs)
360.1.3 by Aaron Bentley
Add experimental branch-mark command
548
391 by Aaron Bentley
Updates from the bzr clean-tree branch
549
commands = [cmd_shelve, cmd_unshelve, cmd_shelf, cmd_clean_tree,
550
            cmd_graph_ancestry, cmd_fetch_ghosts, cmd_patch, cmd_shell,
551
            cmd_branch_history, cmd_zap, cmd_cbranch, cmd_branches, 
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
552
            cmd_multi_pull, cmd_switch, cmd_branch_mark, cmd_import, cmd_shove,
553
            cmd_cdiff]
554
555
364.1.4 by Aaron Bentley
Changed rpush to rspush
556
commands.append(rspush.cmd_rspush)
246 by Aaron Bentley
Merged shelf_v2
557
558
from errors import NoPyBaz
559
try:
560
    import baz_import
147.1.41 by Aaron Bentley
Merge from mainline
561
    commands.append(baz_import.cmd_baz_import_branch)
246 by Aaron Bentley
Merged shelf_v2
562
    commands.append(baz_import.cmd_baz_import)
563
564
except NoPyBaz:
147.1.72 by Aaron Bentley
Handle missing pybaz properly
565
    class cmd_baz_import_branch(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
566
        """Disabled. (Requires PyBaz)"""
147.1.72 by Aaron Bentley
Handle missing pybaz properly
567
        takes_args = ['to_location?', 'from_branch?', 'reuse_history*']
568
        takes_options = ['verbose', Option('max-count', type=int)]
569
        def run(self, to_location=None, from_branch=None, fast=False, 
570
                max_count=None, verbose=False, dry_run=False,
571
                reuse_history_list=[]):
572
            print "This command is disabled.  Please install PyBaz."
573
574
246 by Aaron Bentley
Merged shelf_v2
575
    class cmd_baz_import(bzrlib.commands.Command):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
576
        """Disabled. (Requires PyBaz)"""
147.1.72 by Aaron Bentley
Handle missing pybaz properly
577
        takes_args = ['to_root_dir?', 'from_archive?', 'reuse_history*']
578
        takes_options = ['verbose', Option('prefixes', type=str,
579
                         help="Prefixes of branches to import")]
580
        def run(self, to_root_dir=None, from_archive=None, verbose=False,
581
                reuse_history_list=[], prefixes=None):
582
                print "This command is disabled.  Please install PyBaz."
583
    commands.extend((cmd_baz_import_branch, cmd_baz_import))
246 by Aaron Bentley
Merged shelf_v2
584
271 by Aaron Bentley
Cherry-picked Robert's diff and push fixes
585
246 by Aaron Bentley
Merged shelf_v2
586
if hasattr(bzrlib.commands, 'register_command'):
587
    for command in commands:
588
        bzrlib.commands.register_command(command)
271 by Aaron Bentley
Cherry-picked Robert's diff and push fixes
589
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
590
591
def test_suite():
592
    from bzrlib.tests.TestUtil import TestLoader
147.1.41 by Aaron Bentley
Merge from mainline
593
    import tests
321.1.3 by Aaron Bentley
Fixed up Robert's test changes
594
    from doctest import DocTestSuite, ELLIPSIS
325.1.2 by Aaron Bentley
Merge shelf v2
595
    from unittest import TestSuite
391 by Aaron Bentley
Updates from the bzr clean-tree branch
596
    import tests.clean_tree
374 by Aaron Bentley
Start work on import plugin
597
    import upstream_import
345 by Aaron Bentley
Added zap command
598
    import zap
339 by Aaron Bentley
Moved tests into a subdir
599
    import tests.blackbox
600
    import tests.shelf_tests
246 by Aaron Bentley
Merged shelf_v2
601
    result = TestSuite()
321.1.3 by Aaron Bentley
Fixed up Robert's test changes
602
    result.addTest(DocTestSuite(bzrtools, optionflags=ELLIPSIS))
391 by Aaron Bentley
Updates from the bzr clean-tree branch
603
    result.addTest(tests.clean_tree.test_suite())
387 by Aaron Bentley
Got test suite running with PyBaz unavailable
604
    try:
605
        import baz_import
606
        result.addTest(DocTestSuite(baz_import))
607
    except NoPyBaz:
608
        pass
147.1.41 by Aaron Bentley
Merge from mainline
609
    result.addTest(tests.test_suite())
339 by Aaron Bentley
Moved tests into a subdir
610
    result.addTest(TestLoader().loadTestsFromModule(tests.shelf_tests))
611
    result.addTest(tests.blackbox.test_suite())
374 by Aaron Bentley
Start work on import plugin
612
    result.addTest(upstream_import.test_suite())
345 by Aaron Bentley
Added zap command
613
    result.addTest(zap.test_suite())
246 by Aaron Bentley
Merged shelf_v2
614
    return result