~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to __init__.py

  • Committer: Aaron Bentley
  • Date: 2006-12-21 05:41:05 UTC
  • mfrom: (476.1.1 bzrtools)
  • Revision ID: aaron.bentley@utoronto.ca-20061221054105-r6a8njsyixw9998r
graph-ancestry shows branch nick

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007 Aaron Bentley <aaron@aaronbentley.com>
 
1
# Copyright (C) 2005, 2006 Aaron Bentley <aaron.bentley@utoronto.ca>
2
2
# Copyright (C) 2005, 2006 Canonical Limited.
3
3
# Copyright (C) 2006 Michael Ellerman.
4
4
#
22
22
 
23
23
import bzrlib
24
24
 
25
 
from bzrlib.lazy_import import lazy_import
26
 
lazy_import(globals(), """
27
 
from bzrlib import help, urlutils
28
 
import shelf
29
 
""")
30
 
 
31
 
from version import version_info, __version__
32
 
from command import BzrToolsCommand
 
25
 
 
26
__version__ = '0.14.0'
 
27
 
 
28
 
 
29
version_info = tuple(int(n) for n in __version__.split('.'))
 
30
 
 
31
 
 
32
def check_bzrlib_version(desired):
 
33
    """Check that bzrlib is compatible.
 
34
 
 
35
    If version is < bzrtools version, assume incompatible.
 
36
    If version == bzrtools version, assume completely compatible
 
37
    If version == bzrtools version + 1, assume compatible, with deprecations
 
38
    Otherwise, assume incompatible.
 
39
    """
 
40
    desired_plus = (desired[0], desired[1]+1)
 
41
    bzrlib_version = bzrlib.version_info[:2]
 
42
    if bzrlib_version == desired:
 
43
        return
 
44
    try:
 
45
        from bzrlib.trace import warning
 
46
    except ImportError:
 
47
        # get the message out any way we can
 
48
        from warnings import warn as warning
 
49
    if bzrlib_version < desired:
 
50
        warning('Installed bzr version %s is too old to be used with bzrtools'
 
51
                ' %s.' % (bzrlib.__version__, __version__))
 
52
        # Not using BzrNewError, because it may not exist.
 
53
        raise Exception, ('Version mismatch', version_info)
 
54
    else:
 
55
        warning('Bzrtools is not up to date with installed bzr version %s.'
 
56
                ' \nThere should be a newer version available, e.g. %i.%i.' 
 
57
                % (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
 
58
        if bzrlib_version != desired_plus:
 
59
            raise Exception, 'Version mismatch'
 
60
 
 
61
 
 
62
check_bzrlib_version(version_info[:2])
 
63
 
 
64
 
33
65
from errors import CommandError, NoPyBaz
34
66
from patchsource import BzrPatchSource
 
67
from shelf import Shelf
35
68
import sys
36
69
import os.path
37
70
 
38
71
import bzrlib.builtins
39
72
import bzrlib.commands
40
 
from bzrlib.branch import Branch
41
 
from bzrlib.bzrdir import BzrDir
42
73
from bzrlib.commands import get_cmd_object
43
74
from bzrlib.errors import BzrCommandError
 
75
from bzrlib.help import command_usage
44
76
import bzrlib.ignores
45
 
from bzrlib.trace import note
46
77
from bzrlib.option import Option
47
 
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__),
 
78
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__), 
48
79
                                                 "external")))
49
80
 
50
81
import show_paths
51
 
from command import BzrToolsCommand
52
82
 
53
83
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
54
84
 
55
85
 
56
 
class cmd_clean_tree(BzrToolsCommand):
 
86
class cmd_clean_tree(bzrlib.commands.Command):
57
87
    """Remove unwanted files from working tree.
58
88
 
59
89
    By default, only unknown files, not ignored files, are deleted.  Versioned
68
98
 
69
99
    To check what clean-tree will do, use --dry-run.
70
100
    """
