~abentley/bzrtools/bzrtools.dev

612 by Aaron Bentley
Update email address
1
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron@aaronbentley.com>
460 by Aaron Bentley
Add encoding parameter everywhere
2
# Copyright (C) 2005, 2006 Canonical Limited.
3
# Copyright (C) 2006 Michael Ellerman.
4
#
5
#    This program is free software; you can redistribute it and/or modify
6
#    it under the terms of the GNU General Public License as published by
7
#    the Free Software Foundation; either version 2 of the License, or
8
#    (at your option) any later version.
9
#
10
#    This program is distributed in the hope that it will be useful,
11
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
#    GNU General Public License for more details.
14
#
15
#    You should have received a copy of the GNU General Public License
16
#    along with this program; if not, write to the Free Software
17
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
428 by Aaron Bentley
Add version number, check against bzrlib version
19
import bzrlib
20
512 by Aaron Bentley
More import-time fixups
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
577.1.1 by Aaron Bentley
bzr switch works when the source branch is renamed
23
from bzrlib import help, urlutils
512 by Aaron Bentley
More import-time fixups
24
import shelf
25
""")
428 by Aaron Bentley
Add version number, check against bzrlib version
26
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
27
from command import BzrToolsCommand
650 by Aaron Bentley
Remove references to PyBaz
28
from errors import CommandError
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
29
from patchsource import BzrPatchSource
246 by Aaron Bentley
Merged shelf_v2
30
import sys
31
import os.path
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
32
33
import bzrlib.builtins
34
import bzrlib.commands
577.1.1 by Aaron Bentley
bzr switch works when the source branch is renamed
35
from bzrlib.branch import Branch
36
from bzrlib.bzrdir import BzrDir
410 by Aaron Bentley
Ensure the option settings come from the right 'diff' in colordiff
37
from bzrlib.commands import get_cmd_object
0.1.39 by Michael Ellerman
Fix shelve and unshelve to pass location to Shelf().
38
from bzrlib.errors import BzrCommandError
423 by Aaron Bentley
Add runtime ignores for shelf
39
import bzrlib.ignores
577.1.1 by Aaron Bentley
bzr switch works when the source branch is renamed
40
from bzrlib.trace import note
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
41
from bzrlib.option import Option
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
42
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
43
from command import BzrToolsCommand
465 by Aaron Bentley
Add show-paths command from Alexander Belchenko
44
246 by Aaron Bentley
Merged shelf_v2
45
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
46
class cmd_clean_tree(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
47
    """Remove unwanted files from working tree.
417 by Aaron Bentley
Update clean-tree docs
48
49
    By default, only unknown files, not ignored files, are deleted.  Versioned
50
    files are never deleted.
51
52
    Another class is 'detritus', which includes files emitted by bzr during
53
    normal operations and selftests.  (The value of these files decreases with
54
    time.)
55
56
    If no options are specified, unknown files are deleted.  Otherwise, option
57
    flags are respected, and may be combined.
58
59
    To check what clean-tree will do, use --dry-run.
246 by Aaron Bentley
Merged shelf_v2
60
    """
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
61
    takes_options = [Option('ignored', help='Delete all ignored files.'),
62
                     Option('detritus', help='Delete conflict files, merge'
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
63
                            ' backups, and failed selftest dirs.'),
64
                     Option('unknown',
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
65
                            help='Delete files unknown to bzr (default).'),
66
                     Option('dry-run', help='Show files to delete instead of'
667 by Aaron Bentley
Add prompts before deleting in clean-tree
67
                            ' deleting them.'),
68
                     Option('force', help='Do not prompt before deleting.')]
69
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False,
70
            force=False):
246 by Aaron Bentley
Merged shelf_v2
71
        from clean_tree import clean_tree
415.1.1 by Adeodato Simó
Make clean-tree --detritus or --ignored not delete also unknown files,
72
        if not (unknown or ignored or detritus):
73
            unknown = True
667 by Aaron Bentley
Add prompts before deleting in clean-tree
74
        if dry_run:
75
            force = True
416 by Aaron Bentley
clean-tree --detritus no longer implies --unknown
76
        clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus, 
667 by Aaron Bentley
Add prompts before deleting in clean-tree
77
                   dry_run=dry_run, no_prompt=force)
246 by Aaron Bentley
Merged shelf_v2
78
445 by Aaron Bentley
Remove shove, tweak imports, docs
79
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
80
class cmd_graph_ancestry(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
81
    """Produce ancestry graphs using dot.
