25
from bzrlib.lazy_import import lazy_import
26
lazy_import(globals(), """
27
from bzrlib import help, urlutils
31
from version import version_info, __version__
32
from command import BzrToolsCommand
33
from errors import CommandError
26
__version__ = '0.14.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 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)
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'
62
check_bzrlib_version(version_info[:2])
65
from errors import CommandError, NoPyBaz
34
66
from patchsource import BzrPatchSource
67
from shelf import Shelf
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__),
51
from command import BzrToolsCommand
53
83
bzrlib.ignores.add_runtime_ignores(['./.shelf'])
56
class cmd_clean_tree(BzrToolsCommand):
86
class cmd_clean_tree(bzrlib.commands.Command):
57
87
"""Remove unwanted files from working tree.
59
89
By default, only unknown files, not ignored files, are deleted. Versioned
118
148
If available, rsvg is used to antialias PNG and JPEG output, but this can
119
149
be disabled with --no-antialias.
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."),
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"),
127
157
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:
158
Option('max-distance', help="Show no nodes farther than this",
160
def run(self, branch, file, no_collapse=False, no_antialias=False,
161
merge_branch=None, cluster=False, max_distance=None):
143
164
ranking = "cluster"
145
166
ranking = "forced"
146
graph.write_ancestry_file(directory, file, not no_collapse,
147
not no_antialias, merge_branch, ranking,
167
graph.write_ancestry_file(branch, file, not no_collapse,
168
not no_antialias, merge_branch, ranking,
148
169
max_distance=max_distance)
151
class cmd_fetch_ghosts(BzrToolsCommand):
172
class cmd_fetch_ghosts(bzrlib.commands.Command):
152
173
"""Attempt to retrieve ghosts from another branch.
153
174
If the other branch is not supplied, the last-pulled branch is used.
155
176
aliases = ['fetch-missing']
156
177
takes_args = ['branch?']
157
takes_options = [Option('no-fix', help="Skip additional synchonization.")]
178
takes_options = [Option('no-fix')]
158
179
def run(self, branch=None, no_fix=False):
159
180
from fetch_ghosts import fetch_ghosts
160
181
fetch_ghosts(branch, no_fix)
408
422
If --branch is specified, the branch will be deleted too, but only if the
409
423
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'
425
takes_options = [Option("branch", help="Remove associtated branch from"
415
427
takes_args = ["checkout"]
416
def run(self, checkout, branch=False, force=False):
428
def run(self, checkout, branch=False):
417
429
from zap import zap
418
return zap(checkout, remove_branch=branch, allow_modified=force)
421
class cmd_cbranch(BzrToolsCommand):
430
return zap(checkout, remove_branch=branch)
433
class cmd_cbranch(bzrlib.commands.Command):
423
435
Create a new checkout, associated with a new repository branch.
425
When you cbranch, bzr looks up a target location in locations.conf, and
426
creates the branch there.
428
In your locations.conf, add the following lines:
429
[/working_directory_root]
430
cbranch_target = /branch_root
431
cbranch_target:policy = appendpath
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"
437
NOTE: cbranch also supports "cbranch_root", but that behaviour is
437
When you cbranch, bzr looks up the repository associated with your current
438
directory in locations.conf. It creates a new branch in that repository
439
with the same name and relative path as the checkout you request.
441
The locations.conf parameter is "cbranch_root". So if you want
442
cbranch operations in /home/jrandom/bigproject to produce branches in
443
/home/jrandom/bigproject/repository, you'd add this:
445
[/home/jrandom/bigproject]
446
cbranch_root = /home/jrandom/bigproject/repository
448
Note that if "/home/jrandom/bigproject/repository" isn't a repository,
449
standalone branches will be produced. Standalone branches will also
450
be produced if the source branch is in 0.7 format (or earlier).
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'
446
help='Hard-link files from source/files-from tree'
452
takes_options = [Option("lightweight",
453
help="Create a lightweight checkout"), 'revision']
448
454
takes_args = ["source", "target?"]
449
def run(self, source, target=None, lightweight=False, revision=None,
450
files_from=None, hardlink=False):
455
def run(self, source, target=None, lightweight=False, revision=None):
451
456
from cbranch import cbranch
452
return cbranch(source, target, lightweight=lightweight,
453
revision=revision, files_from=files_from,
457
class cmd_branches(BzrToolsCommand):
457
return cbranch(source, target, lightweight=lightweight,
461
class cmd_branches(bzrlib.commands.Command):
458
462
"""Scan a location for branches"""
459
463
takes_args = ["location?"]
460
464
def run(self, location=None):
461
465
from branches import branches
462
466
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):
469
class cmd_multi_pull(bzrlib.commands.Command):
476
470
"""Pull all the branches under a location, e.g. a repository.
478
472
Both branches present in the directory and the branches of checkouts are
481
475
takes_args = ["location?"]
482
476
def run(self, location=None):
477
from bzrlib.branch import Branch
483
478
from bzrlib.transport import get_transport
484
479
from bzrtools import iter_branch_tree
485
480
if location is None:
487
482
t = get_transport(location)
488
possible_transports = []
489
483
if not t.listable():
490
484
print "Can't list this type of location."
508
502
print "Pulling %s from %s" % (relpath, parent)
510
branch_t = get_transport(parent, possible_transports)
511
pullable.pull(Branch.open_from_transport(branch_t))
504
pullable.pull(Branch.open(parent))
512
505
except Exception, e:
517
class cmd_import(BzrToolsCommand):
518
"""Import sources from a directory, tarball or zip file
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.
509
class cmd_branch_mark(bzrlib.commands.Command):
511
Add, view or list branch markers <EXPERIMENTAL>
513
To add a mark, do 'bzr branch-mark MARK'.
514
To list marks, do 'bzr branch-mark' (this lists all marks for the branch's
516
To delete a mark, do 'bzr branch-mark --delete MARK'
518
These marks can be used to track a branch's status.
520
takes_args = ['mark?', 'branch?']
521
takes_options = [Option('delete', help='Delete this mark')]
522
def run(self, mark=None, branch=None, delete=False):
523
from branch_mark import branch_mark
524
branch_mark(mark, branch, delete)
527
class cmd_import(bzrlib.commands.Command):
528
"""Import sources from a tarball or zip file
530
This command will import a tarball or zip file into a bzr tree, replacing
531
any versioned files already present. If a directory is specified, it is
532
used as the target. If the directory does not exist, or is not versioned,
525
535
Tarballs may be gzip or bzip2 compressed. This is autodetected.
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.
537
If the tarball has a single root directory, that directory is stripped
538
when extracting the tarball.
531
541
takes_args = ['source', 'tree?']
532
542
def run(self, source, tree=None):
533
543
from upstream_import import do_import
534
544
do_import(source, tree)
537
class cmd_cdiff(BzrToolsCommand):
547
class cmd_cdiff(bzrlib.commands.Command):
538
548
"""A color version of bzr's diff"""
539
549
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'
545
def run(self, check_style=False, *args, **kwargs):
550
takes_options = property(lambda x: get_cmd_object('diff').takes_options)
551
def run(*args, **kwargs):
546
552
from colordiff import colordiff
547
colordiff(check_style, *args, **kwargs)
550
class cmd_rspush(BzrToolsCommand):
553
colordiff(*args, **kwargs)
556
class cmd_baz_import(bzrlib.commands.Command):
557
"""Import an Arch or Baz archive into a bzr repository.
559
This command should be used on local archives (or mirrors) only. It is
560
quite slow on remote archives.
562
reuse_history allows you to specify any previous imports you
563
have done of different archives, which this archive has branches
564
tagged from. This will dramatically reduce the time to convert
565
the archive as it will not have to convert the history already
566
converted in that other branch.
568
If you specify prefixes, only branches whose names start with that prefix
569
will be imported. Skipped branches will be listed, so you can import any
570
branches you missed by accident. Here's an example of doing a partial
571
import from thelove@canonical.com:
572
bzr baz-import thelove thelove@canonical.com --prefixes dists:talloc-except
574
WARNING: Encoding should not be specified unless necessary, because if you
575
specify an encoding, your converted branch will not interoperate with
576
independently-converted branches, unless the other branches were converted
577
with exactly the same encoding. Any encoding recognized by Python may
578
be specified. Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
581
takes_args = ['to_root_dir', 'from_archive', 'reuse_history*']
582
takes_options = ['verbose', Option('prefixes', type=str,
583
help="Prefixes of branches to import, colon-separated"),
584
Option('encoding', type=str,
585
help='Force encoding to specified value. See WARNING.')]
587
def run(self, to_root_dir, from_archive, encoding=None, verbose=False,
588
reuse_history_list=[], prefixes=None):
589
from errors import NoPyBaz
592
baz_import.baz_import(to_root_dir, from_archive, encoding,
593
verbose, reuse_history_list, prefixes)
595
print "This command is disabled. Please install PyBaz."
598
class cmd_baz_import_branch(bzrlib.commands.Command):
599
"""Import an Arch or Baz branch into a bzr branch.
601
WARNING: Encoding should not be specified unless necessary, because if you
602
specify an encoding, your converted branch will not interoperate with
603
independently-converted branches, unless the other branches were converted
604
with exactly the same encoding. Any encoding recognized by Python may
605
be specified. Aliases are not detected, so 'utf_8', 'U8', 'UTF' and 'utf8'
608
takes_args = ['to_location', 'from_branch?', 'reuse_history*']
609
takes_options = ['verbose', Option('max-count', type=int),
610
Option('encoding', type=str,
611
help='Force encoding to specified value. See WARNING.')]
613
def run(self, to_location, from_branch=None, fast=False, max_count=None,
614
encoding=None, verbose=False, dry_run=False,
615
reuse_history_list=[]):
616
from errors import NoPyBaz
619
baz_import.baz_import_branch(to_location, from_branch, fast,
620
max_count, verbose, encoding, dry_run,
623
print "This command is disabled. Please install PyBaz."
626
class cmd_rspush(bzrlib.commands.Command):
551
627
"""Upload this branch to another location using rsync.
553
If no location is specified, the last-used location will be used. To
554
prevent dirty trees from being uploaded, rspush will error out if there are
555
unknown files or local changes. It will also error out if the upstream
556
directory is non-empty and not an earlier version of the branch.
629
If no location is specified, the last-used location will be used. To
630
prevent dirty trees from being uploaded, rspush will error out if there are
631
unknown files or local changes. It will also error out if the upstream
632
directory is non-empty and not an earlier version of the branch.
558
634
takes_args = ['location?']
559
635
takes_options = [Option('overwrite', help='Ignore differences between'
560
' branches and overwrite unconditionally.'),
636
' branches and overwrite unconditionally'),
561
637
Option('no-tree', help='Do not push the working tree,'
562
638
' just the .bzr.')]