71
 
    takes_options = [Option('ignored', help='Delete all ignored files.'),
72
 
                     Option('detritus', help='Delete conflict files, merge'
73
 
                            ' backups, and failed selftest dirs.'),
74
 
                     Option('unknown',
75
 
                            help='Delete files unknown to bzr (default).'),
76
 
                     Option('dry-run', help='Show files to delete instead of'
 
101
    takes_options = [Option('ignored', help='delete all ignored files.'), 
 
102
                     Option('detritus', help='delete conflict files, merge'
 
103
                            ' backups, and failed selftest dirs.'), 
 
104
                     Option('unknown', 
 
105
                            help='delete files unknown to bzr.  (default)'),
 
106
                     Option('dry-run', help='show files to delete instead of'
77
107
                            ' deleting them.')]
78
108
    def run(self, unknown=False, ignored=False, detritus=False, dry_run=False):
79
109
        from clean_tree import clean_tree
83
113
                   dry_run=dry_run)
84
114
 
85
115
 
86
 
class cmd_graph_ancestry(BzrToolsCommand):
 
116
class cmd_graph_ancestry(bzrlib.commands.Command):
87
117
    """Produce ancestry graphs using dot.
88
118
    
89
119
    Output format is detected according to file extension.  Some of the more
95
125
    with the last 5 characters of their revision identifier are used instead.
96
126
 
97
127
    The value starting with d is "(maximum) distance from the null revision".
98
 
 
 
128
    
99
129
    If --merge-branch is specified, the two branches are compared and a merge
100
130
    base is selected.
101
 
 
 
131
    
102
132
    Legend:
103
133
    white    normal revision
104
134
    yellow   THIS  history
118
148
    If available, rsvg is used to antialias PNG and JPEG output, but this can
119
149
    be disabled with --no-antialias.
120
150
    """
121
 
    takes_args = ['file', 'merge_branch?']
122
 
    takes_options = [Option('no-collapse', help="Do not skip simple nodes."),
 
151
    takes_args = ['branch', 'file']
 
152
    takes_options = [Option('no-collapse', help="Do not skip simple nodes"), 
123
153
                     Option('no-antialias',
124
 
                     help="Do not use rsvg to produce antialiased output."),
125
 
                     Option('merge-branch', type=str,
126
 
                     help="Use this branch to calcuate a merge base."),
127
 
                     Option('cluster', help="Use clustered output."),
128
 
                     Option('max-distance',
129
 
                            help="Show no nodes farther than this.", type=int),
130
 
                     Option('directory',
131
 
                            help='Source branch to use (default is current'
132
 
                            ' directory).',
133
 
                            short_name='d',
134
 
                            type=unicode),
135
 
                    ]
136
 
    def run(self, file, merge_branch=None, no_collapse=False,
137
 
            no_antialias=False, cluster=False, max_distance=100,
138
 
            directory='.'):
139
 
        if max_distance == -1:
140
 
            max_distance = None
 
154
                     help="Do not use rsvg to produce antialiased output"), 
 
155
                     Option('merge-branch', type=str, 
 
156
                     help="Use this branch to calcuate a merge base"), 
 
157
                     Option('cluster', help="Use clustered output.")]
 
158
    def run(self, branch, file, no_collapse=False, no_antialias=False,
 
159
        merge_branch=None, cluster=False):
141
160
        import graph
142
161
        if cluster:
143
162
            ranking = "cluster"
144
163
        else:
145
164
            ranking = "forced"
146
 
        graph.write_ancestry_file(directory, file, not no_collapse,
147
 
                                  not no_antialias, merge_branch, ranking,
148
 
                                  max_distance=max_distance)
149
 
 
150
 
 
151
 
class cmd_fetch_ghosts(BzrToolsCommand):
 
165
        graph.write_ancestry_file(branch, file, not no_collapse, 
 
166
                                  not no_antialias, merge_branch, ranking)
 
167
 
 
168
 
 
169
class cmd_fetch_ghosts(bzrlib.commands.Command):
152
170
    """Attempt to retrieve ghosts from another branch.
153
171
    If the other branch is not supplied, the last-pulled branch is used.
154
172
    """
155
173
    aliases = ['fetch-missing']
156
174
    takes_args = ['branch?']
157
 
    takes_options = [Option('no-fix', help="Skip additional synchonization.")]
 
175
    takes_options = [Option('no-fix')]
158
176
    def run(self, branch=None, no_fix=False):
159
177
        from fetch_ghosts import fetch_ghosts
160
178
        fetch_ghosts(branch, no_fix)
163
181
each file name found in the patch file."""
164
182
 
165
183
 
166
 
class cmd_patch(BzrToolsCommand):
 
184
class cmd_patch(bzrlib.commands.Command):
167
185
    """Apply a named patch to the current tree.