246 by Aaron Bentley
Merged shelf_v2
82
    
83
    Output format is detected according to file extension.  Some of the more
296 by Aaron Bentley
Updated graph-ancestry help
84
    common output formats are html, png, gif, svg, ps.  An extension of '.dot'
85
    will cause a dot graph file to be produced.  HTML output has mouseovers
86
    that show the commit message.
246 by Aaron Bentley
Merged shelf_v2
87
88
    Branches are labeled r?, where ? is the revno.  If they have no revno,
89
    with the last 5 characters of their revision identifier are used instead.
296 by Aaron Bentley
Updated graph-ancestry help
90
91
    The value starting with d is "(maximum) distance from the null revision".
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
92
246 by Aaron Bentley
Merged shelf_v2
93
    If --merge-branch is specified, the two branches are compared and a merge
94
    base is selected.
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
95
246 by Aaron Bentley
Merged shelf_v2
96
    Legend:
97
    white    normal revision
98
    yellow   THIS  history
99
    red      OTHER history
100
    orange   COMMON history
101
    blue     COMMON non-history ancestor
296 by Aaron Bentley
Updated graph-ancestry help
102
    green    Merge base (COMMON ancestor farthest from the null revision)
103
    dotted   Ghost revision (missing from branch storage)
246 by Aaron Bentley
Merged shelf_v2
104
296 by Aaron Bentley
Updated graph-ancestry help
105
    Ancestry is usually collapsed by skipping revisions with a single parent
246 by Aaron Bentley
Merged shelf_v2
106
    and descendant.  The number of skipped revisions is shown on the arrow.
107
    This feature can be disabled with --no-collapse.
108
109
    By default, revisions are ordered by distance from root, but they can be
110
    clustered instead using --cluster.
111
112
    If available, rsvg is used to antialias PNG and JPEG output, but this can
113
    be disabled with --no-antialias.
114
    """
546 by Aaron Bentley
Fix argument handling in graph-ancestry
115
    takes_args = ['file', 'merge_branch?']
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
116
    takes_options = [Option('no-collapse', help="Do not skip simple nodes."),
296 by Aaron Bentley
Updated graph-ancestry help
117
                     Option('no-antialias',
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
118
                     help="Do not use rsvg to produce antialiased output."),
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
119
                     Option('merge-branch', type=str,
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
120
                     help="Use this branch to calcuate a merge base."),
476.1.2 by Aaron Bentley
graph-ancestry can restrict the number of nodes shown by distance
121
                     Option('cluster', help="Use clustered output."),
544 by Aaron Bentley
Update graph-ancestry to support new graph API
122
                     Option('max-distance',
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
123
                            help="Show no nodes farther than this.", type=int),
544 by Aaron Bentley
Update graph-ancestry to support new graph API
124
                     Option('directory',
125
                            help='Source branch to use (default is current'
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
126
                            ' directory).',
544 by Aaron Bentley
Update graph-ancestry to support new graph API
127
                            short_name='d',
128
                            type=unicode),
129
                    ]
546 by Aaron Bentley
Fix argument handling in graph-ancestry
130
    def run(self, file, merge_branch=None, no_collapse=False,
131
            no_antialias=False, cluster=False, max_distance=100,
132
            directory='.'):
544 by Aaron Bentley
Update graph-ancestry to support new graph API
133
        if max_distance == -1:
134
            max_distance = None
246 by Aaron Bentley
Merged shelf_v2
135
        import graph
136
        if cluster:
137
            ranking = "cluster"
138
        else:
139
            ranking = "forced"
544 by Aaron Bentley
Update graph-ancestry to support new graph API
140
        graph.write_ancestry_file(directory, file, not no_collapse,
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
141
                                  not no_antialias, merge_branch, ranking,
476.1.2 by Aaron Bentley
graph-ancestry can restrict the number of nodes shown by distance
142
                                  max_distance=max_distance)
246 by Aaron Bentley
Merged shelf_v2
143
445 by Aaron Bentley
Remove shove, tweak imports, docs
144
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
145
class cmd_fetch_ghosts(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
146
    """Attempt to retrieve ghosts from another branch.
