1
# Copyright (C) 2004, 2005, 2006 by Canonical Ltd
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
5
5
# the Free Software Foundation; either version 2 of the License, or
6
6
# (at your option) any later version.
8
8
# This program is distributed in the hope that it will be useful,
9
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
11
# GNU General Public License for more details.
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
"""builtin bzr commands"""
21
from bzrlib.lazy_import import lazy_import
22
lazy_import(globals(), """
26
48
from bzrlib.branch import Branch
27
import bzrlib.bzrdir as bzrdir
28
from bzrlib.bundle.read_bundle import BundleReader
29
from bzrlib.bundle.apply_bundle import merge_bundle
30
from bzrlib.commands import Command, display_command
31
import bzrlib.errors as errors
32
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
33
NotBranchError, DivergedBranches, NotConflicted,
34
NoSuchFile, NoWorkingTree, FileInWrongBranch,
35
NotVersionedError, BadBundle)
36
from bzrlib.log import show_one_log
37
from bzrlib.merge import Merge3Merger
38
from bzrlib.option import Option
39
from bzrlib.progress import DummyProgress, ProgressPhase
49
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
50
from bzrlib.conflicts import ConflictList
40
51
from bzrlib.revision import common_ancestor
41
52
from bzrlib.revisionspec import RevisionSpec
43
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
44
from bzrlib.transport.local import LocalTransport
46
53
from bzrlib.workingtree import WorkingTree
56
from bzrlib.commands import Command, display_command
57
from bzrlib.option import Option, RegistryOption
58
from bzrlib.progress import DummyProgress, ProgressPhase
59
from bzrlib.trace import mutter, note, log_error, warning, is_quiet, info
49
62
def tree_files(file_list, default_branch=u'.'):
51
64
return internal_tree_files(file_list, default_branch)
52
except FileInWrongBranch, e:
53
raise BzrCommandError("%s is not in the same branch as %s" %
54
(e.path, file_list[0]))
65
except errors.FileInWrongBranch, e:
66
raise errors.BzrCommandError("%s is not in the same branch as %s" %
67
(e.path, file_list[0]))
57
70
# XXX: Bad function name; should possibly also be a class method of
67
80
:param file_list: Filenames to convert.
69
:param default_branch: Fallback tree path to use if file_list is empty or None.
82
:param default_branch: Fallback tree path to use if file_list is empty or
71
85
:return: workingtree, [relative_paths]
73
87
if file_list is None or len(file_list) == 0:
74
88
return WorkingTree.open_containing(default_branch)[0], file_list
75
tree = WorkingTree.open_containing(file_list[0])[0]
89
tree = WorkingTree.open_containing(osutils.realpath(file_list[0]))[0]
77
91
for filename in file_list:
79
new_list.append(tree.relpath(filename))
93
new_list.append(tree.relpath(osutils.dereference_path(filename)))
80
94
except errors.PathNotChild:
81
raise FileInWrongBranch(tree.branch, filename)
95
raise errors.FileInWrongBranch(tree.branch, filename)
82
96
return tree, new_list
99
@symbol_versioning.deprecated_function(symbol_versioning.zero_fifteen)
85
100
def get_format_type(typestring):
86
101
"""Parse and return a format specifier."""
87
if typestring == "weave":
88
return bzrdir.BzrDirFormat6()
102
# Have to use BzrDirMetaFormat1 directly, so that
103
# RepositoryFormat.set_default_format works
89
104
if typestring == "default":
90
105
return bzrdir.BzrDirMetaFormat1()
91
if typestring == "metaweave":
92
format = bzrdir.BzrDirMetaFormat1()
93
format.repository_format = bzrlib.repository.RepositoryFormat7()
95
if typestring == "knit":
96
format = bzrdir.BzrDirMetaFormat1()
97
format.repository_format = bzrlib.repository.RepositoryFormatKnit1()
99
msg = "Unknown bzr format %s. Current formats are: default, knit,\n" \
100
"metaweave and weave" % typestring
101
raise BzrCommandError(msg)
107
return bzrdir.format_registry.make_bzrdir(typestring)
109
msg = 'Unknown bzr format "%s". See "bzr help formats".' % typestring
110
raise errors.BzrCommandError(msg)
104
113
# TODO: Make sure no commands unconditionally use the working directory as a
150
178
# TODO: --no-recurse, --recurse options
152
180
takes_args = ['file*']
153
takes_options = ['all', 'show-ids', 'revision']
181
takes_options = ['show-ids', 'revision', 'short']
154
182
aliases = ['st', 'stat']
184
encoding_type = 'replace'
157
def run(self, all=False, show_ids=False, file_list=None, revision=None):
158
tree, file_list = tree_files(file_list)
187
def run(self, show_ids=False, file_list=None, revision=None, short=False):
160
188
from bzrlib.status import show_tree_status
161
show_tree_status(tree, show_unchanged=all, show_ids=show_ids,
162
specific_files=file_list, revision=revision)
190
tree, file_list = tree_files(file_list)
192
show_tree_status(tree, show_ids=show_ids,
193
specific_files=file_list, revision=revision,
165
198
class cmd_cat_revision(Command):
173
206
takes_args = ['revision_id?']
174
207
takes_options = ['revision']
208
# cat-revision is more for frontends so should be exact
177
212
def run(self, revision_id=None, revision=None):
179
214
if revision_id is not None and revision is not None:
180
raise BzrCommandError('You can only supply one of revision_id or --revision')
215
raise errors.BzrCommandError('You can only supply one of'
216
' revision_id or --revision')
181
217
if revision_id is None and revision is None:
182
raise BzrCommandError('You must supply either --revision or a revision_id')
218
raise errors.BzrCommandError('You must supply either'
219
' --revision or a revision_id')
183
220
b = WorkingTree.open_containing(u'.')[0].branch
222
# TODO: jam 20060112 should cat-revision always output utf-8?
184
223
if revision_id is not None:
185
sys.stdout.write(b.repository.get_revision_xml(revision_id))
224
self.outf.write(b.repository.get_revision_xml(revision_id).decode('utf-8'))
186
225
elif revision is not None:
187
226
for rev in revision:
189
raise BzrCommandError('You cannot specify a NULL revision.')
228
raise errors.BzrCommandError('You cannot specify a NULL'
190
230
revno, rev_id = rev.in_history(b)
191
sys.stdout.write(b.repository.get_revision_xml(rev_id))
231
self.outf.write(b.repository.get_revision_xml(rev_id).decode('utf-8'))
234
class cmd_remove_tree(Command):
235
"""Remove the working tree from a given branch/checkout.
237
Since a lightweight checkout is little more than a working tree
238
this will refuse to run against one.
241
takes_args = ['location?']
243
def run(self, location='.'):
244
d = bzrdir.BzrDir.open(location)
247
working = d.open_workingtree()
248
except errors.NoWorkingTree:
249
raise errors.BzrCommandError("No working tree to remove")
250
except errors.NotLocalUrl:
251
raise errors.BzrCommandError("You cannot remove the working tree of a "
254
working_path = working.bzrdir.root_transport.base
255
branch_path = working.branch.bzrdir.root_transport.base
256
if working_path != branch_path:
257
raise errors.BzrCommandError("You cannot remove the working tree from "
258
"a lightweight checkout")
260
d.destroy_workingtree()
194
263
class cmd_revno(Command):
195
264
"""Show current revision number.
197
This is equal to the number of revisions on this branch."""
266
This is equal to the number of revisions on this branch.
198
269
takes_args = ['location?']
200
272
def run(self, location=u'.'):
201
print Branch.open_containing(location)[0].revno()
273
self.outf.write(str(Branch.open_containing(location)[0].revno()))
274
self.outf.write('\n')
204
277
class cmd_revision_info(Command):
250
324
Adding a file whose parent directory is not versioned will
251
325
implicitly add the parent, and so on up to the root. This means
252
you should never need to explictly add a directory, they'll just
326
you should never need to explicitly add a directory, they'll just
253
327
get added when you add a file in the directory.
255
329
--dry-run will show which files would be added, but not actually
332
--file-ids-from will try to use the file ids from the supplied path.
333
It looks up ids trying to find a matching parent directory with the
334
same filename, and then by pure path.
258
336
takes_args = ['file*']
259
takes_options = ['no-recurse', 'dry-run', 'verbose']
337
takes_options = ['no-recurse', 'dry-run', 'verbose',
338
Option('file-ids-from', type=unicode,
339
help='Lookup file ids from here')]
340
encoding_type = 'replace'
261
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
342
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False,
262
344
import bzrlib.add
266
# This is pointless, but I'd rather not raise an error
267
action = bzrlib.add.add_action_null
269
action = bzrlib.add.add_action_print
271
action = bzrlib.add.add_action_add
347
if file_ids_from is not None:
349
base_tree, base_path = WorkingTree.open_containing(
351
except errors.NoWorkingTree:
352
base_branch, base_path = Branch.open_containing(
354
base_tree = base_branch.basis_tree()
356
action = bzrlib.add.AddFromBaseAction(base_tree, base_path,
357
to_file=self.outf, should_print=(not is_quiet()))
273
action = bzrlib.add.add_action_add_and_print
359
action = bzrlib.add.AddAction(to_file=self.outf,
360
should_print=(not is_quiet()))
275
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
363
base_tree.lock_read()
365
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
366
action=action, save=not dry_run)
368
if base_tree is not None:
277
370
if len(ignored) > 0:
279
372
for glob in sorted(ignored.keys()):
280
373
for path in ignored[glob]:
281
print "ignored %s matching \"%s\"" % (path, glob)
374
self.outf.write("ignored %s matching \"%s\"\n"
284
378
for glob, paths in ignored.items():
285
379
match_len += len(paths)
286
print "ignored %d file(s)." % match_len
287
print "If you wish to add some of these files, please add them"\
380
self.outf.write("ignored %d file(s).\n" % match_len)
381
self.outf.write("If you wish to add some of these files,"
382
" please add them by name.\n")
291
385
class cmd_mkdir(Command):
294
388
This is equivalent to creating the directory and then adding it.
296
391
takes_args = ['dir+']
392
encoding_type = 'replace'
298
394
def run(self, dir_list):
299
395
for d in dir_list:
301
397
wt, dd = WorkingTree.open_containing(d)
399
self.outf.write('added %s\n' % d)
306
402
class cmd_relpath(Command):
307
403
"""Show path of a file relative to root"""
308
405
takes_args = ['filename']
312
409
def run(self, filename):
410
# TODO: jam 20050106 Can relpath return a munged path if
411
# sys.stdout encoding cannot represent it?
313
412
tree, relpath = WorkingTree.open_containing(filename)
413
self.outf.write(relpath)
414
self.outf.write('\n')
317
417
class cmd_inventory(Command):
318
418
"""Show inventory of the current working copy or a revision.
320
420
It is possible to limit the output to a particular entry
321
type using the --kind option. For example; --kind file.
421
type using the --kind option. For example: --kind file.
423
It is also possible to restrict the list of files to a specific
424
set. For example: bzr inventory --show-ids this/file
323
431
takes_options = ['revision', 'show-ids', 'kind']
433
takes_args = ['file*']
326
def run(self, revision=None, show_ids=False, kind=None):
436
def run(self, revision=None, show_ids=False, kind=None, file_list=None):
327
437
if kind and kind not in ['file', 'directory', 'symlink']:
328
raise BzrCommandError('invalid kind specified')
329
tree = WorkingTree.open_containing(u'.')[0]
331
inv = tree.read_working_inventory()
333
if len(revision) > 1:
334
raise BzrCommandError('bzr inventory --revision takes'
335
' exactly one revision identifier')
336
inv = tree.branch.repository.get_revision_inventory(
337
revision[0].in_history(tree.branch).rev_id)
339
for path, entry in inv.entries():
438
raise errors.BzrCommandError('invalid kind specified')
440
work_tree, file_list = tree_files(file_list)
441
work_tree.lock_read()
443
if revision is not None:
444
if len(revision) > 1:
445
raise errors.BzrCommandError(
446
'bzr inventory --revision takes exactly one revision'
448
revision_id = revision[0].in_history(work_tree.branch).rev_id
449
tree = work_tree.branch.repository.revision_tree(revision_id)
451
extra_trees = [work_tree]
457
if file_list is not None:
458
file_ids = tree.paths2ids(file_list, trees=extra_trees,
459
require_versioned=True)
460
# find_ids_across_trees may include some paths that don't
462
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
463
for file_id in file_ids if file_id in tree)
465
entries = tree.inventory.entries()
468
if tree is not work_tree:
471
for path, entry in entries:
340
472
if kind and kind != entry.kind:
343
print '%-50s %s' % (path, entry.file_id)
475
self.outf.write('%-50s %s\n' % (path, entry.file_id))
477
self.outf.write(path)
478
self.outf.write('\n')
348
481
class cmd_mv(Command):
355
488
If the last argument is a versioned directory, all the other names
356
489
are moved into it. Otherwise, there must be exactly two arguments
357
and the file is changed to a new name, which must not already exist.
490
and the file is changed to a new name.
492
If OLDNAME does not exist on the filesystem but is versioned and
493
NEWNAME does exist on the filesystem but is not versioned, mv
494
assumes that the file has been manually moved and only updates
495
its internal inventory to reflect that change.
496
The same is valid when moving many SOURCE files to a DESTINATION.
359
498
Files cannot be moved between branches.
361
501
takes_args = ['names*']
502
takes_options = [Option("after", help="move only the bzr identifier"
503
" of the file (file has already been moved). Use this flag if"
504
" bzr is not able to detect this itself.")]
362
505
aliases = ['move', 'rename']
364
def run(self, names_list):
506
encoding_type = 'replace'
508
def run(self, names_list, after=False):
509
if names_list is None:
365
512
if len(names_list) < 2:
366
raise BzrCommandError("missing file argument")
513
raise errors.BzrCommandError("missing file argument")
367
514
tree, rel_names = tree_files(names_list)
369
516
if os.path.isdir(names_list[-1]):
370
517
# move into existing directory
371
for pair in tree.move(rel_names[:-1], rel_names[-1]):
372
print "%s => %s" % pair
518
for pair in tree.move(rel_names[:-1], rel_names[-1], after=after):
519
self.outf.write("%s => %s\n" % pair)
374
521
if len(names_list) != 2:
375
raise BzrCommandError('to mv multiple files the destination '
376
'must be a versioned directory')
377
tree.rename_one(rel_names[0], rel_names[1])
378
print "%s => %s" % (rel_names[0], rel_names[1])
522
raise errors.BzrCommandError('to mv multiple files the'
523
' destination must be a versioned'
525
tree.rename_one(rel_names[0], rel_names[1], after=after)
526
self.outf.write("%s => %s\n" % (rel_names[0], rel_names[1]))
381
529
class cmd_pull(Command):
389
537
from one into the other. Once one branch has merged, the other should
390
538
be able to pull it again.
392
If branches have diverged, you can use 'bzr merge' to pull the text changes
393
from one into the other. Once one branch has merged, the other should
394
be able to pull it again.
396
540
If you want to forget your local changes and just update your branch to
397
541
match the remote one, use pull --overwrite.
399
543
If there is no default location set, the first pull will set it. After
400
544
that, you can omit the location to use the default. To change the
401
default, use --remember.
545
default, use --remember. The value will only be saved if the remote
546
location can be accessed.
403
takes_options = ['remember', 'overwrite', 'revision', 'verbose']
549
takes_options = ['remember', 'overwrite', 'revision', 'verbose',
551
help='branch to pull into, '
552
'rather than the one containing the working directory',
404
557
takes_args = ['location?']
558
encoding_type = 'replace'
406
def run(self, location=None, remember=False, overwrite=False, revision=None, verbose=False):
560
def run(self, location=None, remember=False, overwrite=False,
561
revision=None, verbose=False,
563
from bzrlib.tag import _merge_tags_if_possible
407
564
# FIXME: too much stuff is in the command class
565
if directory is None:
409
tree_to = WorkingTree.open_containing(u'.')[0]
568
tree_to = WorkingTree.open_containing(directory)[0]
410
569
branch_to = tree_to.branch
411
except NoWorkingTree:
570
except errors.NoWorkingTree:
413
branch_to = Branch.open_containing(u'.')[0]
572
branch_to = Branch.open_containing(directory)[0]
575
if location is not None:
577
reader = bundle.read_bundle_from_url(location)
578
except errors.NotABundle:
579
pass # Continue on considering this url a Branch
414
581
stored_loc = branch_to.get_parent()
415
582
if location is None:
416
583
if stored_loc is None:
417
raise BzrCommandError("No pull location known or specified.")
584
raise errors.BzrCommandError("No pull location known or"
419
print "Using saved location: %s" % stored_loc
587
display_url = urlutils.unescape_for_display(stored_loc,
589
self.outf.write("Using saved location: %s\n" % display_url)
420
590
location = stored_loc
422
if branch_to.get_parent() is None or remember:
423
branch_to.set_parent(location)
425
branch_from = Branch.open(location)
592
if reader is not None:
593
install_bundle(branch_to.repository, reader)
594
branch_from = branch_to
596
branch_from = Branch.open(location)
598
if branch_to.get_parent() is None or remember:
599
branch_to.set_parent(branch_from.base)
427
602
if revision is None:
603
if reader is not None:
604
rev_id = reader.target
429
605
elif len(revision) == 1:
430
606
rev_id = revision[0].in_history(branch_from).rev_id
432
raise BzrCommandError('bzr pull --revision takes one value.')
608
raise errors.BzrCommandError('bzr pull --revision takes one value.')
434
610
old_rh = branch_to.revision_history()
435
611
if tree_to is not None:
436
count = tree_to.pull(branch_from, overwrite, rev_id)
612
result = tree_to.pull(branch_from, overwrite, rev_id,
613
delta.ChangeReporter(unversioned_filter=tree_to.is_ignored))
438
count = branch_to.pull(branch_from, overwrite, rev_id)
439
note('%d revision(s) pulled.' % (count,))
615
result = branch_to.pull(branch_from, overwrite, rev_id)
617
result.report(self.outf)
619
from bzrlib.log import show_changed_revisions
442
620
new_rh = branch_to.revision_history()
445
from bzrlib.log import show_changed_revisions
446
show_changed_revisions(branch_to, old_rh, new_rh)
621
show_changed_revisions(branch_to, old_rh, new_rh, to_file=self.outf)
449
624
class cmd_push(Command):
469
644
If there is no default push location set, the first push will set it.
470
645
After that, you can omit the location to use the default. To change the
471
default, use --remember.
646
default, use --remember. The value will only be saved if the remote
647
location can be accessed.
473
takes_options = ['remember', 'overwrite',
474
Option('create-prefix',
475
help='Create the path leading up to the branch '
476
'if it does not already exist')]
650
takes_options = ['remember', 'overwrite', 'verbose',
651
Option('create-prefix',
652
help='Create the path leading up to the branch '
653
'if it does not already exist'),
655
help='branch to push from, '
656
'rather than the one containing the working directory',
660
Option('use-existing-dir',
661
help='By default push will fail if the target'
662
' directory exists, but does not already'
663
' have a control directory. This flag will'
664
' allow push to proceed.'),
477
666
takes_args = ['location?']
667
encoding_type = 'replace'
479
669
def run(self, location=None, remember=False, overwrite=False,
480
create_prefix=False, verbose=False):
670
create_prefix=False, verbose=False,
671
use_existing_dir=False,
481
673
# FIXME: Way too big! Put this into a function called from the
483
from bzrlib.transport import get_transport
485
br_from = Branch.open_containing('.')[0]
675
if directory is None:
677
br_from = Branch.open_containing(directory)[0]
486
678
stored_loc = br_from.get_push_location()
487
679
if location is None:
488
680
if stored_loc is None:
489
raise BzrCommandError("No push location known or specified.")
681
raise errors.BzrCommandError("No push location known or specified.")
491
print "Using saved location: %s" % stored_loc
683
display_url = urlutils.unescape_for_display(stored_loc,
685
self.outf.write("Using saved location: %s\n" % display_url)
492
686
location = stored_loc
493
if br_from.get_push_location() is None or remember:
494
br_from.set_push_location(location)
688
to_transport = transport.get_transport(location)
689
location_url = to_transport.base
691
br_to = repository_to = dir_to = None
496
dir_to = bzrlib.bzrdir.BzrDir.open(location)
497
br_to = dir_to.open_branch()
498
except NotBranchError:
500
transport = get_transport(location).clone('..')
501
if not create_prefix:
693
dir_to = bzrdir.BzrDir.open_from_transport(to_transport)
694
except errors.NotBranchError:
695
pass # Didn't find anything
697
# If we can open a branch, use its direct repository, otherwise see
698
# if there is a repository without a branch.
700
br_to = dir_to.open_branch()
701
except errors.NotBranchError:
702
# Didn't find a branch, can we find a repository?
503
transport.mkdir(transport.relpath(location))
505
raise BzrCommandError("Parent directory of %s "
506
"does not exist." % location)
704
repository_to = dir_to.find_repository()
705
except errors.NoRepositoryPresent:
508
current = transport.base
509
needed = [(transport, transport.relpath(location))]
708
# Found a branch, so we must have found a repository
709
repository_to = br_to.repository
713
# The destination doesn't exist; create it.
714
# XXX: Refactor the create_prefix/no_create_prefix code into a
715
# common helper function
717
to_transport.mkdir('.')
718
except errors.FileExists:
719
if not use_existing_dir:
720
raise errors.BzrCommandError("Target directory %s"
721
" already exists, but does not have a valid .bzr"
722
" directory. Supply --use-existing-dir to push"
723
" there anyway." % location)
724
except errors.NoSuchFile:
725
if not create_prefix:
726
raise errors.BzrCommandError("Parent directory of %s"
728
"\nYou may supply --create-prefix to create all"
729
" leading parent directories."
732
cur_transport = to_transport
733
needed = [cur_transport]
734
# Recurse upwards until we can create a directory successfully
736
new_transport = cur_transport.clone('..')
737
if new_transport.base == cur_transport.base:
738
raise errors.BzrCommandError("Failed to create path"
742
new_transport.mkdir('.')
743
except errors.NoSuchFile:
744
needed.append(new_transport)
745
cur_transport = new_transport
749
# Now we only need to create child directories
512
transport, relpath = needed[-1]
513
transport.mkdir(relpath)
516
new_transport = transport.clone('..')
517
needed.append((new_transport,
518
new_transport.relpath(transport.base)))
519
if new_transport.base == transport.base:
520
raise BzrCommandError("Could not create "
522
dir_to = br_from.bzrdir.clone(location,
751
cur_transport = needed.pop()
752
cur_transport.mkdir('.')
754
# Now the target directory exists, but doesn't have a .bzr
755
# directory. So we need to create it, along with any work to create
756
# all of the dependent branches, etc.
757
dir_to = br_from.bzrdir.clone(location_url,
523
758
revision_id=br_from.last_revision())
524
759
br_to = dir_to.open_branch()
525
count = len(br_to.revision_history())
760
# TODO: Some more useful message about what was copied
761
note('Created new branch.')
762
# We successfully created the target, remember it
763
if br_from.get_push_location() is None or remember:
764
br_from.set_push_location(br_to.base)
765
elif repository_to is None:
766
# we have a bzrdir but no branch or repository
767
# XXX: Figure out what to do other than complain.
768
raise errors.BzrCommandError("At %s you have a valid .bzr control"
769
" directory, but not a branch or repository. This is an"
770
" unsupported configuration. Please move the target directory"
771
" out of the way and try again."
774
# We have a repository but no branch, copy the revisions, and then
776
last_revision_id = br_from.last_revision()
777
repository_to.fetch(br_from.repository,
778
revision_id=last_revision_id)
779
br_to = br_from.clone(dir_to, revision_id=last_revision_id)
780
note('Created new branch.')
781
if br_from.get_push_location() is None or remember:
782
br_from.set_push_location(br_to.base)
783
else: # We have a valid to branch
784
# We were able to connect to the remote location, so remember it
785
# we don't need to successfully push because of possible divergence.
786
if br_from.get_push_location() is None or remember:
787
br_from.set_push_location(br_to.base)
527
788
old_rh = br_to.revision_history()
531
792
except errors.NotLocalUrl:
532
793
warning('This transport does not update the working '
533
794
'tree of: %s' % (br_to.base,))
534
count = br_to.pull(br_from, overwrite)
535
except NoWorkingTree:
536
count = br_to.pull(br_from, overwrite)
795
push_result = br_from.push(br_to, overwrite)
796
except errors.NoWorkingTree:
797
push_result = br_from.push(br_to, overwrite)
538
count = tree_to.pull(br_from, overwrite)
539
except DivergedBranches:
540
raise BzrCommandError("These branches have diverged."
541
" Try a merge then push with overwrite.")
542
note('%d revision(s) pushed.' % (count,))
801
push_result = br_from.push(tree_to.branch, overwrite)
805
except errors.DivergedBranches:
806
raise errors.BzrCommandError('These branches have diverged.'
807
' Try using "merge" and then "push".')
808
if push_result is not None:
809
push_result.report(self.outf)
545
811
new_rh = br_to.revision_history()
546
812
if old_rh != new_rh:
547
813
# Something changed
548
814
from bzrlib.log import show_changed_revisions
549
show_changed_revisions(br_to, old_rh, new_rh)
815
show_changed_revisions(br_to, old_rh, new_rh,
818
# we probably did a clone rather than a push, so a message was
552
823
class cmd_branch(Command):
601
866
name = os.path.basename(to_location) + '\n'
868
to_transport = transport.get_transport(to_location)
603
os.mkdir(to_location)
605
if e.errno == errno.EEXIST:
606
raise BzrCommandError('Target directory "%s" already'
607
' exists.' % to_location)
608
if e.errno == errno.ENOENT:
609
raise BzrCommandError('Parent of "%s" does not exist.' %
870
to_transport.mkdir('.')
871
except errors.FileExists:
872
raise errors.BzrCommandError('Target directory "%s" already'
873
' exists.' % to_location)
874
except errors.NoSuchFile:
875
raise errors.BzrCommandError('Parent of "%s" does not exist.'
614
878
# preserve whatever source format we have.
615
dir = br_from.bzrdir.sprout(to_location, revision_id, basis_dir)
879
dir = br_from.bzrdir.sprout(to_transport.base,
880
revision_id, basis_dir)
616
881
branch = dir.open_branch()
617
except bzrlib.errors.NoSuchRevision:
882
except errors.NoSuchRevision:
883
to_transport.delete_tree('.')
619
884
msg = "The branch %s has no revision %s." % (from_location, revision[0])
620
raise BzrCommandError(msg)
621
except bzrlib.errors.UnlistableBranch:
885
raise errors.BzrCommandError(msg)
886
except errors.UnlistableBranch:
887
osutils.rmtree(to_location)
623
888
msg = "The branch %s cannot be used as a --basis" % (basis,)
624
raise BzrCommandError(msg)
889
raise errors.BzrCommandError(msg)
626
891
branch.control_files.put_utf8('branch-name', name)
892
_merge_tags_if_possible(br_from, branch)
628
893
note('Branched %d revision(s).' % branch.revno())
692
960
os.mkdir(to_location)
693
961
except OSError, e:
694
962
if e.errno == errno.EEXIST:
695
raise BzrCommandError('Target directory "%s" already'
696
' exists.' % to_location)
963
raise errors.BzrCommandError('Target directory "%s" already'
964
' exists.' % to_location)
697
965
if e.errno == errno.ENOENT:
698
raise BzrCommandError('Parent of "%s" does not exist.' %
966
raise errors.BzrCommandError('Parent of "%s" does not exist.'
702
old_format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
703
bzrlib.bzrdir.BzrDirFormat.set_default_format(bzrdir.BzrDirMetaFormat1())
706
checkout = bzrdir.BzrDirMetaFormat1().initialize(to_location)
707
bzrlib.branch.BranchReferenceFormat().initialize(checkout, source)
709
checkout_branch = bzrlib.bzrdir.BzrDir.create_branch_convenience(
710
to_location, force_new_tree=False)
711
checkout = checkout_branch.bzrdir
712
checkout_branch.bind(source)
713
if revision_id is not None:
714
rh = checkout_branch.revision_history()
715
checkout_branch.set_revision_history(rh[:rh.index(revision_id) + 1])
716
checkout.create_workingtree(revision_id)
718
bzrlib.bzrdir.BzrDirFormat.set_default_format(old_format)
970
source.create_checkout(to_location, revision_id, lightweight)
721
973
class cmd_renames(Command):
749
1009
'bzr revert' instead of 'bzr commit' after the update.
751
1011
takes_args = ['dir?']
753
1014
def run(self, dir='.'):
754
1015
tree = WorkingTree.open_containing(dir)[0]
1016
master = tree.branch.get_master_branch()
1017
if master is not None:
1020
tree.lock_tree_write()
757
if tree.last_revision() == tree.branch.last_revision():
1022
existing_pending_merges = tree.get_parent_ids()[1:]
1023
last_rev = tree.last_revision()
1024
if last_rev == tree.branch.last_revision():
758
1025
# may be up to date, check master too.
759
1026
master = tree.branch.get_master_branch()
760
if master is None or master.last_revision == tree.last_revision():
761
note("Tree is up to date.")
1027
if master is None or last_rev == master.last_revision():
1028
revno = tree.branch.revision_id_to_revno(last_rev)
1029
note("Tree is up to date at revision %d." % (revno,))
763
1031
conflicts = tree.update()
764
note('Updated to revision %d.' %
765
(tree.branch.revision_id_to_revno(tree.last_revision()),))
1032
revno = tree.branch.revision_id_to_revno(tree.last_revision())
1033
note('Updated to revision %d.' % (revno,))
1034
if tree.get_parent_ids()[1:] != existing_pending_merges:
1035
note('Your local commits will now show as pending merges with '
1036
"'bzr status', and can be committed with 'bzr commit'.")
766
1037
if conflicts != 0:
804
1075
takes_args = ['file*']
805
1076
takes_options = ['verbose', Option('new', help='remove newly-added files')]
806
1077
aliases = ['rm']
1078
encoding_type = 'replace'
808
1080
def run(self, file_list, verbose=False, new=False):
809
1081
tree, file_list = tree_files(file_list)
810
1082
if new is False:
811
1083
if file_list is None:
812
raise BzrCommandError('Specify one or more files to remove, or'
1084
raise errors.BzrCommandError('Specify one or more files to'
1085
' remove, or use --new.')
815
from bzrlib.delta import compare_trees
816
added = [compare_trees(tree.basis_tree(), tree,
817
specific_files=file_list).added]
818
file_list = sorted([f[0] for f in added[0]], reverse=True)
1087
added = tree.changes_from(tree.basis_tree(),
1088
specific_files=file_list).added
1089
file_list = sorted([f[0] for f in added], reverse=True)
819
1090
if len(file_list) == 0:
820
raise BzrCommandError('No matching files.')
821
tree.remove(file_list, verbose=verbose)
1091
raise errors.BzrCommandError('No matching files.')
1092
tree.remove(file_list, verbose=verbose, to_file=self.outf)
824
1095
class cmd_file_id(Command):
828
1099
same through all revisions where the file exists, even when it is
829
1100
moved or renamed.
832
1104
takes_args = ['filename']
833
1106
@display_command
834
1107
def run(self, filename):
835
1108
tree, relpath = WorkingTree.open_containing(filename)
836
i = tree.inventory.path2id(relpath)
838
raise BzrError("%r is not a versioned file" % filename)
1109
i = tree.path2id(relpath)
1111
raise errors.NotVersionedError(filename)
1113
self.outf.write(i + '\n')
843
1116
class cmd_file_path(Command):
844
1117
"""Print path of file_ids to a file or directory.
846
1119
This prints one line for each directory down to the target,
847
starting at the branch root."""
1120
starting at the branch root.
849
1124
takes_args = ['filename']
850
1126
@display_command
851
1127
def run(self, filename):
852
1128
tree, relpath = WorkingTree.open_containing(filename)
854
fid = inv.path2id(relpath)
856
raise BzrError("%r is not a versioned file" % filename)
857
for fip in inv.get_idpath(fid):
1129
fid = tree.path2id(relpath)
1131
raise errors.NotVersionedError(filename)
1132
segments = osutils.splitpath(relpath)
1133
for pos in range(1, len(segments) + 1):
1134
path = osutils.joinpath(segments[:pos])
1135
self.outf.write("%s\n" % tree.path2id(path))
861
1138
class cmd_reconcile(Command):
881
1158
def run(self, branch="."):
882
1159
from bzrlib.reconcile import reconcile
883
dir = bzrlib.bzrdir.BzrDir.open(branch)
1160
dir = bzrdir.BzrDir.open(branch)
887
1164
class cmd_revision_history(Command):
888
"""Display list of revision ids on this branch."""
1165
"""Display the list of revision ids on a branch."""
1166
takes_args = ['location?']
890
1170
@display_command
892
branch = WorkingTree.open_containing(u'.')[0].branch
893
for patchid in branch.revision_history():
1171
def run(self, location="."):
1172
branch = Branch.open_containing(location)[0]
1173
for revid in branch.revision_history():
1174
self.outf.write(revid)
1175
self.outf.write('\n')
897
1178
class cmd_ancestry(Command):
898
1179
"""List all revisions merged into this branch."""
1180
takes_args = ['location?']
900
1184
@display_command
902
tree = WorkingTree.open_containing(u'.')[0]
904
# FIXME. should be tree.last_revision
905
revision_ids = b.repository.get_ancestry(b.last_revision())
906
assert revision_ids[0] == None
1185
def run(self, location="."):
1187
wt = WorkingTree.open_containing(location)[0]
1188
except errors.NoWorkingTree:
1189
b = Branch.open(location)
1190
last_revision = b.last_revision()
1193
last_revision = wt.last_revision()
1195
revision_ids = b.repository.get_ancestry(last_revision)
1196
assert revision_ids[0] is None
907
1197
revision_ids.pop(0)
908
1198
for revision_id in revision_ids:
1199
self.outf.write(revision_id + '\n')
912
1202
class cmd_init(Command):
933
1223
takes_args = ['location?']
934
1224
takes_options = [
936
help='Specify a format for this branch. Current'
937
' formats are: default, knit, metaweave and'
938
' weave. Default is knit; metaweave and'
939
' weave are deprecated',
940
type=get_format_type),
942
def run(self, location=None, format=None):
943
from bzrlib.branch import Branch
1225
RegistryOption('format',
1226
help='Specify a format for this branch. '
1227
'See "help formats".',
1228
registry=bzrdir.format_registry,
1229
converter=bzrdir.format_registry.make_bzrdir,
1230
value_switches=True,
1231
title="Branch Format",
1233
Option('append-revisions-only',
1234
help='Never change revnos or the existing log.'
1235
' Append revisions to it only.')
1237
def run(self, location=None, format=None, append_revisions_only=False):
944
1238
if format is None:
945
format = get_format_type('default')
1239
format = bzrdir.format_registry.make_bzrdir('default')
946
1240
if location is None:
949
# The path has to exist to initialize a
950
# branch inside of it.
951
# Just using os.mkdir, since I don't
952
# believe that we want to create a bunch of
953
# locations if the user supplies an extended path
954
if not os.path.exists(location):
1243
to_transport = transport.get_transport(location)
1245
# The path has to exist to initialize a
1246
# branch inside of it.
1247
# Just using os.mkdir, since I don't
1248
# believe that we want to create a bunch of
1249
# locations if the user supplies an extended path
1250
# TODO: create-prefix
1252
to_transport.mkdir('.')
1253
except errors.FileExists:
957
1257
existing_bzrdir = bzrdir.BzrDir.open(location)
958
except NotBranchError:
1258
except errors.NotBranchError:
959
1259
# really a NotBzrDir error...
960
bzrdir.BzrDir.create_branch_convenience(location, format=format)
1260
branch = bzrdir.BzrDir.create_branch_convenience(to_transport.base,
1263
from bzrlib.transport.local import LocalTransport
962
1264
if existing_bzrdir.has_branch():
963
if existing_bzrdir.has_workingtree():
964
raise errors.AlreadyBranchError(location)
966
raise errors.BranchExistsWithoutWorkingTree(location)
1265
if (isinstance(to_transport, LocalTransport)
1266
and not existing_bzrdir.has_workingtree()):
1267
raise errors.BranchExistsWithoutWorkingTree(location)
1268
raise errors.AlreadyBranchError(location)
968
existing_bzrdir.create_branch()
1270
branch = existing_bzrdir.create_branch()
969
1271
existing_bzrdir.create_workingtree()
1272
if append_revisions_only:
1274
branch.set_append_revisions_only(True)
1275
except errors.UpgradeRequired:
1276
raise errors.BzrCommandError('This branch format cannot be set'
1277
' to append-revisions-only. Try --experimental-branch6')
972
1280
class cmd_init_repository(Command):
983
1291
cd trunk-checkout
984
1292
(add files here)
986
takes_args = ["location"]
987
takes_options = [Option('format',
988
help='Specify a format for this repository.'
989
' Current formats are: default, knit,'
990
' metaweave and weave. Default is knit;'
991
' metaweave and weave are deprecated',
992
type=get_format_type),
1294
takes_args = ["location"]
1295
takes_options = [RegistryOption('format',
1296
help='Specify a format for this repository. See'
1297
' "bzr help formats" for details',
1298
registry=bzrdir.format_registry,
1299
converter=bzrdir.format_registry.make_bzrdir,
1300
value_switches=True, title='Repository format'),
994
1302
help='Allows branches in repository to have'
995
1303
' a working tree')]
996
1304
aliases = ["init-repo"]
997
1305
def run(self, location, format=None, trees=False):
998
from bzrlib.transport import get_transport
999
1306
if format is None:
1000
format = get_format_type('default')
1001
transport = get_transport(location)
1002
if not transport.has('.'):
1004
newdir = format.initialize_on_transport(transport)
1307
format = bzrdir.format_registry.make_bzrdir('default')
1309
if location is None:
1312
to_transport = transport.get_transport(location)
1314
to_transport.mkdir('.')
1315
except errors.FileExists:
1318
newdir = format.initialize_on_transport(to_transport)
1005
1319
repo = newdir.create_repository(shared=True)
1006
1320
repo.set_make_working_trees(trees)
1009
1323
class cmd_diff(Command):
1010
"""Show differences in working tree.
1324
"""Show differences in the working tree or between revisions.
1012
1326
If files are listed, only the changes in those files are listed.
1013
1327
Otherwise, all changes for the tree are listed.
1050
1376
elif prefix == '1':
1051
1377
old_label = 'old/'
1052
1378
new_label = 'new/'
1054
if not ':' in prefix:
1055
raise BzrError("--diff-prefix expects two values separated by a colon")
1056
1380
old_label, new_label = prefix.split(":")
1382
raise BzrCommandError(
1383
"--prefix expects two values separated by a colon")
1385
if revision and len(revision) > 2:
1386
raise errors.BzrCommandError('bzr diff --revision takes exactly'
1387
' one or two revision specifiers')
1059
1390
tree1, file_list = internal_tree_files(file_list)
1063
except FileInWrongBranch:
1394
except errors.FileInWrongBranch:
1064
1395
if len(file_list) != 2:
1065
raise BzrCommandError("Files are in different branches")
1396
raise errors.BzrCommandError("Files are in different branches")
1067
1398
tree1, file1 = WorkingTree.open_containing(file_list[0])
1068
1399
tree2, file2 = WorkingTree.open_containing(file_list[1])
1069
1400
if file1 != "" or file2 != "":
1070
1401
# FIXME diff those two files. rbc 20051123
1071
raise BzrCommandError("Files are in different branches")
1402
raise errors.BzrCommandError("Files are in different branches")
1072
1403
file_list = None
1073
if revision is not None:
1074
if tree2 is not None:
1075
raise BzrCommandError("Can't specify -r with two branches")
1076
if (len(revision) == 1) or (revision[1].spec is None):
1077
return diff_cmd_helper(tree1, file_list, diff_options,
1079
old_label=old_label, new_label=new_label)
1080
elif len(revision) == 2:
1081
return diff_cmd_helper(tree1, file_list, diff_options,
1082
revision[0], revision[1],
1083
old_label=old_label, new_label=new_label)
1085
raise BzrCommandError('bzr diff --revision takes exactly one or two revision identifiers')
1087
if tree2 is not None:
1088
return show_diff_trees(tree1, tree2, sys.stdout,
1089
specific_files=file_list,
1090
external_diff_options=diff_options,
1091
old_label=old_label, new_label=new_label)
1093
return diff_cmd_helper(tree1, file_list, diff_options,
1094
old_label=old_label, new_label=new_label)
1404
except errors.NotBranchError:
1405
if (revision is not None and len(revision) == 2
1406
and not revision[0].needs_branch()
1407
and not revision[1].needs_branch()):
1408
# If both revision specs include a branch, we can
1409
# diff them without needing a local working tree
1410
tree1, tree2 = None, None
1414
if tree2 is not None:
1415
if revision is not None:
1416
# FIXME: but there should be a clean way to diff between
1417
# non-default versions of two trees, it's not hard to do
1419
raise errors.BzrCommandError(
1420
"Sorry, diffing arbitrary revisions across branches "
1421
"is not implemented yet")
1422
return show_diff_trees(tree1, tree2, sys.stdout,
1423
specific_files=file_list,
1424
external_diff_options=diff_options,
1425
old_label=old_label, new_label=new_label)
1427
return diff_cmd_helper(tree1, file_list, diff_options,
1428
revision_specs=revision,
1429
old_label=old_label, new_label=new_label)
1097
1432
class cmd_deleted(Command):
1103
1438
# directories with readdir, rather than stating each one. Same
1104
1439
# level of effort but possibly much less IO. (Or possibly not,
1105
1440
# if the directories are very large...)
1441
takes_options = ['show-ids']
1106
1443
@display_command
1107
1444
def run(self, show_ids=False):
1108
1445
tree = WorkingTree.open_containing(u'.')[0]
1109
old = tree.basis_tree()
1110
for path, ie in old.inventory.iter_entries():
1111
if not tree.has_id(ie.file_id):
1113
print '%-50s %s' % (path, ie.file_id)
1448
old = tree.basis_tree()
1451
for path, ie in old.inventory.iter_entries():
1452
if not tree.has_id(ie.file_id):
1453
self.outf.write(path)
1455
self.outf.write(' ')
1456
self.outf.write(ie.file_id)
1457
self.outf.write('\n')
1118
1464
class cmd_modified(Command):
1119
"""List files modified in working tree."""
1465
"""List files modified in working tree.
1467
See also: "bzr status".
1121
1472
@display_command
1123
from bzrlib.delta import compare_trees
1125
1474
tree = WorkingTree.open_containing(u'.')[0]
1126
td = compare_trees(tree.basis_tree(), tree)
1475
td = tree.changes_from(tree.basis_tree())
1128
1476
for path, id, kind, text_modified, meta_modified in td.modified:
1477
self.outf.write(path + '\n')
1133
1480
class cmd_added(Command):
1134
"""List files added in working tree."""
1481
"""List files added in working tree.
1483
See also: "bzr status".
1136
1488
@display_command
1138
1490
wt = WorkingTree.open_containing(u'.')[0]
1139
basis_inv = wt.basis_tree().inventory
1142
if file_id in basis_inv:
1144
path = inv.id2path(file_id)
1145
if not os.access(bzrlib.osutils.abspath(path), os.F_OK):
1493
basis = wt.basis_tree()
1496
basis_inv = basis.inventory
1499
if file_id in basis_inv:
1501
if inv.is_root(file_id) and len(basis_inv) == 0:
1503
path = inv.id2path(file_id)
1504
if not os.access(osutils.abspath(path), os.F_OK):
1506
self.outf.write(path + '\n')
1151
1513
class cmd_root(Command):
1152
1514
"""Show the tree root directory.
1215
1575
# find the file id to log:
1217
dir, fp = bzrdir.BzrDir.open_containing(location)
1218
b = dir.open_branch()
1577
tree, b, fp = bzrdir.BzrDir.open_containing_tree_or_branch(
1222
inv = dir.open_workingtree().inventory
1223
except (errors.NotBranchError, errors.NotLocalUrl):
1224
# either no tree, or is remote.
1225
inv = b.basis_tree().inventory
1226
file_id = inv.path2id(fp)
1581
tree = b.basis_tree()
1582
file_id = tree.path2id(fp)
1584
raise errors.BzrCommandError(
1585
"Path does not have any revision history: %s" %
1228
1588
# local dir only
1229
1589
# FIXME ? log the current subdir only RBC 20060203
1230
dir, relpath = bzrdir.BzrDir.open_containing('.')
1590
if revision is not None \
1591
and len(revision) > 0 and revision[0].get_branch():
1592
location = revision[0].get_branch()
1595
dir, relpath = bzrdir.BzrDir.open_containing(location)
1231
1596
b = dir.open_branch()
1233
if revision is None:
1236
elif len(revision) == 1:
1237
rev1 = rev2 = revision[0].in_history(b).revno
1238
elif len(revision) == 2:
1239
if revision[0].spec is None:
1240
# missing begin-range means first revision
1243
rev1 = revision[0].in_history(b).revno
1245
if revision[1].spec is None:
1246
# missing end-range means last known revision
1249
rev2 = revision[1].in_history(b).revno
1251
raise BzrCommandError('bzr log --revision takes one or two values.')
1253
# By this point, the revision numbers are converted to the +ve
1254
# form if they were supplied in the -ve form, so we can do
1255
# this comparison in relative safety
1257
(rev2, rev1) = (rev1, rev2)
1259
mutter('encoding log as %r', bzrlib.user_encoding)
1261
# use 'replace' so that we don't abort if trying to write out
1262
# in e.g. the default C locale.
1263
outf = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
1265
if (log_format == None):
1266
default = bzrlib.config.BranchConfig(b).log_format()
1267
log_format = get_log_format(long=long, short=short, line=line, default=default)
1269
lf = log_formatter(log_format,
1272
show_timezone=timezone)
1278
direction=direction,
1279
start_revision=rev1,
1600
if revision is None:
1603
elif len(revision) == 1:
1604
rev1 = rev2 = revision[0].in_history(b).revno
1605
elif len(revision) == 2:
1606
if revision[1].get_branch() != revision[0].get_branch():
1607
# b is taken from revision[0].get_branch(), and
1608
# show_log will use its revision_history. Having
1609
# different branches will lead to weird behaviors.
1610
raise errors.BzrCommandError(
1611
"Log doesn't accept two revisions in different"
1613
if revision[0].spec is None:
1614
# missing begin-range means first revision
1617
rev1 = revision[0].in_history(b).revno
1619
if revision[1].spec is None:
1620
# missing end-range means last known revision
1623
rev2 = revision[1].in_history(b).revno
1625
raise errors.BzrCommandError(
1626
'bzr log --revision takes one or two values.')
1628
# By this point, the revision numbers are converted to the +ve
1629
# form if they were supplied in the -ve form, so we can do
1630
# this comparison in relative safety
1632
(rev2, rev1) = (rev1, rev2)
1634
if log_format is None:
1635
log_format = log.log_formatter_registry.get_default(b)
1637
lf = log_format(show_ids=show_ids, to_file=self.outf,
1638
show_timezone=timezone)
1644
direction=direction,
1645
start_revision=rev1,
1284
1652
def get_log_format(long=False, short=False, line=False, default='long'):
1323
1694
Option('ignored', help='Print ignored files'),
1325
1696
Option('null', help='Null separate the files'),
1327
1699
@display_command
1328
1700
def run(self, revision=None, verbose=False,
1329
1701
non_recursive=False, from_root=False,
1330
1702
unknown=False, versioned=False, ignored=False,
1703
null=False, kind=None, show_ids=False, path=None):
1705
if kind and kind not in ('file', 'directory', 'symlink'):
1706
raise errors.BzrCommandError('invalid kind specified')
1333
1708
if verbose and null:
1334
raise BzrCommandError('Cannot set both --verbose and --null')
1709
raise errors.BzrCommandError('Cannot set both --verbose and --null')
1335
1710
all = not (unknown or versioned or ignored)
1337
1712
selection = {'I':ignored, '?':unknown, 'V':versioned}
1339
tree, relpath = WorkingTree.open_containing(u'.')
1719
raise errors.BzrCommandError('cannot specify both --from-root'
1723
tree, branch, relpath = bzrdir.BzrDir.open_containing_tree_or_branch(
1344
1729
if revision is not None:
1345
tree = tree.branch.repository.revision_tree(
1346
revision[0].in_history(tree.branch).rev_id)
1347
for fp, fc, kind, fid, entry in tree.list_files():
1348
if fp.startswith(relpath):
1349
fp = fp[len(relpath):]
1350
if non_recursive and '/' in fp:
1352
if not all and not selection[fc]:
1355
kindch = entry.kind_character()
1356
print '%-8s %s%s' % (fc, fp, kindch)
1358
sys.stdout.write(fp)
1359
sys.stdout.write('\0')
1730
tree = branch.repository.revision_tree(
1731
revision[0].in_history(branch).rev_id)
1733
tree = branch.basis_tree()
1737
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1738
if fp.startswith(relpath):
1739
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1740
if non_recursive and '/' in fp:
1742
if not all and not selection[fc]:
1744
if kind is not None and fkind != kind:
1747
kindch = entry.kind_character()
1748
outstring = '%-8s %s%s' % (fc, fp, kindch)
1749
if show_ids and fid is not None:
1750
outstring = "%-50s %s" % (outstring, fid)
1751
self.outf.write(outstring + '\n')
1753
self.outf.write(fp + '\0')
1756
self.outf.write(fid)
1757
self.outf.write('\0')
1765
self.outf.write('%-50s %s\n' % (fp, my_id))
1767
self.outf.write(fp + '\n')
1365
1772
class cmd_unknowns(Command):
1366
"""List unknown files."""
1773
"""List unknown files.
1775
See also: "bzr ls --unknown".
1367
1780
@display_command
1369
from bzrlib.osutils import quotefn
1370
1782
for f in WorkingTree.open_containing(u'.')[0].unknowns():
1783
self.outf.write(osutils.quotefn(f) + '\n')
1374
1786
class cmd_ignore(Command):
1375
"""Ignore a command or pattern.
1787
"""Ignore specified files or patterns.
1377
1789
To remove patterns from the ignore list, edit the .bzrignore file.
1379
If the pattern contains a slash, it is compared to the whole path
1380
from the branch root. Otherwise, it is compared to only the last
1381
component of the path. To match a file only in the root directory,
1384
Ignore patterns are case-insensitive on case-insensitive systems.
1386
Note: wildcards must be quoted from the shell on Unix.
1791
Trailing slashes on patterns are ignored.
1792
If the pattern contains a slash or is a regular expression, it is compared
1793
to the whole path from the branch root. Otherwise, it is compared to only
1794
the last component of the path. To match a file only in the root
1795
directory, prepend './'.
1797
Ignore patterns specifying absolute paths are not allowed.
1799
Ignore patterns may include globbing wildcards such as:
1800
? - Matches any single character except '/'
1801
* - Matches 0 or more characters except '/'
1802
/**/ - Matches 0 or more directories in a path
1803
[a-z] - Matches a single character from within a group of characters
1805
Ignore patterns may also be Python regular expressions.
1806
Regular expression ignore patterns are identified by a 'RE:' prefix
1807
followed by the regular expression. Regular expression ignore patterns
1808
may not include named or numbered groups.
1810
Note: ignore patterns containing shell wildcards must be quoted from
1389
1814
bzr ignore ./Makefile
1390
1815
bzr ignore '*.class'
1816
bzr ignore 'lib/**/*.o'
1817
bzr ignore 'RE:lib/.*\.o'
1392
# TODO: Complain if the filename is absolute
1393
takes_args = ['name_pattern']
1819
takes_args = ['name_pattern*']
1821
Option('old-default-rules',
1822
help='Out the ignore rules bzr < 0.9 always used.')
1395
def run(self, name_pattern):
1825
def run(self, name_pattern_list=None, old_default_rules=None):
1396
1826
from bzrlib.atomicfile import AtomicFile
1827
if old_default_rules is not None:
1828
# dump the rules and exit
1829
for pattern in ignores.OLD_DEFAULTS:
1832
if not name_pattern_list:
1833
raise errors.BzrCommandError("ignore requires at least one "
1834
"NAME_PATTERN or --old-default-rules")
1835
name_pattern_list = [globbing.normalize_pattern(p)
1836
for p in name_pattern_list]
1837
for name_pattern in name_pattern_list:
1838
if (name_pattern[0] == '/' or
1839
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1840
raise errors.BzrCommandError(
1841
"NAME_PATTERN should not be an absolute path")
1399
1842
tree, relpath = WorkingTree.open_containing(u'.')
1400
1843
ifn = tree.abspath('.bzrignore')
1402
1844
if os.path.exists(ifn):
1403
1845
f = open(ifn, 'rt')
1486
1931
tgz .tar.gz, .tgz
1489
takes_args = ['dest']
1934
takes_args = ['dest', 'branch?']
1490
1935
takes_options = ['revision', 'format', 'root']
1491
def run(self, dest, revision=None, format=None, root=None):
1936
def run(self, dest, branch=None, revision=None, format=None, root=None):
1493
1937
from bzrlib.export import export
1494
tree = WorkingTree.open_containing(u'.')[0]
1940
tree = WorkingTree.open_containing(u'.')[0]
1943
b = Branch.open(branch)
1496
1945
if revision is None:
1497
1946
# should be tree.last_revision FIXME
1498
1947
rev_id = b.last_revision()
1500
1949
if len(revision) != 1:
1501
raise BzrError('bzr export --revision takes exactly 1 argument')
1950
raise errors.BzrCommandError('bzr export --revision takes exactly 1 argument')
1502
1951
rev_id = revision[0].in_history(b).rev_id
1503
1952
t = b.repository.revision_tree(rev_id)
1505
1954
export(t, dest, format, root)
1506
1955
except errors.NoSuchExportFormat, e:
1507
raise BzrCommandError('Unsupported export format: %s' % e.format)
1956
raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
1510
1959
class cmd_cat(Command):
1511
1960
"""Write a file's text from a previous revision."""
1513
takes_options = ['revision']
1962
takes_options = ['revision', 'name-from-revision']
1514
1963
takes_args = ['filename']
1964
encoding_type = 'exact'
1516
1966
@display_command
1517
def run(self, filename, revision=None):
1967
def run(self, filename, revision=None, name_from_revision=False):
1518
1968
if revision is not None and len(revision) != 1:
1519
raise BzrCommandError("bzr cat --revision takes exactly one number")
1969
raise errors.BzrCommandError("bzr cat --revision takes exactly"
1522
tree, relpath = WorkingTree.open_containing(filename)
1524
except NotBranchError:
1974
tree, b, relpath = \
1975
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
1976
except errors.NotBranchError:
1979
if revision is not None and revision[0].get_branch() is not None:
1980
b = Branch.open(revision[0].get_branch())
1527
1981
if tree is None:
1528
b, relpath = Branch.open_containing(filename)
1982
tree = b.basis_tree()
1529
1983
if revision is None:
1530
1984
revision_id = b.last_revision()
1532
1986
revision_id = revision[0].in_history(b).rev_id
1533
b.print_file(relpath, revision_id)
1988
cur_file_id = tree.path2id(relpath)
1989
rev_tree = b.repository.revision_tree(revision_id)
1990
old_file_id = rev_tree.path2id(relpath)
1992
if name_from_revision:
1993
if old_file_id is None:
1994
raise errors.BzrCommandError("%r is not present in revision %s"
1995
% (filename, revision_id))
1997
rev_tree.print_file(old_file_id)
1998
elif cur_file_id is not None:
1999
rev_tree.print_file(cur_file_id)
2000
elif old_file_id is not None:
2001
rev_tree.print_file(old_file_id)
2003
raise errors.BzrCommandError("%r is not present in revision %s" %
2004
(filename, revision_id))
1536
2007
class cmd_local_time_offset(Command):
1611
2078
if local and not tree.branch.get_bound_location():
1612
2079
raise errors.LocalRequiresBoundBranch()
1613
if message is None and not file:
1614
template = make_commit_message_template(tree, selected_list)
1615
message = edit_commit_message(template)
1617
raise BzrCommandError("please specify a commit message"
1618
" with either --message or --file")
1619
elif message and file:
1620
raise BzrCommandError("please specify either --message or --file")
1624
message = codecs.open(file, 'rt', bzrlib.user_encoding).read()
1627
raise BzrCommandError("empty commit message specified")
2081
def get_message(commit_obj):
2082
"""Callback to get commit message"""
2083
my_message = message
2084
if my_message is None and not file:
2085
template = make_commit_message_template(tree, selected_list)
2086
my_message = edit_commit_message(template)
2087
if my_message is None:
2088
raise errors.BzrCommandError("please specify a commit"
2089
" message with either --message or --file")
2090
elif my_message and file:
2091
raise errors.BzrCommandError(
2092
"please specify either --message or --file")
2094
my_message = codecs.open(file, 'rt',
2095
bzrlib.user_encoding).read()
2096
if my_message == "":
2097
raise errors.BzrCommandError("empty commit message specified")
1630
2101
reporter = ReportCommitToLog()
1632
2103
reporter = NullCommitReporter()
1635
tree.commit(message, specific_files=selected_list,
2106
tree.commit(message_callback=get_message,
2107
specific_files=selected_list,
1636
2108
allow_pointless=unchanged, strict=strict, local=local,
1637
2109
reporter=reporter)
1638
2110
except PointlessCommit:
1639
2111
# FIXME: This should really happen before the file is read in;
1640
2112
# perhaps prepare the commit; get the message; then actually commit
1641
raise BzrCommandError("no changes to commit",
1642
["use --unchanged to commit anyhow"])
2113
raise errors.BzrCommandError("no changes to commit."
2114
" use --unchanged to commit anyhow")
1643
2115
except ConflictsInTree:
1644
raise BzrCommandError("Conflicts detected in working tree. "
1645
'Use "bzr conflicts" to list, "bzr resolve FILE" to resolve.')
2116
raise errors.BzrCommandError('Conflicts detected in working '
2117
'tree. Use "bzr conflicts" to list, "bzr resolve FILE" to'
1646
2119
except StrictCommitFailed:
1647
raise BzrCommandError("Commit refused because there are unknown "
1648
"files in the working tree.")
2120
raise errors.BzrCommandError("Commit refused because there are"
2121
" unknown files in the working tree.")
1649
2122
except errors.BoundBranchOutOfDate, e:
1650
raise BzrCommandError(str(e)
1651
+ ' Either unbind, update, or'
1652
' pass --local to commit.')
2123
raise errors.BzrCommandError(str(e) + "\n"
2124
'To commit to master branch, run update and then commit.\n'
2125
'You can also pass --local to commit to continue working '
1655
2129
class cmd_check(Command):
1700
2155
takes_args = ['url?']
1701
2156
takes_options = [
1703
help='Upgrade to a specific format. Current formats'
1704
' are: default, knit, metaweave and weave.'
1705
' Default is knit; metaweave and weave are'
1707
type=get_format_type),
2157
RegistryOption('format',
2158
help='Upgrade to a specific format. See "bzr help'
2159
' formats" for details',
2160
registry=bzrdir.format_registry,
2161
converter=bzrdir.format_registry.make_bzrdir,
2162
value_switches=True, title='Branch format'),
1711
2165
def run(self, url='.', format=None):
1712
2166
from bzrlib.upgrade import upgrade
1713
2167
if format is None:
1714
format = get_format_type('default')
2168
format = bzrdir.format_registry.make_bzrdir('default')
1715
2169
upgrade(url, format)
1718
2172
class cmd_whoami(Command):
1719
"""Show bzr user id."""
1720
takes_options = ['email']
2173
"""Show or set bzr user id.
2177
bzr whoami 'Frank Chu <fchu@example.com>'
2179
takes_options = [ Option('email',
2180
help='display email address only'),
2182
help='set identity for the current branch instead of '
2185
takes_args = ['name?']
2186
encoding_type = 'replace'
1722
2188
@display_command
1723
def run(self, email=False):
2189
def run(self, email=False, branch=False, name=None):
2191
# use branch if we're inside one; otherwise global config
2193
c = Branch.open_containing('.')[0].get_config()
2194
except errors.NotBranchError:
2195
c = config.GlobalConfig()
2197
self.outf.write(c.user_email() + '\n')
2199
self.outf.write(c.username() + '\n')
2202
# display a warning if an email address isn't included in the given name.
1725
b = WorkingTree.open_containing(u'.')[0].branch
1726
config = bzrlib.config.BranchConfig(b)
1727
except NotBranchError:
1728
config = bzrlib.config.GlobalConfig()
2204
config.extract_email_address(name)
2205
except errors.NoEmailInUsername, e:
2206
warning('"%s" does not seem to contain an email address. '
2207
'This is allowed, but not recommended.', name)
1731
print config.user_email()
2209
# use global config unless --branch given
2211
c = Branch.open_containing('.')[0].get_config()
1733
print config.username()
2213
c = config.GlobalConfig()
2214
c.set_user_option('email', name)
1736
2217
class cmd_nick(Command):
1755
2236
class cmd_selftest(Command):
1756
2237
"""Run internal test suite.
1758
This creates temporary test directories in the working directory,
1759
but not existing data is affected. These directories are deleted
1760
if the tests pass, or left behind to help in debugging if they
1761
fail and --keep-output is specified.
2239
This creates temporary test directories in the working directory, but not
2240
existing data is affected. These directories are deleted if the tests
2241
pass, or left behind to help in debugging if they fail and --keep-output
1763
If arguments are given, they are regular expressions that say
1764
which tests should run.
2244
If arguments are given, they are regular expressions that say which tests
2245
should run. Tests matching any expression are run, and other tests are
2248
Alternatively if --first is given, matching tests are run first and then
2249
all other tests are run. This is useful if you have been working in a
2250
particular area, but want to make sure nothing else was broken.
1766
2252
If the global option '--no-plugins' is given, plugins are not loaded
1767
2253
before running the selftests. This has two effects: features provided or
1768
2254
modified by plugins will not be tested, and tests provided by plugins will
1772
2258
bzr selftest ignore
2259
run only tests relating to 'ignore'
1773
2260
bzr --no-plugins selftest -v
2261
disable plugins and list tests as they're run
2263
For each test, that needs actual disk access, bzr create their own
2264
subdirectory in the temporary testing directory (testXXXX.tmp).
2265
By default the name of such subdirectory is based on the name of the test.
2266
If option '--numbered-dirs' is given, bzr will use sequent numbers
2267
of running tests to create such subdirectories. This is default behavior
2268
on Windows because of path length limitation.
1775
2270
# TODO: --list should give a list of all available tests
1805
2300
Option('lsprof-timed',
1806
2301
help='generate lsprof output for benchmarked'
1807
2302
' sections of code.'),
2303
Option('cache-dir', type=str,
2304
help='a directory to cache intermediate'
2305
' benchmark steps'),
2306
Option('clean-output',
2307
help='clean temporary tests directories'
2308
' without running tests'),
2310
help='run all tests, but run specified tests first',
2312
Option('numbered-dirs',
2313
help='use numbered dirs for TestCaseInTempDir'),
2315
encoding_type = 'replace'
1810
2317
def run(self, testspecs_list=None, verbose=None, one=False,
1811
2318
keep_output=False, transport=None, benchmark=None,
2319
lsprof_timed=None, cache_dir=None, clean_output=False,
2320
first=False, numbered_dirs=None):
1813
2321
import bzrlib.ui
1814
2322
from bzrlib.tests import selftest
1815
2323
import bzrlib.benchmarks as benchmarks
1816
# we don't want progress meters from the tests to go to the
1817
# real output; and we don't want log messages cluttering up
1819
save_ui = bzrlib.ui.ui_factory
1820
print '%10s: %s' % ('bzr', bzrlib.osutils.realpath(sys.argv[0]))
2324
from bzrlib.benchmarks import tree_creator
2327
from bzrlib.tests import clean_selftest_output
2328
clean_selftest_output()
2331
if numbered_dirs is None and sys.platform == 'win32':
2332
numbered_dirs = True
2334
if cache_dir is not None:
2335
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2336
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1821
2337
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1823
bzrlib.trace.info('running tests...')
2339
if testspecs_list is not None:
2340
pattern = '|'.join(testspecs_list)
2344
test_suite_factory = benchmarks.test_suite
2347
# TODO: should possibly lock the history file...
2348
benchfile = open(".perf_history", "at", buffering=1)
2350
test_suite_factory = None
1825
bzrlib.ui.ui_factory = bzrlib.ui.SilentUIFactory()
1826
if testspecs_list is not None:
1827
pattern = '|'.join(testspecs_list)
1831
test_suite_factory = benchmarks.test_suite
1835
test_suite_factory = None
1838
2355
result = selftest(verbose=verbose,
1839
2356
pattern=pattern,
1840
2357
stop_on_failure=one,
1841
2358
keep_output=keep_output,
1842
2359
transport=transport,
1843
2360
test_suite_factory=test_suite_factory,
1844
lsprof_timed=lsprof_timed)
1846
bzrlib.trace.info('tests passed')
1848
bzrlib.trace.info('tests failed')
1849
return int(not result)
2361
lsprof_timed=lsprof_timed,
2362
bench_history=benchfile,
2363
matching_tests_first=first,
2364
numbered_dirs=numbered_dirs,
1851
bzrlib.ui.ui_factory = save_ui
1854
def _get_bzr_branch():
1855
"""If bzr is run from a branch, return Branch or None"""
1856
import bzrlib.errors
1857
from bzrlib.branch import Branch
1858
from bzrlib.osutils import abspath
1859
from os.path import dirname
1862
branch = Branch.open(dirname(abspath(dirname(__file__))))
1864
except bzrlib.errors.BzrError:
1869
print "bzr (bazaar-ng) %s" % bzrlib.__version__
1870
# is bzrlib itself in a branch?
1871
branch = _get_bzr_branch()
1873
rh = branch.revision_history()
1875
print " bzr checkout, revision %d" % (revno,)
1876
print " nick: %s" % (branch.nick,)
1878
print " revid: %s" % (rh[-1],)
1879
print "Using python interpreter:", sys.executable
1881
print "Using python standard library:", os.path.dirname(site.__file__)
1882
print "Using bzrlib:",
1883
if len(bzrlib.__path__) > 1:
1884
# print repr, which is a good enough way of making it clear it's
1885
# more than one element (eg ['/foo/bar', '/foo/bzr'])
1886
print repr(bzrlib.__path__)
1888
print bzrlib.__path__[0]
1891
print bzrlib.__copyright__
1892
print "http://bazaar-vcs.org/"
1894
print "bzr comes with ABSOLUTELY NO WARRANTY. bzr is free software, and"
1895
print "you may use, modify and redistribute it under the terms of the GNU"
1896
print "General Public License version 2 or later."
2367
if benchfile is not None:
2370
info('tests passed')
2372
info('tests failed')
2373
return int(not result)
1899
2376
class cmd_version(Command):
1900
2377
"""Show version of bzr."""
1901
2379
@display_command
2381
from bzrlib.version import show_version
1905
2385
class cmd_rocks(Command):
1906
2386
"""Statement of optimism."""
1908
2390
@display_command
1910
print "it sure does!"
2392
print "It sure does!"
1913
2395
class cmd_find_merge_base(Command):
1914
"""Find and print a base revision for merging two branches.
2396
"""Find and print a base revision for merging two branches."""
1916
2397
# TODO: Options to specify revisions on either side, as if
1917
2398
# merging only part of the history.
1918
2399
takes_args = ['branch', 'other']
1937
2415
base_rev_id = common_ancestor(last1, last2, source)
1939
2417
print 'merge base is revision %s' % base_rev_id
1943
if base_revno is None:
1944
raise bzrlib.errors.UnrelatedBranches()
1946
print ' r%-6d in %s' % (base_revno, branch)
1948
other_revno = branch2.revision_id_to_revno(base_revid)
1950
print ' r%-6d in %s' % (other_revno, other)
1954
2420
class cmd_merge(Command):
1955
2421
"""Perform a three-way merge.
1957
The branch is the branch you will merge from. By default, it will
1958
merge the latest revision. If you specify a revision, that
1959
revision will be merged. If you specify two revisions, the first
1960
will be used as a BASE, and the second one as OTHER. Revision
1961
numbers are always relative to the specified branch.
2423
The branch is the branch you will merge from. By default, it will merge
2424
the latest revision. If you specify a revision, that revision will be
2425
merged. If you specify two revisions, the first will be used as a BASE,
2426
and the second one as OTHER. Revision numbers are always relative to the
1963
2429
By default, bzr will try to merge in all new work from the other
1964
2430
branch, automatically determining an appropriate base. If this
1994
2465
takes_args = ['branch?']
1995
2466
takes_options = ['revision', 'force', 'merge-type', 'reprocess', 'remember',
1996
Option('show-base', help="Show base revision text in "
2000
from merge import merge_type_help
2001
from inspect import getdoc
2002
return getdoc(self) + '\n' + merge_type_help()
2467
Option('show-base', help="Show base revision text in "
2469
Option('uncommitted', help='Apply uncommitted changes'
2470
' from a working copy, instead of branch changes'),
2471
Option('pull', help='If the destination is already'
2472
' completely merged into the source, pull from the'
2473
' source rather than merging. When this happens,'
2474
' you do not need to commit the result.'),
2476
help='Branch to merge into, '
2477
'rather than the one containing the working directory',
2004
2483
def run(self, branch=None, revision=None, force=False, merge_type=None,
2005
show_base=False, reprocess=False, remember=False):
2484
show_base=False, reprocess=False, remember=False,
2485
uncommitted=False, pull=False,
2488
from bzrlib.tag import _merge_tags_if_possible
2006
2489
if merge_type is None:
2007
merge_type = Merge3Merger
2010
tree = WorkingTree.open_containing(u'.')[0]
2012
if branch is not None:
2013
reader = BundleReader(file(branch, 'rb'))
2017
if e.errno not in (errno.ENOENT, errno.EISDIR):
2022
if reader is not None:
2023
conflicts = merge_bundle(reader, tree, not force, merge_type,
2024
reprocess, show_base)
2030
stored_loc = tree.branch.get_parent()
2032
if stored_loc is None:
2033
raise BzrCommandError("No merge branch known or specified.")
2035
print "Using saved branch: %s" % stored_loc
2038
if tree.branch.get_parent() is None or remember:
2039
tree.branch.set_parent(branch)
2490
merge_type = _mod_merge.Merge3Merger
2492
if directory is None: directory = u'.'
2493
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2494
# inventory. Because merge is a mutating operation, it really
2495
# should be a lock_write() for the whole cmd_merge operation.
2496
# However, cmd_merge open's its own tree in _merge_helper, which
2497
# means if we lock here, the later lock_write() will always block.
2498
# Either the merge helper code should be updated to take a tree,
2499
# (What about tree.merge_from_branch?)
2500
tree = WorkingTree.open_containing(directory)[0]
2501
change_reporter = delta.ChangeReporter(
2502
unversioned_filter=tree.is_ignored)
2504
if branch is not None:
2506
reader = bundle.read_bundle_from_url(branch)
2507
except errors.NotABundle:
2508
pass # Continue on considering this url a Branch
2510
conflicts = merge_bundle(reader, tree, not force, merge_type,
2511
reprocess, show_base, change_reporter)
2517
if revision is None \
2518
or len(revision) < 1 or revision[0].needs_branch():
2519
branch = self._get_remembered_parent(tree, branch, 'Merging from')
2041
2521
if revision is None or len(revision) < 1:
2043
other = [branch, -1]
2524
other = [branch, None]
2527
other = [branch, -1]
2044
2528
other_branch, path = Branch.open_containing(branch)
2531
raise errors.BzrCommandError('Cannot use --uncommitted and'
2532
' --revision at the same time.')
2533
branch = revision[0].get_branch() or branch
2046
2534
if len(revision) == 1:
2047
2535
base = [None, None]
2048
2536
other_branch, path = Branch.open_containing(branch)
2052
2540
assert len(revision) == 2
2053
2541
if None in revision:
2054
raise BzrCommandError(
2055
"Merge doesn't permit that revision specifier.")
2056
b, path = Branch.open_containing(branch)
2058
base = [branch, revision[0].in_history(b).revno]
2059
other = [branch, revision[1].in_history(b).revno]
2542
raise errors.BzrCommandError(
2543
"Merge doesn't permit empty revision specifier.")
2544
base_branch, path = Branch.open_containing(branch)
2545
branch1 = revision[1].get_branch() or branch
2546
other_branch, path1 = Branch.open_containing(branch1)
2547
if revision[0].get_branch() is not None:
2548
# then path was obtained from it, and is None.
2551
base = [branch, revision[0].in_history(base_branch).revno]
2552
other = [branch1, revision[1].in_history(other_branch).revno]
2554
if tree.branch.get_parent() is None or remember:
2555
tree.branch.set_parent(other_branch.base)
2557
# pull tags now... it's a bit inconsistent to do it ahead of copying
2558
# the history but that's done inside the merge code
2559
_merge_tags_if_possible(other_branch, tree.branch)
2061
2562
interesting_files = [path]
2063
2564
interesting_files = None
2064
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2565
pb = ui.ui_factory.nested_progress_bar()
2067
conflict_count = merge(other, base, check_clean=(not force),
2068
merge_type=merge_type,
2069
reprocess=reprocess,
2070
show_base=show_base,
2071
pb=pb, file_list=interesting_files)
2568
conflict_count = _merge_helper(
2569
other, base, check_clean=(not force),
2570
merge_type=merge_type,
2571
reprocess=reprocess,
2572
show_base=show_base,
2575
pb=pb, file_list=interesting_files,
2576
change_reporter=change_reporter)
2074
2579
if conflict_count != 0:
2078
except bzrlib.errors.AmbiguousBase, e:
2583
except errors.AmbiguousBase, e:
2079
2584
m = ("sorry, bzr can't determine the right merge base yet\n"
2080
2585
"candidates are:\n "
2081
2586
+ "\n ".join(e.bases)
2111
2632
Option('show-base', help="Show base revision text in "
2115
from merge import merge_type_help
2116
from inspect import getdoc
2117
return getdoc(self) + '\n' + merge_type_help()
2119
2635
def run(self, file_list=None, merge_type=None, show_base=False,
2120
2636
reprocess=False):
2121
from bzrlib.merge import merge_inner, transform_tree
2122
2637
if merge_type is None:
2123
merge_type = Merge3Merger
2638
merge_type = _mod_merge.Merge3Merger
2124
2639
tree, file_list = tree_files(file_list)
2125
2640
tree.lock_write()
2127
pending_merges = tree.pending_merges()
2128
if len(pending_merges) != 1:
2129
raise BzrCommandError("Sorry, remerge only works after normal"
2130
+ " merges. Not cherrypicking or"
2642
parents = tree.get_parent_ids()
2643
if len(parents) != 2:
2644
raise errors.BzrCommandError("Sorry, remerge only works after normal"
2645
" merges. Not cherrypicking or"
2132
2647
repository = tree.branch.repository
2133
base_revision = common_ancestor(tree.branch.last_revision(),
2134
pending_merges[0], repository)
2648
base_revision = common_ancestor(parents[0],
2649
parents[1], repository)
2135
2650
base_tree = repository.revision_tree(base_revision)
2136
other_tree = repository.revision_tree(pending_merges[0])
2651
other_tree = repository.revision_tree(parents[1])
2137
2652
interesting_ids = None
2654
conflicts = tree.conflicts()
2138
2655
if file_list is not None:
2139
2656
interesting_ids = set()
2140
2657
for filename in file_list:
2141
2658
file_id = tree.path2id(filename)
2142
2659
if file_id is None:
2143
raise NotVersionedError(filename)
2660
raise errors.NotVersionedError(filename)
2144
2661
interesting_ids.add(file_id)
2145
2662
if tree.kind(file_id) != "directory":
2148
2665
for name, ie in tree.inventory.iter_entries(file_id):
2149
2666
interesting_ids.add(ie.file_id)
2150
transform_tree(tree, tree.basis_tree(), interesting_ids)
2151
if file_list is None:
2152
restore_files = list(tree.iter_conflicts())
2667
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
2669
# Remerge only supports resolving contents conflicts
2670
allowed_conflicts = ('text conflict', 'contents conflict')
2671
restore_files = [c.path for c in conflicts
2672
if c.typestring in allowed_conflicts]
2673
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
2674
tree.set_conflicts(ConflictList(new_conflicts))
2675
if file_list is not None:
2154
2676
restore_files = file_list
2155
2677
for filename in restore_files:
2157
2679
restore(tree.abspath(filename))
2158
except NotConflicted:
2680
except errors.NotConflicted:
2160
conflicts = merge_inner(tree.branch, other_tree, base_tree,
2162
interesting_ids = interesting_ids,
2163
other_rev_id=pending_merges[0],
2164
merge_type=merge_type,
2165
show_base=show_base,
2166
reprocess=reprocess)
2682
conflicts = _mod_merge.merge_inner(
2683
tree.branch, other_tree, base_tree,
2685
interesting_ids=interesting_ids,
2686
other_rev_id=parents[1],
2687
merge_type=merge_type,
2688
show_base=show_base,
2689
reprocess=reprocess)
2169
2692
if conflicts > 0:
2174
2698
class cmd_revert(Command):
2175
"""Reverse all changes since the last commit.
2177
Only versioned files are affected. Specify filenames to revert only
2178
those files. By default, any files that are changed will be backed up
2179
first. Backup files have a '~' appended to their name.
2699
"""Revert files to a previous revision.
2701
Giving a list of files will revert only those files. Otherwise, all files
2702
will be reverted. If the revision is not specified with '--revision', the
2703
last committed revision is used.
2705
To remove only some changes, without reverting to a prior version, use
2706
merge instead. For example, "merge . --r-2..-3" will remove the changes
2707
introduced by -2, without affecting the changes introduced by -1. Or
2708
to remove certain changes on a hunk-by-hunk basis, see the Shelf plugin.
2710
By default, any files that have been manually changed will be backed up
2711
first. (Files changed only by merge are not backed up.) Backup files have
2712
'.~#~' appended to their name, where # is a number.
2714
When you provide files, you can use their current pathname or the pathname
2715
from the target revision. So you can use revert to "undelete" a file by
2716
name. If you name a directory, all the contents of that directory will be
2181
2719
takes_options = ['revision', 'no-backup']
2182
2720
takes_args = ['file*']
2183
2721
aliases = ['merge-revert']
2185
2723
def run(self, revision=None, no_backup=False, file_list=None):
2186
from bzrlib.commands import parse_spec
2187
2724
if file_list is not None:
2188
2725
if len(file_list) == 0:
2189
raise BzrCommandError("No files specified")
2726
raise errors.BzrCommandError("No files specified")
2195
2732
# FIXME should be tree.last_revision
2196
2733
rev_id = tree.last_revision()
2197
2734
elif len(revision) != 1:
2198
raise BzrCommandError('bzr revert --revision takes exactly 1 argument')
2735
raise errors.BzrCommandError('bzr revert --revision takes exactly 1 argument')
2200
2737
rev_id = revision[0].in_history(tree.branch).rev_id
2201
pb = bzrlib.ui.ui_factory.nested_progress_bar()
2738
pb = ui.ui_factory.nested_progress_bar()
2203
2740
tree.revert(file_list,
2204
2741
tree.branch.repository.revision_tree(rev_id),
2742
not no_backup, pb, report_changes=True)
2210
2747
class cmd_assert_fail(Command):
2211
2748
"""Test reporting of assertion failures"""
2749
# intended just for use in testing
2214
assert False, "always fails"
2754
raise AssertionError("always fails")
2217
2757
class cmd_help(Command):
2218
2758
"""Show help on a command or other topic.
2220
For a list of all available commands, say 'bzr help commands'."""
2760
For a list of all available commands, say 'bzr help commands'.
2221
2762
takes_options = [Option('long', 'show help on all commands')]
2222
2763
takes_args = ['topic?']
2223
2764
aliases = ['?', '--help', '-?', '-h']
2225
2766
@display_command
2226
2767
def run(self, topic=None, long=False):
2228
2769
if topic is None and long:
2229
2770
topic = "commands"
2771
bzrlib.help.help(topic)
2233
2774
class cmd_shell_complete(Command):
2234
2775
"""Show appropriate completions for context.
2236
For a list of all available commands, say 'bzr shell-complete'."""
2777
For a list of all available commands, say 'bzr shell-complete'.
2237
2779
takes_args = ['context?']
2238
2780
aliases = ['s-c']
2269
2812
Option('theirs-only',
2270
2813
'Display changes in the remote branch only'),
2818
encoding_type = 'replace'
2279
2821
def run(self, other_branch=None, reverse=False, mine_only=False,
2280
2822
theirs_only=False, log_format=None, long=False, short=False, line=False,
2281
2823
show_ids=False, verbose=False):
2282
2824
from bzrlib.missing import find_unmerged, iter_log_data
2283
2825
from bzrlib.log import log_formatter
2284
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
2826
local_branch = Branch.open_containing(u".")[0]
2285
2827
parent = local_branch.get_parent()
2286
2828
if other_branch is None:
2287
2829
other_branch = parent
2288
2830
if other_branch is None:
2289
raise BzrCommandError("No missing location known or specified.")
2290
print "Using last location: " + local_branch.get_parent()
2291
remote_branch = bzrlib.branch.Branch.open(other_branch)
2831
raise errors.BzrCommandError("No peer location known or specified.")
2832
display_url = urlutils.unescape_for_display(parent,
2834
print "Using last location: " + display_url
2836
remote_branch = Branch.open(other_branch)
2292
2837
if remote_branch.base == local_branch.base:
2293
2838
remote_branch = local_branch
2294
2839
local_branch.lock_read()
2456
3010
if to_revid is None:
2457
3011
to_revno = b.revno()
2458
3012
if from_revno is None or to_revno is None:
2459
raise BzrCommandError('Cannot sign a range of non-revision-history revisions')
3013
raise errors.BzrCommandError('Cannot sign a range of non-revision-history revisions')
2460
3014
for revno in range(from_revno, to_revno + 1):
2461
3015
b.repository.sign_revision(b.get_rev_id(revno),
2464
raise BzrCommandError('Please supply either one revision, or a range.')
3018
raise errors.BzrCommandError('Please supply either one revision, or a range.')
2467
3021
class cmd_bind(Command):
2468
"""Bind the current branch to a master branch.
2470
After binding, commits must succeed on the master branch
2471
before they are executed on the local one.
3022
"""Convert the current branch into a checkout of the supplied branch.
3024
Once converted into a checkout, commits must succeed on the master branch
3025
before they will be applied to the local branch.
3027
See "help checkouts" for more information on checkouts.
2474
takes_args = ['location']
3030
takes_args = ['location?']
2475
3031
takes_options = []
2477
3033
def run(self, location=None):
2478
3034
b, relpath = Branch.open_containing(u'.')
3035
if location is None:
3037
location = b.get_old_bound_location()
3038
except errors.UpgradeRequired:
3039
raise errors.BzrCommandError('No location supplied. '
3040
'This format does not remember old locations.')
3042
if location is None:
3043
raise errors.BzrCommandError('No location supplied and no '
3044
'previous location known')
2479
3045
b_other = Branch.open(location)
2481
3047
b.bind(b_other)
2482
except DivergedBranches:
2483
raise BzrCommandError('These branches have diverged.'
2484
' Try merging, and then bind again.')
3048
except errors.DivergedBranches:
3049
raise errors.BzrCommandError('These branches have diverged.'
3050
' Try merging, and then bind again.')
2487
3053
class cmd_unbind(Command):
2488
"""Unbind the current branch from its master branch.
2490
After unbinding, the local branch is considered independent.
2491
All subsequent commits will be local.
3054
"""Convert the current checkout into a regular branch.
3056
After unbinding, the local branch is considered independent and subsequent
3057
commits will be local only.
3059
See "help checkouts" for more information on checkouts.
2494
3062
takes_args = []
3176
class cmd_wait_until_signalled(Command):
3177
"""Test helper for test_start_and_stop_bzr_subprocess_send_signal.
3179
This just prints a line to signal when it is ready, then blocks on stdin.
3185
sys.stdout.write("running\n")
3187
sys.stdin.readline()
3190
class cmd_serve(Command):
3191
"""Run the bzr server."""
3193
aliases = ['server']
3197
help='serve on stdin/out for use from inetd or sshd'),
3199
help='listen for connections on nominated port of the form '
3200
'[hostname:]portnumber. Passing 0 as the port number will '
3201
'result in a dynamically allocated port. Default port is '
3205
help='serve contents of directory',
3207
Option('allow-writes',
3208
help='By default the server is a readonly server. Supplying '
3209
'--allow-writes enables write access to the contents of '
3210
'the served directory and below. '
3214
def run(self, port=None, inet=False, directory=None, allow_writes=False):
3215
from bzrlib.transport import smart
3216
from bzrlib.transport import get_transport
3217
if directory is None:
3218
directory = os.getcwd()
3219
url = urlutils.local_path_to_url(directory)
3220
if not allow_writes:
3221
url = 'readonly+' + url
3222
t = get_transport(url)
3224
server = smart.SmartServerPipeStreamMedium(sys.stdin, sys.stdout, t)
3227
port = smart.BZR_DEFAULT_PORT
3231
host, port = port.split(':')
3235
server = smart.SmartTCPServer(t, host=host, port=port)
3236
print 'listening on port: ', server.port
3240
class cmd_join(Command):
3241
"""Combine a subtree into its containing tree.
3243
This is marked as a merge of the subtree into the containing tree, and all
3244
history is preserved.
3247
takes_args = ['tree']
3248
takes_options = [Option('reference', 'join by reference')]
3250
def run(self, tree, reference=False):
3251
sub_tree = WorkingTree.open(tree)
3252
parent_dir = osutils.dirname(sub_tree.basedir)
3253
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3254
repo = containing_tree.branch.repository
3255
if not repo.supports_rich_root():
3256
raise errors.BzrCommandError(
3257
"Can't join trees because %s doesn't support rich root data.\n"
3258
"You can use bzr upgrade on the repository."
3262
containing_tree.add_reference(sub_tree)
3263
except errors.BadReferenceTarget, e:
3264
# XXX: Would be better to just raise a nicely printable
3265
# exception from the real origin. Also below. mbp 20070306
3266
raise errors.BzrCommandError("Cannot join %s. %s" %
3270
containing_tree.subsume(sub_tree)
3271
except errors.BadSubsumeSource, e:
3272
raise errors.BzrCommandError("Cannot join %s. %s" %
3276
class cmd_split(Command):
3277
"""Split a tree into two trees.
3280
takes_args = ['tree']
3282
def run(self, tree):
3283
containing_tree, subdir = WorkingTree.open_containing(tree)
3284
sub_id = containing_tree.path2id(subdir)
3286
raise errors.NotVersionedError(subdir)
3288
containing_tree.extract(sub_id)
3289
except errors.RootNotRich:
3290
raise errors.UpgradeRequired(containing_tree.branch.base)
3294
class cmd_tag(Command):
3295
"""Create a tag naming a revision.
3297
Tags give human-meaningful names to revisions. Commands that take a -r
3298
(--revision) option can be given -rtag:X, where X is any previously
3301
Tags are stored in the branch. Tags are copied from one branch to another
3302
along when you branch, push, pull or merge.
3304
It is an error to give a tag name that already exists unless you pass
3305
--force, in which case the tag is moved to point to the new revision.
3308
takes_args = ['tag_name']
3311
help='Delete this tag rather than placing it.',
3314
help='Branch in which to place the tag.',
3319
help='Replace existing tags',
3324
def run(self, tag_name,
3330
branch, relpath = Branch.open_containing(directory)
3334
branch.tags.delete_tag(tag_name)
3335
self.outf.write('Deleted tag %s.\n' % tag_name)
3338
if len(revision) != 1:
3339
raise errors.BzrCommandError(
3340
"Tags can only be placed on a single revision, "
3342
revision_id = revision[0].in_history(branch).rev_id
3344
revision_id = branch.last_revision()
3345
if (not force) and branch.tags.has_tag(tag_name):
3346
raise errors.TagAlreadyExists(tag_name)
3347
branch.tags.set_tag(tag_name, revision_id)
3348
self.outf.write('Created tag %s.\n' % tag_name)
3353
class cmd_tags(Command):
3356
This tag shows a table of tag names and the revisions they reference.
3361
help='Branch whose tags should be displayed',
3371
branch, relpath = Branch.open_containing(directory)
3372
for tag_name, target in sorted(branch.tags.get_tag_dict().items()):
3373
self.outf.write('%-20s %s\n' % (tag_name, target))
2595
3376
# command-line interpretation helper for merge-related commands
2596
def merge(other_revision, base_revision,
2597
check_clean=True, ignore_zero=False,
2598
this_dir=None, backup_files=False, merge_type=Merge3Merger,
2599
file_list=None, show_base=False, reprocess=False,
2600
pb=DummyProgress()):
3377
def _merge_helper(other_revision, base_revision,
3378
check_clean=True, ignore_zero=False,
3379
this_dir=None, backup_files=False,
3381
file_list=None, show_base=False, reprocess=False,
3384
change_reporter=None):
2601
3385
"""Merge changes into a tree.
2625
3409
clients might prefer to call merge.merge_inner(), which has less magic
2628
from bzrlib.merge import Merger
3412
# Loading it late, so that we don't always have to import bzrlib.merge
3413
if merge_type is None:
3414
merge_type = _mod_merge.Merge3Merger
2629
3415
if this_dir is None:
2630
3416
this_dir = u'.'
2631
3417
this_tree = WorkingTree.open_containing(this_dir)[0]
2632
if show_base and not merge_type is Merge3Merger:
2633
raise BzrCommandError("Show-base is not supported for this merge"
2634
" type. %s" % merge_type)
3418
if show_base and not merge_type is _mod_merge.Merge3Merger:
3419
raise errors.BzrCommandError("Show-base is not supported for this merge"
3420
" type. %s" % merge_type)
2635
3421
if reprocess and not merge_type.supports_reprocess:
2636
raise BzrCommandError("Conflict reduction is not supported for merge"
2637
" type %s." % merge_type)
3422
raise errors.BzrCommandError("Conflict reduction is not supported for merge"
3423
" type %s." % merge_type)
2638
3424
if reprocess and show_base:
2639
raise BzrCommandError("Cannot do conflict reduction and show base.")
3425
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3426
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3427
# only want to take out a lock_tree_write() if we don't have to pull
3428
# any ancestry. But merge might fetch ancestry in the middle, in
3429
# which case we would need a lock_write().
3430
# Because we cannot upgrade locks, for now we live with the fact that
3431
# the tree will be locked multiple times during a merge. (Maybe
3432
# read-only some of the time, but it means things will get read
2641
merger = Merger(this_tree.branch, this_tree=this_tree, pb=pb)
3435
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3436
pb=pb, change_reporter=change_reporter)
2642
3437
merger.pp = ProgressPhase("Merge phase", 5, pb)
2643
3438
merger.pp.next_phase()
2644
3439
merger.check_basis(check_clean)