168
186
    """
169
187
    takes_args = ['filename?']
170
 
    takes_options = [Option('strip', type=int, help=strip_help),
171
 
                     Option('silent', help='Suppress chatter.')]
172
 
    def run(self, filename=None, strip=None, silent=False):
 
188
    takes_options = [Option('strip', type=int, help=strip_help)]
 
189
    def run(self, filename=None, strip=None):
173
190
        from patch import patch
174
191
        from bzrlib.workingtree import WorkingTree
175
192
        wt = WorkingTree.open_containing('.')[0]
176
193
        if strip is None:
177
194
            strip = 0
178
 
        return patch(wt, filename, strip, silent)
179
 
 
180
 
 
181
 
class cmd_shelve(BzrToolsCommand):
 
195
        return patch(wt, filename, strip)
 
196
 
 
197
 
 
198
class cmd_shelve(bzrlib.commands.Command):
182
199
    """Temporarily set aside some changes from the current tree.
183
200
 
184
201
    Shelve allows you to temporarily put changes you've made "on the shelf",
209
226
    """
210
227
 
211
228
    takes_args = ['file*']
212
 
    takes_options = [Option('message',
213
 
            help='A message to associate with the shelved changes.',
214
 
            short_name='m', type=unicode),
215
 
            'revision',
216
 
            Option('all', help='Shelve all changes without prompting.'),
217
 
            Option('no-color', help='Never display changes in color.')]
 
229
    takes_options = ['message', 'revision',
 
230
            Option('all', help='Shelve all changes without prompting'), 
 
231
            Option('no-color', help='Never display changes in color')]
218
232
 
219
233
    def run(self, all=False, file_list=None, message=None, revision=None,
220
234
            no_color=False):
226
240
                                  "parameter.")
227
241
 
228
242
        source = BzrPatchSource(revision, file_list)
229
 
        s = shelf.Shelf(source.base)
 
243
        s = Shelf(source.base)
230
244
        s.shelve(source, all, message, no_color)
231
245
        return 0
232
246
 
254
268
    aliases = ['switch']
255
269
    takes_args = ['othershelf']
256
270
    def run(self, othershelf):
257
 
        s = shelf.Shelf(self.shelf.base, othershelf)
 
271
        s = Shelf(self.shelf.base, othershelf)
258
272
        s.make_default()
259
273
 
260
274
 
273
287
        self.shelf.upgrade()
274
288
 
275
289
 
276
 
class cmd_shelf(BzrToolsCommand):
 
290
class cmd_shelf(bzrlib.commands.Command):
277
291
    """Perform various operations on your shelved patches. See also shelve."""
278
292
    takes_args = ['subcommand', 'args*']
279
293
 
287
301
            args_list = []
288
302
        cmd = self._get_cmd_object(subcommand)
289
303
        source = BzrPatchSource()
290
 
        s = shelf.Shelf(source.base)
 
304
        s = Shelf(source.base)
291
305
        cmd.shelf = s
292
 
 
293
 
        if args_list is None:
294
 
            args_list = []
295
306
        return cmd.run_argv_aliases(args_list)
296
307
 
297
308
    def _get_cmd_object(self, cmd_name):
314
325
        cmd_obj = cmd_class()
315
326
        indent = 2 * ' '
316
327
 
317
 
        usage = cmd_obj._usage()
 
328
        usage = command_usage(cmd_obj)
318
329
        usage = usage.replace('bzr shelf-', '')
319
330
        text.append('%s%s\n' % (indent, usage))
320
331
 
339
350
        return text
340
351
 
341
352
 
342
 
class cmd_unshelve(BzrToolsCommand):
 
353
class cmd_unshelve(bzrlib.commands.Command):
343
354
    """Restore shelved changes.
344
355
 
345
356
    By default the most recently shelved changes are restored. However if you
348
359
    See 'shelve' for more information.
349
360
    """
350
361
    takes_options = [
351
 
            Option('all', help='Unshelve all changes without prompting.'),
352
 
            Option('force', help='Force unshelving even if errors occur.'),
353
 
            Option('no-color', help='Never display changes in color.')
 
362
            Option('all', help='Unshelve all changes without prompting'),
 
363
            Option('force', help='Force unshelving even if errors occur'),
 
364
            Option('no-color', help='Never display changes in color')
354
365
        ]
355
366
    takes_args = ['patch?']
356
367
    def run(self, patch=None, all=False, force=False, no_color=False):
357
368
        source = BzrPatchSource()
358
 
        s = shelf.Shelf(source.base)
 
369
        s = Shelf(source.base)
359
370
        s.unshelve(source, patch, all, force, no_color)
360
371
        return 0
361
372
 
362
373
 
363
 
class cmd_shell(BzrToolsCommand):
 
374
class cmd_shell(bzrlib.commands.Command):
364
375
    """Begin an interactive shell tailored for bzr.