246 by Aaron Bentley
Merged shelf_v2
147
    If the other branch is not supplied, the last-pulled branch is used.
148
    """
149
    aliases = ['fetch-missing']
150
    takes_args = ['branch?']
558 by Aaron Bentley
Fix the --no-fix option of fetch-ghosts
151
    takes_options = [Option('no-fix', help="Skip additional synchonization.")]
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
152
    def run(self, branch=None, no_fix=False):
246 by Aaron Bentley
Merged shelf_v2
153
        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
154
        fetch_ghosts(branch, no_fix)
246 by Aaron Bentley
Merged shelf_v2
155
156
strip_help="""Strip the smallest prefix containing num leading slashes  from \
157
each file name found in the patch file."""
445 by Aaron Bentley
Remove shove, tweak imports, docs
158
159
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
160
class cmd_patch(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
161
    """Apply a named patch to the current tree.
246 by Aaron Bentley
Merged shelf_v2
162
    """
163
    takes_args = ['filename?']
496 by Aaron Bentley
Add --silent option to patch
164
    takes_options = [Option('strip', type=int, help=strip_help),
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
165
                     Option('silent', help='Suppress chatter.')]
496 by Aaron Bentley
Add --silent option to patch
166
    def run(self, filename=None, strip=None, silent=False):
246 by Aaron Bentley
Merged shelf_v2
167
        from patch import patch
340 by Aaron Bentley
Fixed patch on checkouts
168
        from bzrlib.workingtree import WorkingTree
169
        wt = WorkingTree.open_containing('.')[0]
473 by Aaron Bentley
Clean up patch command (support http urls again)
170
        if strip is None:
171
            strip = 0
496 by Aaron Bentley
Add --silent option to patch
172
        return patch(wt, filename, strip, silent)
246 by Aaron Bentley
Merged shelf_v2
173
427 by Aaron Bentley
Merge latest changes from Shelf
174
668 by Aaron Bentley
Rename shelve/unshelve to shelve1/unshelve1, alias to old names
175
class cmd_shelve1(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
176
    """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
177
178
    Shelve allows you to temporarily put changes you've made "on the shelf",
179
    ie. out of the way, until a later time when you can bring them back from
669 by Aaron Bentley
Update docs
180
    the shelf with the 'unshelve1' command.
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
181
289 by Aaron Bentley
Updated shelf help
182
    Shelve is intended to help separate several sets of text changes that have
183
    been inappropriately mingled.  If you just want to get rid of all changes
184
    (text and otherwise) and you don't need to restore them later, use revert.
669 by Aaron Bentley
Update docs
185
    If you want to shelve all text changes at once, use shelve1 --all.
289 by Aaron Bentley
Updated shelf help
186
669 by Aaron Bentley
Update docs
187
    By default shelve1 asks you what you want to shelve, press '?' at the
188
    prompt to get help. To shelve everything run shelve1 --all.
0.1.90 by Michael Ellerman
Update help text to try and be clearer, some stolen from bzrtools.
189
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
190
    If filenames are specified, only the changes to those files will be
191
    shelved, other files will be left untouched.
192
193
    If a revision is specified, changes since that revision will be shelved.
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
194
195
    You can put multiple items on the shelf. Normally each time you run
669 by Aaron Bentley
Update docs
196
    unshelve1 the most recently shelved changes will be reinstated. However,
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
197
    you can also unshelve changes in a different order by explicitly
669 by Aaron Bentley
Update docs
198
    specifiying which changes to unshelve1. This works best when the changes
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
199
    don't depend on each other.
0.7.3 by Michael Ellerman
Add a reference from 'shelve' help to 'shelf'.
200
201
    While you have patches on the shelf you can view and manipulate them with
