26
__version__ = '0.16.0'
29
version_info = tuple(int(n) for n in __version__.split('.'))
32
def check_bzrlib_version(desired):
33
"""Check that bzrlib is compatible.
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.
40
desired_plus = (desired[0], desired[1]+1)
41
bzrlib_version = bzrlib.version_info[:2]
42
if bzrlib_version == desired:
45
from bzrlib.trace import warning
47
# get the message out any way we can
48
from warnings import warn as warning
49
if bzrlib_version < desired:
50
warning('Installed Bazaar version %s is too old to be used with'
52
'"Bzrtools" %s.' % (bzrlib.__version__, __version__))
53
# Not using BzrNewError, because it may not exist.
54
raise Exception, ('Version mismatch', version_info)
56
warning('Plugin "Bzrtools" is not up to date with installed Bazaar'
58
' There should be a newer version of Bzrtools available, e.g.'
60
% (bzrlib.__version__, bzrlib_version[0], bzrlib_version[1]))
61
if bzrlib_version != desired_plus:
62
raise Exception, 'Version mismatch'
65
check_bzrlib_version(version_info[:2])
25
67
from bzrlib.lazy_import import lazy_import
26
68
lazy_import(globals(), """
27
from bzrlib import help, urlutils
69
from bzrlib import help
31
from version import version_info, __version__
32
from command import BzrToolsCommand
33
from errors import CommandError
73
from errors import CommandError, NoPyBaz
34
74
from patchsource import BzrPatchSource
38
78
import bzrlib.builtins
39
79
import bzrlib.commands
40
from bzrlib.branch import Branch
41
from bzrlib.bzrdir import BzrDir
42
80
from bzrlib.commands import get_cmd_object
43
81
from bzrlib.errors import BzrCommandError
44
82
import bzrlib.ignores
45
from bzrlib.trace import note
46
83
from bzrlib.option import Option
47
84
sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__),
51
from command import BzrToolsCommand
53
89
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
56
class cmd_clean_tree(BzrToolsCommand):
92
class cmd_clean_tree(bzrlib.commands.Command):
57
93
"""Remove unwanted files from working tree.
59
95
By default, only unknown files, not ignored files, are deleted. Versioned
69
105
To check what clean-tree will do, use --dry-run.
71
takes_options = [Option('ignored', help='Delete all ignored files.'),
72
Option('detritus', help='Delete conflict files, merge'
107
takes_options = [Option('ignored', help='delete all ignored files.'),
108
Option('detritus', help='delete conflict files, merge'
73
109
' backups, and failed selftest dirs.'),
75
help='Delete files unknown to bzr (default).'),
76
Option('dry-run', help='Show files to delete instead of'
111
help='delete files unknown to bzr. (default)'),
112
Option('dry-run', help='show files to delete instead of'
77
113
' deleting them.')]
78
114
def run(self, unknown=False, ignored=False, detritus=False, dry_run=False):
79
115
from clean_tree import clean_tree
80
116
if not (unknown or ignored or detritus):
82
clean_tree('.', unknown=unknown, ignored=ignored, detritus=detritus,
86
class cmd_graph_ancestry(BzrToolsCommand):
118
clean_tree('.', out=self.outf, unknown=unknown, ignored=ignored,
119
detritus=detritus, dry_run=dry_run)
122
class cmd_graph_ancestry(bzrlib.commands.Command):
87
123
"""Produce ancestry graphs using dot.
89
125
Output format is detected according to file extension. Some of the more
90
126
common output formats are html, png, gif, svg, ps. An extension of '.dot'
91
127
will cause a dot graph file to be produced. HTML output has mouseovers
118
154
If available, rsvg is used to antialias PNG and JPEG output, but this can
119
155
be disabled with --no-antialias.
121
takes_args = ['file', 'merge_branch?']
122
takes_options = [Option('no-collapse', help="Do not skip simple nodes."),
157
takes_args = ['branch', 'file']
158
takes_options = [Option('no-collapse', help="Do not skip simple nodes"),
123
159
Option('no-antialias',
124
help="Do not use rsvg to produce antialiased output."),
160
help="Do not use rsvg to produce antialiased output"),
125
161
Option('merge-branch', type=str,
126
help="Use this branch to calcuate a merge base."),
162
help="Use this branch to calcuate a merge base"),
127
163
Option('cluster', help="Use clustered output."),
128
Option('max-distance',
129
help="Show no nodes farther than this.", type=int),
131
help='Source branch to use (default is current'
136
def run(self, file, merge_branch=None, no_collapse=False,
137
no_antialias=False, cluster=False, max_distance=100,
139
if max_distance == -1:
164
Option('max-distance', help="Show no nodes farther than this",
166
def run(self, branch, file, no_collapse=False, no_antialias=False,
167
merge_branch=None, cluster=False, max_distance=None):
143
170
ranking = "cluster"
145
172
ranking = "forced"
146
graph.write_ancestry_file(directory, file, not no_collapse,
173
graph.write_ancestry_file(branch, file, not no_collapse,
147
174
not no_antialias, merge_branch, ranking,
148
175
max_distance=max_distance)
151
class cmd_fetch_ghosts(BzrToolsCommand):
178
class cmd_fetch_ghosts(bzrlib.commands.Command):
152
179
"""Attempt to retrieve ghosts from another branch.
153
180
If the other branch is not supplied, the last-pulled branch is used.
155
182
aliases = ['fetch-missing']
156
183
takes_args = ['branch?']
157
takes_options = [Option('no-fix', help="Skip additional synchonization.")]
184
takes_options = [Option('no-fix')]
158
185
def run(self, branch=None, no_fix=False):
159
186
from fetch_ghosts import fetch_ghosts
160
187
fetch_ghosts(branch, no_fix)
211
238
takes_args = ['file*']
212
takes_options = [Option('message',
213
help='A message to associate with the shelved changes.',
214
short_name='m', type=unicode),
216
Option('all', help='Shelve all changes without prompting.'),
217
Option('no-color', help='Never display changes in color.')]
239
takes_options = ['message', 'revision',
240
Option('all', help='Shelve all changes without prompting'),
241
Option('no-color', help='Never display changes in color')]
219
243
def run(self, all=False, file_list=None, message=None, revision=None,
408
432
If --branch is specified, the branch will be deleted too, but only if the
409
433
the branch has no new commits (relative to its parent).
411
takes_options = [Option("branch", help="Remove associated branch from"
413
Option('force', help='Delete tree even if contents are'
435
takes_options = [Option("branch", help="Remove associtated branch from"
415
437
takes_args = ["checkout"]
416
def run(self, checkout, branch=False, force=False):
438
def run(self, checkout, branch=False):
417
439
from zap import zap
418
return zap(checkout, remove_branch=branch, allow_modified=force)
421
class cmd_cbranch(BzrToolsCommand):
440
return zap(checkout, remove_branch=branch)
443
class cmd_cbranch(bzrlib.commands.Command):
423
445
Create a new checkout, associated with a new repository branch.
440
462
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'
446
help='Hard-link files from source/files-from tree'
463
help="Create a lightweight checkout"), 'revision']
448
464
takes_args = ["source", "target?"]
449
def run(self, source, target=None, lightweight=False, revision=None,
450
files_from=None, hardlink=False):
465
def run(self, source, target=None, lightweight=False, revision=None):
451
466
from cbranch import cbranch
452
467
return cbranch(source, target, lightweight=lightweight,
453
revision=revision, files_from=files_from,
457
class cmd_branches(BzrToolsCommand):
471
class cmd_branches(bzrlib.commands.Command):
458
472
"""Scan a location for branches"""
459
473
takes_args = ["location?"]
460
474
def run(self, location=None):
461
475
from branches import branches
462
476
return branches(location)
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))
475
class cmd_multi_pull(BzrToolsCommand):
479
class cmd_multi_pull(bzrlib.commands.Command):
476
480
"""Pull all the branches under a location, e.g. a repository.
478
482
Both branches present in the directory and the branches of checkouts are
508
512
print "Pulling %s from %s" % (relpath, parent)
510
branch_t = get_transport(parent, possible_transports)
511
pullable.pull(Branch.open_from_transport(branch_t))
514
pullable.pull(Branch.open(parent))
512
515
except Exception, e:
517
class cmd_import(BzrToolsCommand):
519
class cmd_branch_mark(bzrlib.commands.Command):
521
Add, view or list branch markers <EXPERIMENTAL>
523
To add a mark, do 'bzr branch-mark MARK'.
524
To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
526
To delete a mark, do 'bzr branch-mark --delete MARK'
528
These marks can be used to track a branch's status.
530
takes_args = ['mark?', 'branch?']
531
takes_options = [Option('delete', help='Delete this mark')]
532
def run(self, mark=None, branch=None, delete=False):
533
from branch_mark import branch_mark
534
branch_mark(mark, branch, delete)
537
class cmd_import(bzrlib.commands.Command):
518
538
"""Import sources from a directory, tarball or zip file
520
540
This command will import a directory, tarball or zip file into a bzr
534
554
do_import(source, tree)
537
class cmd_cdiff(BzrToolsCommand):
557
class cmd_cdiff(bzrlib.commands.Command):
538
558
"""A color version of bzr's diff"""
539
559
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',
561
def _takes_options(self):
562
options = list(get_cmd_object('diff').takes_options)
563
options.append(Option('check-style',
542
564
help='Warn if trailing whitespace or spurious changes have been'
568
takes_options = property(_takes_options)
545
570
def run(self, check_style=False, *args, **kwargs):
546
571
from colordiff import colordiff
547
572
colordiff(check_style, *args, **kwargs)
550
class cmd_rspush(BzrToolsCommand):
575
class cmd_baz_import(bzrlib.commands.Command):
576
"""Import an Arch or Baz archive into a bzr repository.
578
This command should be used on local archives (or mirrors) only. It is
579
quite slow on remote archives.
581
reuse_history allows you to specify any previous imports you
582
have done of different archives, which this archive has branches
583
tagged from. This will dramatically reduce the time to convert
584
the archive as it will not have to convert the history already
585
converted in that other branch.
587
If you specify prefixes, only branches whose names start with that prefix
588
will be imported. Skipped branches will be listed, so you can import any
589
branches you missed by accident. Here's an example of doing a partial
590
import from thelove@canonical.com:
591
bzr baz-import thelove thelove@canonical.com --prefixes dists:talloc-except
593
WARNING: Encoding should not be specified unless necessary, because if you
594
specify an encoding, your converted branch will not interoperate with
595
independently-converted branches, unless the other branches were converted
596
with exactly the same encoding. Any encoding recognized by Python may
597
be specified. Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
600
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
601
takes_options = ['verbose', Option('prefixes', type=str,
602
help="Prefixes of branches to import, colon-separated"),
603
Option('encoding', type=str,
604
help='Force encoding to specified value. See WARNING.')]
606
def run(self, to_root_dir, from_archive, encoding=None, verbose=False,
607
reuse_history_list=[], prefixes=None):
608
from errors import NoPyBaz
611
baz_import.baz_import(to_root_dir, from_archive, encoding,
612
verbose, reuse_history_list, prefixes)
614
print "This command is disabled. Please install PyBaz."
617
class cmd_baz_import_branch(bzrlib.commands.Command):
618
"""Import an Arch or Baz branch into a bzr branch.
620
WARNING: Encoding should not be specified unless necessary, because if you
621
specify an encoding, your converted branch will not interoperate with
622
independently-converted branches, unless the other branches were converted
623
with exactly the same encoding. Any encoding recognized by Python may
624
be specified. Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
627
takes_args = ['to_location', 'from_branch?', 'reuse_history*']
628
takes_options = ['verbose', Option('max-count', type=int),
629
Option('encoding', type=str,
630
help='Force encoding to specified value. See WARNING.')]
632
def run(self, to_location, from_branch=None, fast=False, max_count=None,
633
encoding=None, verbose=False, dry_run=False,
634
reuse_history_list=[]):
635
from errors import NoPyBaz
638
baz_import.baz_import_branch(to_location, from_branch, fast,
639
max_count, verbose, encoding, dry_run,
642
print "This command is disabled. Please install PyBaz."
645
class cmd_rspush(bzrlib.commands.Command):
551
646
"""Upload this branch to another location using rsync.
553
648
If no location is specified, the last-used location will be used. To
569
664
working_tree=not no_tree)
572
class cmd_link_tree(BzrToolsCommand):
573
"""Hardlink matching files to another tree.
575
Only files with identical content and execute bit will be linked.
577
takes_args = ['location']
579
def run(self, location):
580
from bzrlib import workingtree
581
from bzrlib.plugins.bzrtools.link_tree import link_tree
582
target_tree = workingtree.WorkingTree.open_containing(".")[0]
583
source_tree = workingtree.WorkingTree.open(location)
584
target_tree.lock_write()
586
source_tree.lock_read()
588
link_tree(target_tree, source_tree)
594
from heads import cmd_heads
667
class cmd_switch(bzrlib.commands.Command):
668
"""Set the branch of a lightweight checkout and update."""
670
takes_args = ['to_location']
672
def run(self, to_location):
673
from switch import cmd_switch
674
cmd_switch().run(to_location)
679
cmd_baz_import_branch,
597
681
cmd_branch_history,
601
686
cmd_fetch_ghosts,
602
687
cmd_graph_ancestry,