365
376
    Bzr commands can be used without typing bzr first, and will be run natively
366
377
    when possible.  Tab completion is tailored for bzr.  The shell prompt shows
383
394
        return shell.run_shell()
384
395
 
385
396
 
386
 
class cmd_branch_history(BzrToolsCommand):
 
397
class cmd_branch_history(bzrlib.commands.Command):
387
398
    """\
388
399
    Display the development history of a branch.
389
400
 
393
404
    """
394
405
    takes_args = ["branch?"]
395
406
    def run(self, branch=None):
396
 
        from branchhistory import branch_history
 
407
        from branchhistory import branch_history 
397
408
        return branch_history(branch)
398
409
 
399
410
 
400
 
class cmd_zap(BzrToolsCommand):
 
411
class cmd_zap(bzrlib.commands.Command):
401
412
    """\
402
413
    Remove a lightweight checkout, if it can be done safely.
403
414
 
408
419
    If --branch is specified, the branch will be deleted too, but only if the
409
420
    the branch has no new commits (relative to its parent).
410
421
    """
411
 
    takes_options = [Option("branch", help="Remove associated branch from"
412
 
                                           " repository."),
413
 
                     Option('force', help='Delete tree even if contents are'
414
 
                     ' modified.')]
 
422
    takes_options = [Option("branch", help="Remove associtated branch from"
 
423
                                           " repository")]
415
424
    takes_args = ["checkout"]
416
 
    def run(self, checkout, branch=False, force=False):
 
425
    def run(self, checkout, branch=False):
417
426
        from zap import zap
418
 
        return zap(checkout, remove_branch=branch, allow_modified=force)
419
 
 
420
 
 
421
 
class cmd_cbranch(BzrToolsCommand):
 
427
        return zap(checkout, remove_branch=branch)
 
428
 
 
429
 
 
430
class cmd_cbranch(bzrlib.commands.Command):
422
431
    """
423
432
    Create a new checkout, associated with a new repository branch.
424
 
 
425
 
    When you cbranch, bzr looks up a target location in locations.conf, and
426
 
    creates the branch there.
427
 
 
428
 
    In your locations.conf, add the following lines:
429
 
    [/working_directory_root]
430
 
    cbranch_target = /branch_root
431
 
    cbranch_target:policy = appendpath
432
 
 
433
 
    This will mean that if you run "bzr cbranch foo/bar foo/baz" in the
434
 
    working directory root, the branch will be created in
435
 
    "/branch_root/foo/baz"
436
 
 
437
 
    NOTE: cbranch also supports "cbranch_root", but that behaviour is
438
 
    deprecated.
 
433
    
 
434
    When you cbranch, bzr looks up the repository associated with your current
 
435
    directory in locations.conf.  It creates a new branch in that repository
 
436
    with the same name and relative path as the checkout you request.
 
437
 
 
438
    The locations.conf parameter is "cbranch_root".  So if you want 
 
439
    cbranch operations in /home/jrandom/bigproject to produce branches in 
 
440
    /home/jrandom/bigproject/repository, you'd add this:
 
441
 
 
442
    [/home/jrandom/bigproject]
 
443
    cbranch_root = /home/jrandom/bigproject/repository
 
444
 
 
445
    Note that if "/home/jrandom/bigproject/repository" isn't a repository,
 
446
    standalone branches will be produced.  Standalone branches will also
 
447
    be produced if the source branch is in 0.7 format (or earlier).
439
448
    """
440
 
    takes_options = [Option("lightweight",
441
 
                            help="Create a lightweight checkout."), 'revision',
442
 
                     Option('files-from', type=unicode,
443
 
                            help='Accelerate checkout using files from this'
444
 
                                 ' tree.'),
445
 
                     Option('hardlink',
446
 
                            help='Hard-link files from source/files-from tree'
447
 
                            ' where posible.')]
 
449
    takes_options = [Option("lightweight", 
 
450
                            help="Create a lightweight checkout"), 'revision']
448
451
    takes_args = ["source", "target?"]