202
    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.
203
    """
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
204
668 by Aaron Bentley
Rename shelve/unshelve to shelve1/unshelve1, alias to old names
205
    aliases = ['shelve']
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
206
    takes_args = ['file*']
556 by Aaron Bentley
Fix shelf's message parameter
207
    takes_options = [Option('message',
208
            help='A message to associate with the shelved changes.',
561 by Aaron Bentley
Fix shelf message option
209
            short_name='m', type=unicode),
556 by Aaron Bentley
Fix shelf's message parameter
210
            'revision',
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
211
            Option('all', help='Shelve all changes without prompting.'),
212
            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.
213
423.1.4 by Aaron Bentley
Add --no-color option to shelf
214
    def run(self, all=False, file_list=None, message=None, revision=None,
215
            no_color=False):
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
216
        if revision is not None and revision:
217
            if len(revision) == 1:
218
                revision = revision[0]
219
            else:
220
                raise CommandError("shelve only accepts a single revision "
221
                                  "parameter.")
222
223
        source = BzrPatchSource(revision, file_list)
512 by Aaron Bentley
More import-time fixups
224
        s = shelf.Shelf(source.base)
423.1.4 by Aaron Bentley
Add --no-color option to shelf
225
        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
226
        return 0
227
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
228
229
# The following classes are only used as subcommands for 'shelf', they're
230
# not to be registered directly with bzr.
231
232
class cmd_shelf_list(bzrlib.commands.Command):
233
    """List the patches on the current shelf."""
234
    aliases = ['list', 'ls']
235
    def run(self):
236
        self.shelf.list()
237
238
239
class cmd_shelf_delete(bzrlib.commands.Command):
240
    """Delete the patch from the current shelf."""
241
    aliases = ['delete', 'del']
242
    takes_args = ['patch']
243
    def run(self, patch):
244
        self.shelf.delete(patch)
245
246
247
class cmd_shelf_switch(bzrlib.commands.Command):
248
    """Switch to the other shelf, create it if necessary."""
249
    aliases = ['switch']
0.1.117 by Michael Ellerman
Arg names with hyphens don't seem to work (broke shelf switch).
250
    takes_args = ['othershelf']
251
    def run(self, othershelf):
512 by Aaron Bentley
More import-time fixups
252
        s = shelf.Shelf(self.shelf.base, othershelf)
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
253
        s.make_default()
254
255
256
class cmd_shelf_show(bzrlib.commands.Command):
0.1.110 by Michael Ellerman
Make the patch argument to 'shelf show' optional.
257
    """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'.
258
    aliases = ['show', 'cat', 'display']
0.1.110 by Michael Ellerman
Make the patch argument to 'shelf show' optional.
259
    takes_args = ['patch?']
260
    def run(self, patch=None):
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
261
        self.shelf.display(patch)
262
263
264
class cmd_shelf_upgrade(bzrlib.commands.Command):
265
    """Upgrade old format shelves."""
266
    aliases = ['upgrade']
267
    def run(self):
268
        self.shelf.upgrade()
269
270
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
271
class cmd_shelf(BzrToolsCommand):
669 by Aaron Bentley
Update docs
272
    """Perform various operations on your shelved patches. See also shelve1."""
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
273
    takes_args = ['subcommand', 'args*']
274
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
275
    subcommands = [cmd_shelf_list, cmd_shelf_delete, cmd_shelf_switch,
276
        cmd_shelf_show, cmd_shelf_upgrade]
277
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
278
    def run(self, subcommand, args_list):
279
        import sys
280
456.1.1 by Aaron Bentley
Fix shelf ls with no args (Alexander Belchenko)
281
        if args_list is None:
282
            args_list = []
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()
512 by Aaron Bentley
More import-time fixups
285
        s = shelf.Shelf(source.base)
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
286
        cmd.shelf = s
0.7.4 by Michael Ellerman
Cope with run_argv_aliases() API change
287
288
        if args_list is None:
289
            args_list = []
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
290
        return cmd.run_argv_aliases(args_list)
291
292
    def _get_cmd_object(self, cmd_name):
