~abentley/bzrtools/bzrtools.dev

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