449
 
    def run(self, source, target=None, lightweight=False, revision=None,
450
 
            files_from=None, hardlink=False):
 
452
    def run(self, source, target=None, lightweight=False, revision=None):
451
453
        from cbranch import cbranch
452
 
        return cbranch(source, target, lightweight=lightweight,
453
 
                       revision=revision, files_from=files_from,
454
 
                       hardlink=hardlink)
455
 
 
456
 
 
457
 
class cmd_branches(BzrToolsCommand):
 
454
        return cbranch(source, target, lightweight=lightweight, 
 
455
                       revision=revision)
 
456
 
 
457
 
 
458
class cmd_branches(bzrlib.commands.Command):
458
459
    """Scan a location for branches"""
459
460
    takes_args = ["location?"]
460
461
    def run(self, location=None):
461
462
        from branches import branches
462
463
        return branches(location)
463
464
 
464
 
class cmd_trees(BzrToolsCommand):
465
 
    """Scan a location for trees"""
466
 
    takes_args = ['location?']
467
 
    def run(self, location='.'):
468
 
        from bzrlib.workingtree import WorkingTree
469
 
        from bzrlib.transport import get_transport
470
 
        t = get_transport(location)
471
 
        for tree in WorkingTree.find_trees(location):
472
 
            self.outf.write('%s\n' % t.relpath(
473
 
                tree.bzrdir.root_transport.base))
474
465
 
475
 
class cmd_multi_pull(BzrToolsCommand):
 
466
class cmd_multi_pull(bzrlib.commands.Command):
476
467
    """Pull all the branches under a location, e.g. a repository.
477
 
 
 
468
    
478
469
    Both branches present in the directory and the branches of checkouts are
479
470
    pulled.
480
471
    """
481
472
    takes_args = ["location?"]
482
473
    def run(self, location=None):
 
474
        from bzrlib.branch import Branch
483
475
        from bzrlib.transport import get_transport
484
476
        from bzrtools import iter_branch_tree
485
477
        if location is None:
486
478
            location = '.'
487
479
        t = get_transport(location)
488
 
        possible_transports = []
489
480
        if not t.listable():
490
481
            print "Can't list this type of location."
491
482
            return 3
507
498
                relpath = base
508
499
            print "Pulling %s from %s" % (relpath, parent)
509
500
            try:
510
 
                branch_t = get_transport(parent, possible_transports)
511
 
                pullable.pull(Branch.open_from_transport(branch_t))
 
501
                pullable.pull(Branch.open(parent))
512
502
            except Exception, e:
513
503
                print e
514
504
 
515
505
 
516
 
 
517
 
class cmd_import(BzrToolsCommand):
518
 
    """Import sources from a directory, tarball or zip file
519
 
 
520
 
    This command will import a directory, tarball or zip file into a bzr
521
 
    tree, replacing any versioned files already present.  If a directory is
522
 
    specified, it is used as the target.  If the directory does not exist, or
523
 
    is not versioned, it is created.
 
506
class cmd_branch_mark(bzrlib.commands.Command):
 
507
    """
 
508
    Add, view or list branch markers <EXPERIMENTAL>
 
509
 
 
510
    To add a mark, do 'bzr branch-mark MARK'.
 
511
    To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
 
512
    repository).
 
513
    To delete a mark, do 'bzr branch-mark --delete MARK'
 
514
 
 
515
    These marks can be used to track a branch's status.
 
516
    """
 
517
    takes_args = ['mark?', 'branch?']
 
518
    takes_options = [Option('delete', help='Delete this mark')]
 
519
    def run(self, mark=None, branch=None, delete=False):
 
520
        from branch_mark import branch_mark
 
521
        branch_mark(mark, branch, delete)
 
522
 
 
523
 
 
524
class cmd_import(bzrlib.commands.Command):
 
525
    """Import sources from a tarball or zip file
 
526
    
 
527
    This command will import a tarball or zip file into a bzr tree, replacing
 
528
    any versioned files already present.  If a directory is specified, it is
 
529
    used as the target.  If the directory does not exist, or is not versioned,
 
530
    it is created.
524
531
 
525
532
    Tarballs may be gzip or bzip2 compressed.  This is autodetected.
526
533
 
527
 
    If the tarball or zip has a single root directory, that directory is
528
 
    stripped when extracting the tarball.  This is not done for directories.
 
534
    If the tarball has a single root directory, that directory is stripped
 
