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