747
747
# The destination doesn't exist; create it.
748
748
# XXX: Refactor the create_prefix/no_create_prefix code into a
749
749
# common helper function
751
def make_directory(transport):
755
def redirected(redirected_transport, e, redirection_notice):
756
return transport.get_transport(e.get_target_url())
751
to_transport.mkdir('.')
759
to_transport = transport.do_catching_redirections(
760
make_directory, to_transport, redirected)
752
761
except errors.FileExists:
753
762
if not use_existing_dir:
754
763
raise errors.BzrCommandError("Target directory %s"
763
772
" leading parent directories."
765
774
_create_prefix(to_transport)
775
except errors.TooManyRedirections:
776
raise errors.BzrCommandError("Too many redirections trying "
777
"to make %s." % location)
767
779
# Now the target directory exists, but doesn't have a .bzr
768
780
# directory. So we need to create it, along with any work to create
1380
1392
class cmd_diff(Command):
1381
"""Show differences in the working tree or between revisions.
1393
"""Show differences in the working tree, between revisions or branches.
1383
If files are listed, only the changes in those files are listed.
1384
Otherwise, all changes for the tree are listed.
1395
If no arguments are given, all changes for the current tree are listed.
1396
If files are given, only the changes in those files are listed.
1397
Remote and multiple branches can be compared by using the --old and
1398
--new options. If not provided, the default for both is derived from
1399
the first argument, if any, or the current tree if no arguments are
1386
1402
"bzr diff -p1" is equivalent to "bzr diff --prefix old/:new/", and
1387
1403
produces patches suitable for "patch -p1".
1406
1422
bzr diff -r1..2
1424
Difference between revision 2 and revision 1 for branch xxx::
1428
Show just the differences for file NEWS::
1432
Show the differences in working tree xxx for file NEWS::
1436
Show the differences from branch xxx to this working tree:
1440
Show the differences between two branches for file NEWS::
1442
bzr diff --old xxx --new yyy NEWS
1408
1444
Same as 'bzr diff' but prefix paths with old/ and new/::
1410
1446
bzr diff --prefix old/:new/
1412
Show the differences between the two working trees::
1414
bzr diff bzr.mine bzr.dev
1416
Show just the differences for 'foo.c'::
1420
1448
# TODO: Option to use external diff command; could be GNU diff, wdiff,
1421
1449
# or a graphical diff.
1446
1482
@display_command
1447
1483
def run(self, revision=None, file_list=None, diff_options=None,
1449
from bzrlib.diff import diff_cmd_helper, show_diff_trees
1484
prefix=None, old=None, new=None):
1485
from bzrlib.diff import _get_trees_to_diff, show_diff_trees
1451
1487
if (prefix is None) or (prefix == '0'):
1452
1488
# diff -p0 format
1466
1502
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1467
1503
' one or two revision specifiers')
1470
tree1, file_list = internal_tree_files(file_list)
1474
except errors.FileInWrongBranch:
1475
if len(file_list) != 2:
1476
raise errors.BzrCommandError("Files are in different branches")
1478
tree1, file1 = WorkingTree.open_containing(file_list[0])
1479
tree2, file2 = WorkingTree.open_containing(file_list[1])
1480
if file1 != "" or file2 != "":
1481
# FIXME diff those two files. rbc 20051123
1482
raise errors.BzrCommandError("Files are in different branches")
1484
except errors.NotBranchError:
1485
if (revision is not None and len(revision) == 2
1486
and not revision[0].needs_branch()
1487
and not revision[1].needs_branch()):
1488
# If both revision specs include a branch, we can
1489
# diff them without needing a local working tree
1490
tree1, tree2 = None, None
1494
if tree2 is not None:
1495
if revision is not None:
1496
# FIXME: but there should be a clean way to diff between
1497
# non-default versions of two trees, it's not hard to do
1499
raise errors.BzrCommandError(
1500
"Sorry, diffing arbitrary revisions across branches "
1501
"is not implemented yet")
1502
return show_diff_trees(tree1, tree2, sys.stdout,
1503
specific_files=file_list,
1504
external_diff_options=diff_options,
1505
old_label=old_label, new_label=new_label)
1507
return diff_cmd_helper(tree1, file_list, diff_options,
1508
revision_specs=revision,
1509
old_label=old_label, new_label=new_label)
1505
old_tree, new_tree, specific_files, extra_trees = \
1506
_get_trees_to_diff(file_list, revision, old, new)
1507
return show_diff_trees(old_tree, new_tree, sys.stdout,
1508
specific_files=specific_files,
1509
external_diff_options=diff_options,
1510
old_label=old_label, new_label=new_label,
1511
extra_trees=extra_trees)
1512
1514
class cmd_deleted(Command):
1916
1919
Ignore class files in all directories::
1918
bzr ignore '*.class'
1920
Ignore .o files under the lib directory::
1922
bzr ignore 'lib/**/*.o'
1924
Ignore .o files under the lib directory::
1926
bzr ignore 'RE:lib/.*\.o'
1921
bzr ignore "*.class"
1923
Ignore .o files under the lib directory::
1925
bzr ignore "lib/**/*.o"
1927
Ignore .o files under the lib directory::
1929
bzr ignore "RE:lib/.*\.o"
1929
1932
_see_also = ['status', 'ignored']
2114
2117
def run(self, filename, revision=None, name_from_revision=False):
2115
2118
if revision is not None and len(revision) != 1:
2116
2119
raise errors.BzrCommandError("bzr cat --revision takes exactly"
2120
" one revision specifier")
2121
tree, branch, relpath = \
2122
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2121
tree, b, relpath = \
2122
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
2123
except errors.NotBranchError:
2125
return self._run(tree, branch, relpath, filename, revision,
2126
if revision is not None and revision[0].get_branch() is not None:
2127
b = Branch.open(revision[0].get_branch())
2130
def _run(self, tree, b, relpath, filename, revision, name_from_revision):
2128
2131
if tree is None:
2129
2132
tree = b.basis_tree()
2130
2133
if revision is None:
2219
2222
"files in the working tree."),
2220
2223
ListOption('fixes', type=str,
2221
2224
help="Mark a bug as being fixed by this revision."),
2222
Option('author', type=str,
2225
Option('author', type=unicode,
2223
2226
help="Set the author's name, if it's different "
2224
2227
"from the committer."),
2225
2228
Option('local',
2599
2605
transport=None, benchmark=None,
2600
2606
lsprof_timed=None, cache_dir=None,
2601
2607
first=False, list_only=False,
2602
randomize=None, exclude=None, strict=False):
2608
randomize=None, exclude=None, strict=False, coverage=None):
2603
2609
import bzrlib.ui
2604
2610
from bzrlib.tests import selftest
2605
2611
import bzrlib.benchmarks as benchmarks
2687
2694
branch1 = Branch.open_containing(branch)[0]
2688
2695
branch2 = Branch.open_containing(other)[0]
2690
last1 = ensure_null(branch1.last_revision())
2691
last2 = ensure_null(branch2.last_revision())
2693
graph = branch1.repository.get_graph(branch2.repository)
2694
base_rev_id = graph.find_unique_lca(last1, last2)
2696
print 'merge base is revision %s' % base_rev_id
2700
last1 = ensure_null(branch1.last_revision())
2701
last2 = ensure_null(branch2.last_revision())
2703
graph = branch1.repository.get_graph(branch2.repository)
2704
base_rev_id = graph.find_unique_lca(last1, last2)
2706
print 'merge base is revision %s' % base_rev_id
2699
2713
class cmd_merge(Command):
3072
3088
last committed revision is used.
3074
3090
To remove only some changes, without reverting to a prior version, use
3075
merge instead. For example, "merge . --r-2..-3" will remove the changes
3076
introduced by -2, without affecting the changes introduced by -1. Or
3077
to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3091
merge instead. For example, "merge . --revision -2..-3" will remove the
3092
changes introduced by -2, without affecting the changes introduced by -1.
3093
Or to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
3079
3095
By default, any files that have been manually changed will be backed up
3080
3096
first. (Files changed only by merge are not backed up.) Backup files have
3092
3108
The working tree contains a list of pending merged revisions, which will
3093
3109
be included as parents in the next commit. Normally, revert clears that
3094
list as well as reverting the files. If any files, are specified, revert
3095
leaves the pending merge list alnone and reverts only the files. Use "bzr
3110
list as well as reverting the files. If any files are specified, revert
3111
leaves the pending merge list alone and reverts only the files. Use "bzr
3096
3112
revert ." in the tree root to revert all files but keep the merge record,
3097
3113
and "bzr revert --forget-merges" to clear the pending merge list without
3098
3114
reverting any files.
3422
3438
takes_options = ['revision']
3424
3440
def run(self, revision_id_list=None, revision=None):
3425
import bzrlib.gpg as gpg
3426
3441
if revision_id_list is not None and revision is not None:
3427
3442
raise errors.BzrCommandError('You can only supply one of revision_id or --revision')
3428
3443
if revision_id_list is None and revision is None:
3429
3444
raise errors.BzrCommandError('You must supply either --revision or a revision_id')
3430
3445
b = WorkingTree.open_containing(u'.')[0].branch
3448
return self._run(b, revision_id_list, revision)
3452
def _run(self, b, revision_id_list, revision):
3453
import bzrlib.gpg as gpg
3431
3454
gpg_strategy = gpg.GPGStrategy(b.get_config())
3432
3455
if revision_id_list is not None:
3433
for revision_id in revision_id_list:
3434
b.repository.sign_revision(revision_id, gpg_strategy)
3456
b.repository.start_write_group()
3458
for revision_id in revision_id_list:
3459
b.repository.sign_revision(revision_id, gpg_strategy)
3461
b.repository.abort_write_group()
3464
b.repository.commit_write_group()
3435
3465
elif revision is not None:
3436
3466
if len(revision) == 1:
3437
3467
revno, rev_id = revision[0].in_history(b)
3438
b.repository.sign_revision(rev_id, gpg_strategy)
3468
b.repository.start_write_group()
3470
b.repository.sign_revision(rev_id, gpg_strategy)
3472
b.repository.abort_write_group()
3475
b.repository.commit_write_group()
3439
3476
elif len(revision) == 2:
3440
3477
# are they both on rh- if so we can walk between them
3441
3478
# might be nice to have a range helper for arbitrary
3446
3483
to_revno = b.revno()
3447
3484
if from_revno is None or to_revno is None:
3448
3485
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
3449
for revno in range(from_revno, to_revno + 1):
3450
b.repository.sign_revision(b.get_rev_id(revno),
3486
b.repository.start_write_group()
3488
for revno in range(from_revno, to_revno + 1):
3489
b.repository.sign_revision(b.get_rev_id(revno),
3492
b.repository.abort_write_group()
3495
b.repository.commit_write_group()
3453
3497
raise errors.BzrCommandError('Please supply either one revision, or a range.')
3526
3570
Option('force', help='Say yes to all questions.')]
3527
3571
takes_args = ['location?']
3573
encoding_type = 'replace'
3530
3575
def run(self, location=None,
3531
3576
dry_run=False, verbose=False,
3532
3577
revision=None, force=False):
3533
from bzrlib.log import log_formatter, show_log
3534
from bzrlib.uncommit import uncommit
3536
3578
if location is None:
3537
3579
location = u'.'
3538
3580
control, relpath = bzrdir.BzrDir.open_containing(location)
3544
3586
b = control.open_branch()
3588
if tree is not None:
3593
return self._run(b, tree, dry_run, verbose, revision, force)
3595
if tree is not None:
3600
def _run(self, b, tree, dry_run, verbose, revision, force):
3601
from bzrlib.log import log_formatter, show_log
3602
from bzrlib.uncommit import uncommit
3604
last_revno, last_rev_id = b.last_revision_info()
3547
3607
if revision is None:
3609
rev_id = last_rev_id
3550
3611
# 'bzr uncommit -r 10' actually means uncommit
3551
3612
# so that the final tree is at revno 10.
3552
3613
# but bzrlib.uncommit.uncommit() actually uncommits
3553
3614
# the revisions that are supplied.
3554
3615
# So we need to offset it by one
3555
revno = revision[0].in_history(b).revno+1
3616
revno = revision[0].in_history(b).revno + 1
3617
if revno <= last_revno:
3618
rev_id = b.get_rev_id(revno)
3557
if revno <= b.revno():
3558
rev_id = b.get_rev_id(revno)
3620
if rev_id is None or _mod_revision.is_null(rev_id):
3560
3621
self.outf.write('No revisions to uncommit.\n')
3665
3725
smart_server = medium.SmartServerPipeStreamMedium(
3666
3726
sys.stdin, sys.stdout, t)
3668
host = BZR_DEFAULT_INTERFACE
3728
host = medium.BZR_DEFAULT_INTERFACE
3669
3729
if port is None:
3670
port = BZR_DEFAULT_PORT
3730
port = medium.BZR_DEFAULT_PORT
3672
3732
if ':' in port:
3673
3733
host, port = port.split(':')
3898
3958
for that mirror.
3900
3960
Mail is sent using your preferred mail program. This should be transparent
3901
on Windows (it uses MAPI). On *nix, it requires the xdg-email utility. If
3902
the preferred client can't be found (or used), your editor will be used.
3961
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
3962
If the preferred client can't be found (or used), your editor will be used.
3904
3964
To use a specific mail program, set the mail_client configuration option.
3905
3965
(For Thunderbird 1.5, this works around some bugs.) Supported values for
3957
4017
def _run(self, submit_branch, revision, public_branch, remember, format,
3958
4018
no_bundle, no_patch, output, from_, mail_to, message):
3959
4019
from bzrlib.revision import NULL_REVISION
4020
branch = Branch.open_containing(from_)[0]
3960
4021
if output is None:
3961
4022
outfile = StringIO()
3962
4023
elif output == '-':
3963
4024
outfile = self.outf
3965
4026
outfile = open(output, 'wb')
4027
# we may need to write data into branch's repository to calculate
3967
branch = Branch.open_containing(from_)[0]
3968
4031
if output is None:
3969
4032
config = branch.get_config()
3970
4033
if mail_to is None:
3971
4034
mail_to = config.get_user_option('submit_to')
3973
raise errors.BzrCommandError('No mail-to address'
3975
4035
mail_client = config.get_mail_client()
3976
4036
if remember and submit_branch is None:
3977
4037
raise errors.BzrCommandError(
4256
4317
value_switches=True, enum_switch=False,
4257
4318
branch='Reconfigure to a branch.',
4258
4319
tree='Reconfigure to a tree.',
4259
checkout='Reconfigure to a checkout.'),
4320
checkout='Reconfigure to a checkout.',
4321
lightweight_checkout='Reconfigure to a lightweight'
4260
4323
Option('bind-to', help='Branch to bind checkout to.',
4262
4325
Option('force',
4275
4338
elif target_type == 'checkout':
4276
4339
reconfiguration = reconfigure.Reconfigure.to_checkout(directory,
4341
elif target_type == 'lightweight-checkout':
4342
reconfiguration = reconfigure.Reconfigure.to_lightweight_checkout(
4278
4344
reconfiguration.apply(force)
4347
class cmd_switch(Command):
4348
"""Set the branch of a checkout and update.
4350
For lightweight checkouts, this changes the branch being referenced.
4351
For heavyweight checkouts, this checks that there are no local commits
4352
versus the current bound branch, then it makes the local branch a mirror
4353
of the new location and binds to it.
4355
In both cases, the working tree is updated and uncommitted changes
4356
are merged. The user can commit or revert these as they desire.
4358
Pending merges need to be committed or reverted before using switch.
4361
takes_args = ['to_location']
4362
takes_options = [Option('force',
4363
help='Switch even if local commits will be lost.')
4366
def run(self, to_location, force=False):
4367
from bzrlib import switch
4368
to_branch = Branch.open(to_location)
4370
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
4371
switch.switch(control_dir, to_branch, force)
4372
note('Switched to branch: %s',
4373
urlutils.unescape_for_display(to_branch.base, 'utf-8'))
4281
4376
def _create_prefix(cur_transport):
4282
4377
needed = [cur_transport]
4283
4378
# Recurse upwards until we can create a directory successfully