535
    when extracting the tarball.
529
536
    """
530
 
 
 
537
    
531
538
    takes_args = ['source', 'tree?']
532
539
    def run(self, source, tree=None):
533
540
        from upstream_import import do_import
534
541
        do_import(source, tree)
535
542
 
536
543
 
537
 
class cmd_cdiff(BzrToolsCommand):
 
544
class cmd_cdiff(bzrlib.commands.Command):
538
545
    """A color version of bzr's diff"""
539
546
    takes_args = property(lambda x: get_cmd_object('diff').takes_args)
540
 
    takes_options = list(get_cmd_object('diff').takes_options) + [
541
 
        Option('check-style',
542
 
            help='Warn if trailing whitespace or spurious changes have been'
543
 
                 ' added.')]
544
 
 
545
 
    def run(self, check_style=False, *args, **kwargs):
 
547
    takes_options = property(lambda x: get_cmd_object('diff').takes_options)
 
548
    def run(*args, **kwargs):
546
549
        from colordiff import colordiff
547
 
        colordiff(check_style, *args, **kwargs)
548
 
 
549
 
 
550
 
class cmd_baz_import(BzrToolsCommand):
 
550
        colordiff(*args, **kwargs)
 
551
 
 
552
 
 
553
class cmd_baz_import(bzrlib.commands.Command):
551
554
    """Import an Arch or Baz archive into a bzr repository.
552
555
 
553
556
    This command should be used on local archives (or mirrors) only.  It is
554
557
    quite slow on remote archives.
555
 
 
556
 
    reuse_history allows you to specify any previous imports you
 
558
    
 
559
    reuse_history allows you to specify any previous imports you 
557
560
    have done of different archives, which this archive has branches
558
 
    tagged from. This will dramatically reduce the time to convert
 
561
    tagged from. This will dramatically reduce the time to convert 
559
562
    the archive as it will not have to convert the history already
560
563
    converted in that other branch.
561
564
 
574
577
    """
575
578
    takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
576
579
    takes_options = ['verbose', Option('prefixes', type=str,
577
 
                     help="Prefixes of branches to import, colon-separated."),
578
 
                     Option('encoding', type=str,
 
580
                     help="Prefixes of branches to import, colon-separated"),
 
581
                     Option('encoding', type=str, 
579
582
                     help='Force encoding to specified value.  See WARNING.')]
580
583
 