293
        for cmd_class in self.subcommands:
294
            for alias in cmd_class.aliases:
295
                if alias == cmd_name:
296
                    return cmd_class()
297
        raise CommandError("Unknown shelf subcommand '%s'" % cmd_name)
298
299
    def help(self):
0.1.111 by Michael Ellerman
Make help for subcommands more readable, print options in help also.
300
        text = ["%s\n\nSubcommands:\n" % self.__doc__]
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
301
302
        for cmd_class in self.subcommands:
0.1.111 by Michael Ellerman
Make help for subcommands more readable, print options in help also.
303
            text.extend(self.sub_help(cmd_class) + ['\n'])
304
305
        return ''.join(text)
306
307
    def sub_help(self, cmd_class):
308
        text = []
309
        cmd_obj = cmd_class()
310
        indent = 2 * ' '
311
531.1.1 by Aaron Bentley
Add test for shelf help, since it's custom
312
        usage = cmd_obj._usage()
0.1.111 by Michael Ellerman
Make help for subcommands more readable, print options in help also.
313
        usage = usage.replace('bzr shelf-', '')
314
        text.append('%s%s\n' % (indent, usage))
315
316
        text.append('%s%s\n' % (2 * indent, cmd_class.__doc__))
317
318
        # Somewhat copied from bzrlib.help.help_on_command_options
319
        option_help = []
320
        for option_name, option in sorted(cmd_obj.options().items()):
321
            if option_name == 'help':
322
                continue
323
            option_help.append('%s--%s' % (3 * indent, option_name))
324
            if option.type is not None:
325
                option_help.append(' %s' % option.argname.upper())
326
            if option.short_name():
327
                option_help.append(', -%s' % option.short_name())
328
            option_help.append('%s%s\n' % (2 * indent, option.help))
329
330
        if len(option_help) > 0:
331
            text.append('%soptions:\n' % (2 * indent))
332
            text.extend(option_help)
333
334
        return text
0.1.109 by Michael Ellerman
Hijack the bzr command infrastructure to do subcommands for 'shelf'.
335
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
336
668 by Aaron Bentley
Rename shelve/unshelve to shelve1/unshelve1, alias to old names
337
class cmd_unshelve1(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
338
    """Restore shelved changes.
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
339
340
    By default the most recently shelved changes are restored. However if you
341
    specify a patch by name those changes will be restored instead.
342
669 by Aaron Bentley
Update docs
343
    See 'shelve1' for more information.
0.1.73 by Michael Ellerman
Merge most of the standalone shelf branch. This brings in a few changes which
344
    """
668 by Aaron Bentley
Rename shelve/unshelve to shelve1/unshelve1, alias to old names
345
    aliases = ['unshelve']
0.1.91 by Michael Ellerman
Add --force option to unshelve, which runs the shelved changes through
346
    takes_options = [
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
347
            Option('all', help='Unshelve all changes without prompting.'),
348
            Option('force', help='Force unshelving even if errors occur.'),
349
            Option('no-color', help='Never display changes in color.')
423.1.4 by Aaron Bentley
Add --no-color option to shelf
350
        ]
0.1.113 by Michael Ellerman
Support for unshelving in arbitrary order.
351
    takes_args = ['patch?']
423.1.4 by Aaron Bentley
Add --no-color option to shelf
352
    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
353
        source = BzrPatchSource()
512 by Aaron Bentley
More import-time fixups
354
        s = shelf.Shelf(source.base)
423.1.4 by Aaron Bentley
Add --no-color option to shelf
355
        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
356
        return 0
357
0.1.22 by Michael Ellerman
Add __init__.py, put cmd_shelve/unshelve in there.
358
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
359
class cmd_shell(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
360
    """Begin an interactive shell tailored for bzr.
287 by Aaron Bentley
Added shell docstring
361
    Bzr commands can be used without typing bzr first, and will be run natively
362
    when possible.  Tab completion is tailored for bzr.  The shell prompt shows
363
    the branch nick, revno, and path.
364
365
    If it encounters any moderately complicated shell command, it will punt to
366
    the system shell.
367
368
    Example:
369
    $ bzr shell
370
    bzr bzrtools:287/> status
371
    modified:
372
      __init__.py
373
    bzr bzrtools:287/> status --[TAB][TAB]
374
    --all        --help       --revision   --show-ids
375
    bzr bzrtools:287/> status --
376
    """
249 by Aaron Bentley
Got the shell basics working properly
377
    def run(self):
378
        import shell
281 by Aaron Bentley
Handled whitespace branch names better
379
        return shell.run_shell()
246 by Aaron Bentley
Merged shelf_v2
380
445 by Aaron Bentley
Remove shove, tweak imports, docs
381
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
382
class cmd_branch_history(BzrToolsCommand):
292 by Aaron Bentley
Introduced branch-history command
383
    """\
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
384
    Display the development history of a branch.
292 by Aaron Bentley
Introduced branch-history command
385
293 by Aaron Bentley
Updated help
386
    Each different committer or branch nick is considered a different line of
387
    development.  Committers are treated as the same if they have the same
388
    name, or if they have the same email address.
292 by Aaron Bentley
Introduced branch-history command
389
    """
390
    takes_args = ["branch?"]
391
    def run(self, branch=None):
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
392
        from branchhistory import branch_history
292 by Aaron Bentley
Introduced branch-history command
393
        return branch_history(branch)
394
345 by Aaron Bentley
Added zap command
395
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
396
class cmd_zap(BzrToolsCommand):
345 by Aaron Bentley
Added zap command
397
    """\
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
398
    Remove a lightweight checkout, if it can be done safely.
411 by Aaron Bentley
Update zap documentation
399
400
    This command will remove a lightweight checkout without losing data.  That
401
    means it only removes lightweight checkouts, and only if they have no
402
    uncommitted changes.
403
404
    If --branch is specified, the branch will be deleted too, but only if the
405
    the branch has no new commits (relative to its parent).
345 by Aaron Bentley
Added zap command
406
    """
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
407
    takes_options = [Option("branch", help="Remove associated branch from"
573.1.3 by Aaron Bentley
Allow zap --force to delete modified checkouts
408
                                           " repository."),
409
                     Option('force', help='Delete tree even if contents are'
410
                     ' modified.')]
345 by Aaron Bentley
Added zap command
411
    takes_args = ["checkout"]
573.1.3 by Aaron Bentley
Allow zap --force to delete modified checkouts
412
    def run(self, checkout, branch=False, force=False):
345 by Aaron Bentley
Added zap command
413
        from zap import zap
573.1.3 by Aaron Bentley
Allow zap --force to delete modified checkouts
414
        return zap(checkout, remove_branch=branch, allow_modified=force)
345 by Aaron Bentley
Added zap command
415
416
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
417
class cmd_cbranch(BzrToolsCommand):
349 by Aaron Bentley
Added cbranch command
418
    """
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
419
    Create a new checkout, associated with a new repository branch.
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
420
486 by Aaron Bentley
Support deep cbranch hierarcy via appendpath
421
    When you cbranch, bzr looks up a target location in locations.conf, and
422
    creates the branch there.
423
424
    In your locations.conf, add the following lines:
425
    [/working_directory_root]
426
    cbranch_target = /branch_root
427
    cbranch_target:policy = appendpath
428
429
    This will mean that if you run "bzr cbranch foo/bar foo/baz" in the
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
430
    working directory root, the branch will be created in
486 by Aaron Bentley
Support deep cbranch hierarcy via appendpath
431
    "/branch_root/foo/baz"
432
433
    NOTE: cbranch also supports "cbranch_root", but that behaviour is
434
    deprecated.
349 by Aaron Bentley
Added cbranch command
435
    """
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
436
    takes_options = [Option("lightweight",
596.1.1 by Aaron Bentley
Update cbranch to accelerate checkouts
437
                            help="Create a lightweight checkout."), 'revision',
600 by Aaron Bentley
Rename from-files to files-from, to match bzr proper
438
                     Option('files-from', type=unicode,
596.1.1 by Aaron Bentley
Update cbranch to accelerate checkouts
439
                            help='Accelerate checkout using files from this'
619 by Aaron Bentley
Add support for hard-link in cbranch
440
                                 ' tree.'),
441
                     Option('hardlink',
442
                            help='Hard-link files from source/files-from tree'
443
                            ' where posible.')]
355.1.2 by Aaron Bentley
cbranch mimics checkout wrt --lightweight
444
    takes_args = ["source", "target?"]
596.1.1 by Aaron Bentley
Update cbranch to accelerate checkouts
445
    def run(self, source, target=None, lightweight=False, revision=None,
619 by Aaron Bentley
Add support for hard-link in cbranch
446
            files_from=None, hardlink=False):
349 by Aaron Bentley
Added cbranch command
447
        from cbranch import cbranch
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
448
        return cbranch(source, target, lightweight=lightweight,
619 by Aaron Bentley
Add support for hard-link in cbranch
449
                       revision=revision, files_from=files_from,
450
                       hardlink=hardlink)
355.1.2 by Aaron Bentley
cbranch mimics checkout wrt --lightweight
451
349 by Aaron Bentley
Added cbranch command
452
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
453
class cmd_branches(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
454
    """Scan a location for branches"""
352 by Aaron Bentley
Added branches subcommand
455
    takes_args = ["location?"]
456
    def run(self, location=None):
457
        from branches import branches
458
        return branches(location)
459
603 by Aaron Bentley
Update branches, multi-pull to new APIs, create trees
460
class cmd_trees(BzrToolsCommand):
461
    """Scan a location for trees"""
462
    takes_args = ['location?']
463
    def run(self, location='.'):
464
        from bzrlib.workingtree import WorkingTree
465
        from bzrlib.transport import get_transport
466
        t = get_transport(location)
467
        for tree in WorkingTree.find_trees(location):
468
            self.outf.write('%s\n' % t.relpath(
469
                tree.bzrdir.root_transport.base))
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
470
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
471
class cmd_multi_pull(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
472
    """Pull all the branches under a location, e.g. a repository.
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
473
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
474
    Both branches present in the directory and the branches of checkouts are
475
    pulled.
476
    """
477
    takes_args = ["location?"]
478
    def run(self, location=None):
479
        from bzrlib.transport import get_transport
480
        from bzrtools import iter_branch_tree
481
        if location is None:
482
            location = '.'
483
        t = get_transport(location)
572 by Aaron Bentley
multi-pull reuses connections where possible
484
        possible_transports = []
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
485
        if not t.listable():
486
            print "Can't list this type of location."
487
            return 3
488
        for branch, wt in iter_branch_tree(t):
489
            if wt is None:
490
                pullable = branch
491
            else:
492
                pullable = wt
493
            parent = branch.get_parent()
494
            if parent is None:
495
                continue
496
            if wt is not None:
497
                base = wt.basedir
498
            else:
499
                base = branch.base
500
            if base.startswith(t.base):
501
                relpath = base[len(t.base):].rstrip('/')
502
            else:
503
                relpath = base
504
            print "Pulling %s from %s" % (relpath, parent)
505
            try:
572 by Aaron Bentley
multi-pull reuses connections where possible
506
                branch_t = get_transport(parent, possible_transports)
507
                pullable.pull(Branch.open_from_transport(branch_t))
353 by Aaron Bentley
Added multi-pull, working on branches and checkouts
508
            except Exception, e:
509
                print e
510
511
603 by Aaron Bentley
Update branches, multi-pull to new APIs, create trees
512
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
513
class cmd_import(BzrToolsCommand):
490 by Aaron Bentley
Improve bzr import docs
514
    """Import sources from a directory, tarball or zip file
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
515
490 by Aaron Bentley
Improve bzr import docs
516
    This command will import a directory, tarball or zip file into a bzr
517
    tree, replacing any versioned files already present.  If a directory is
518
    specified, it is used as the target.  If the directory does not exist, or
519
    is not versioned, it is created.
380 by Aaron Bentley
Got import working decently
520
521
    Tarballs may be gzip or bzip2 compressed.  This is autodetected.
522
490 by Aaron Bentley
Improve bzr import docs
523
    If the tarball or zip has a single root directory, that directory is
524
    stripped when extracting the tarball.  This is not done for directories.
380 by Aaron Bentley
Got import working decently
525
    """
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
526
380 by Aaron Bentley
Got import working decently
527
    takes_args = ['source', 'tree?']
528
    def run(self, source, tree=None):
377 by Aaron Bentley
Got import command working
529
        from upstream_import import do_import
380 by Aaron Bentley
Got import working decently
530
        do_import(source, tree)
377 by Aaron Bentley
Got import command working
531
392.1.1 by Aaron Bentley
Implement 'shove' for moving changes to other trees
532
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
533
class cmd_cdiff(BzrToolsCommand):
415 by Aaron Bentley
Remove <BZRTOOLS> tag from command descriptions
534
    """A color version of bzr's diff"""
410 by Aaron Bentley
Ensure the option settings come from the right 'diff' in colordiff
535
    takes_args = property(lambda x: get_cmd_object('diff').takes_args)
560 by Aaron Bentley
Update cdiff option definition
536
    takes_options = list(get_cmd_object('diff').takes_options) + [
537
        Option('check-style',
500 by Aaron Bentley
Add help
538
            help='Warn if trailing whitespace or spurious changes have been'
560 by Aaron Bentley
Update cdiff option definition
539
                 ' added.')]
497 by Aaron Bentley
Add optional style checks to colordiff
540
541
    def run(self, check_style=False, *args, **kwargs):
399 by Aaron Bentley
Implement cdiff (based on old Fai code)
542
        from colordiff import colordiff
497 by Aaron Bentley
Add optional style checks to colordiff
543
        colordiff(check_style, *args, **kwargs)
360.1.3 by Aaron Bentley
Add experimental branch-mark command
544
430 by Aaron Bentley
Avoid loading PyBaz unless running baz-import
545
568 by Aaron Bentley
Don't check version when running non-bzrtools commands
546
class cmd_rspush(BzrToolsCommand):
460 by Aaron Bentley
Add encoding parameter everywhere
547
    """Upload this branch to another location using rsync.
548
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
549
    If no location is specified, the last-used location will be used.  To
550
    prevent dirty trees from being uploaded, rspush will error out if there are
551
    unknown files or local changes.  It will also error out if the upstream
552
    directory is non-empty and not an earlier version of the branch.
460 by Aaron Bentley
Add encoding parameter everywhere
553
    """
554
    takes_args = ['location?']
555
    takes_options = [Option('overwrite', help='Ignore differences between'
553.1.1 by Vincent Ladeuil
Fix option help strings to comply with the style guide.
556
                            ' branches and overwrite unconditionally.'),
460 by Aaron Bentley
Add encoding parameter everywhere
557
                     Option('no-tree', help='Do not push the working tree,'
558
                            ' just the .bzr.')]
559
560
    def run(self, location=None, overwrite=False, no_tree=False):
561
        from bzrlib import workingtree
562
        import bzrtools
563
        cur_branch = workingtree.WorkingTree.open_containing(".")[0]
531.2.2 by Charlie Shepherd
Remove all trailing whitespace
564
        bzrtools.rspush(cur_branch, location, overwrite=overwrite,
460 by Aaron Bentley
Add encoding parameter everywhere
565
                      working_tree=not no_tree)
566
567
622 by Aaron Bentley
Add link-tree command
568
class cmd_link_tree(BzrToolsCommand):
569
    """Hardlink matching files to another tree.
570
571
    Only files with identical content and execute bit will be linked.
572
    """
573
    takes_args = ['location']
574
575
    def run(self, location):
576
        from bzrlib import workingtree
577
        from bzrlib.plugins.bzrtools.link_tree import link_tree
578
        target_tree = workingtree.WorkingTree.open_containing(".")[0]
579
        source_tree = workingtree.WorkingTree.open(location)
580
        target_tree.lock_write()
581
        try:
582
            source_tree.lock_read()
583
            try:
584
                link_tree(target_tree, source_tree)
585
            finally:
586
                source_tree.unlock()
587
        finally:
588
            target_tree.unlock()