581
584
    def run(self, to_root_dir, from_archive, encoding=None, verbose=False,
589
592
            print "This command is disabled.  Please install PyBaz."
590
593
 
591
594
 
592
 
class cmd_baz_import_branch(BzrToolsCommand):
 
595
class cmd_baz_import_branch(bzrlib.commands.Command):
593
596
    """Import an Arch or Baz branch into a bzr branch.
594
597
 
595
598
    WARNING: Encoding should not be specified unless necessary, because if you
600
603
    are incompatible.
601
604
    """
602
605
    takes_args = ['to_location', 'from_branch?', 'reuse_history*']
603
 
    takes_options = ['verbose', 
604
 
                     Option('max-count', type=int, 
605
 
                     help='Maximim revisions to import at once.'),
606
 
                     Option('encoding', type=str,
 
606
    takes_options = ['verbose', Option('max-count', type=int),
 
607
                     Option('encoding', type=str, 
607
608
                     help='Force encoding to specified value.  See WARNING.')]
608
609
 
609
610
    def run(self, to_location, from_branch=None, fast=False, max_count=None,
612
613
        from errors import NoPyBaz
613
614
        try:
614
615
            import baz_import
615
 
            baz_import.baz_import_branch(to_location, from_branch, fast,
 
616
            baz_import.baz_import_branch(to_location, from_branch, fast, 
616
617
                                         max_count, verbose, encoding, dry_run,
617
618
                                         reuse_history_list)
618
619
        except NoPyBaz:
619
620
            print "This command is disabled.  Please install PyBaz."
620
621
 
621
622
 
622
 
class cmd_rspush(BzrToolsCommand):
 
623
class cmd_rspush(bzrlib.commands.Command):
623
624
    """Upload this branch to another location using rsync.
624
625
 
625
 
    If no location is specified, the last-used location will be used.  To
626
 
    prevent dirty trees from being uploaded, rspush will error out if there are
627
 
    unknown files or local changes.  It will also error out if the upstream
628
 
    directory is non-empty and not an earlier version of the branch.
 
626
    If no location is specified, the last-used location will be used.  To 
 
627
    prevent dirty trees from being uploaded, rspush will error out if there are 
 
628
    unknown files or local changes.  It will also error out if the upstream 
 
629
    directory is non-empty and not an earlier version of the branch. 
629
630
    """
630
631
    takes_args = ['location?']
631
632
    takes_options = [Option('overwrite', help='Ignore differences between'
632
 
                            ' branches and overwrite unconditionally.'),
 
633
                            ' branches and overwrite unconditionally'),
633
634
                     Option('no-tree', help='Do not push the working tree,'
634
635
                            ' just the .bzr.')]
635
636
 
637
638
        from bzrlib import workingtree
638
639
        import bzrtools
639
640
        cur_branch = workingtree.WorkingTree.open_containing(".")[0]
640
 
        bzrtools.rspush(cur_branch, location, overwrite=overwrite,
 
641
        bzrtools.rspush(cur_branch, location, overwrite=overwrite, 
641
642
                      working_tree=not no_tree)
642
643
 
643
644
 
644
 
class cmd_link_tree(BzrToolsCommand):
645
 
    """Hardlink matching files to another tree.
646
 
 
647
 
    Only files with identical content and execute bit will be linked.
648
 
    """
649
 
    takes_args = ['location']
650
 
 
651
 
    def run(self, location):
652
 
        from bzrlib import workingtree
653
 
        from bzrlib.plugins.bzrtools.link_tree import link_tree
654
 
        target_tree = workingtree.WorkingTree.open_containing(".")[0]
655
 
        source_tree = workingtree.WorkingTree.open(location)
656
 
        target_tree.lock_write()
657
 
        try:
658
 
            source_tree.lock_read()
659
 
            try:
660
 
                link_tree(target_tree, source_tree)
661
 
            finally:
662
 
                source_tree.unlock()
663
 
        finally:
664
 
            target_tree.unlock()
665
 
 
666
 
from heads import cmd_heads
 
645
class cmd_switch(bzrlib.commands.Command):
 
646
    """Set the branch of a lightweight checkout and update."""
 
647
 
 
648
    takes_args = ['to_location']
 
649
 
 
650
    def run(self, to_location):
 
651
        from switch import cmd_switch
 
652
        cmd_switch().run(to_location)
 
653
 
 
654
 
667
655
commands = [
668
656
            cmd_baz_import,
669
657
            cmd_baz_import_branch,
670
658
            cmd_branches,
671
659
            cmd_branch_history,
672
 
            cmd_cbranch,
 
660
            cmd_branch_mark,
 
661
            cmd_cbranch,  
673
662
            cmd_cdiff,
674
663
            cmd_clean_tree,
675
664
            cmd_fetch_ghosts,
676
665
            cmd_graph_ancestry,
677
 
            cmd_heads,
678
666
            cmd_import,
679
 
            cmd_link_tree,
680
667
            cmd_multi_pull,
681
668
            cmd_patch,
682
669
            cmd_rspush,
683
 
            cmd_shelf,
 
670
            cmd_shelf, 
684
671
            cmd_shell,
685
 
            cmd_shelve,
686
 
            cmd_trees,
687
 
            cmd_unshelve,
688
 
            cmd_zap,
 
672
            cmd_shelve, 
 
673
            cmd_switch,
 
674
            cmd_unshelve, 
 
675
            cmd_zap,            
689
676
            ]
690
677
 
691
678
 
701
688
    from unittest import TestSuite
702
689
    import bzrtools
703
690
    import tests.clean_tree
704
 
    import tests.test_dotgraph
705
 
    import tests.is_clean
706
 
    import tests.test_cbranch
707
 
    import tests.test_link_tree
708
 
    import tests.test_patch
709
 
    import tests.test_rspush
710
691
    import tests.upstream_import
711
692
    import zap
712
693
    import tests.blackbox
724
705
    result.addTest(tests.blackbox.test_suite())
725
706
    result.addTest(tests.upstream_import.test_suite())
726
707
    result.addTest(zap.test_suite())
727
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_dotgraph))
728
 
    result.addTest(TestLoader().loadTestsFromModule(tests.is_clean))
729
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_link_tree))
730
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_patch))
731
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_rspush))
732
 
    result.addTest(TestLoader().loadTestsFromModule(tests.test_cbranch))
733
708
    return result