362
364
action = bzrlib.add.AddAction(to_file=self.outf,
363
365
should_print=(not is_quiet()))
365
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
366
action=action, save=not dry_run)
368
base_tree.lock_read()
370
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
371
action=action, save=not dry_run)
373
if base_tree is not None:
367
375
if len(ignored) > 0:
369
377
for glob in sorted(ignored.keys()):
435
443
raise errors.BzrCommandError('invalid kind specified')
437
445
work_tree, file_list = tree_files(file_list)
439
if revision is not None:
440
if len(revision) > 1:
441
raise errors.BzrCommandError('bzr inventory --revision takes'
442
' exactly one revision identifier')
443
revision_id = revision[0].in_history(work_tree.branch).rev_id
444
tree = work_tree.branch.repository.revision_tree(revision_id)
446
# We include work_tree as well as 'tree' here
447
# So that doing '-r 10 path/foo' will lookup whatever file
448
# exists now at 'path/foo' even if it has been renamed, as
449
# well as whatever files existed in revision 10 at path/foo
450
trees = [tree, work_tree]
455
if file_list is not None:
456
file_ids = _mod_tree.find_ids_across_trees(file_list, trees,
457
require_versioned=True)
458
# find_ids_across_trees may include some paths that don't
460
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
461
for file_id in file_ids if file_id in tree)
463
entries = tree.inventory.entries()
446
work_tree.lock_read()
448
if revision is not None:
449
if len(revision) > 1:
450
raise errors.BzrCommandError(
451
'bzr inventory --revision takes exactly one revision'
453
revision_id = revision[0].in_history(work_tree.branch).rev_id
454
tree = work_tree.branch.repository.revision_tree(revision_id)
456
extra_trees = [work_tree]
462
if file_list is not None:
463
file_ids = tree.paths2ids(file_list, trees=extra_trees,
464
require_versioned=True)
465
# find_ids_across_trees may include some paths that don't
467
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
468
for file_id in file_ids if file_id in tree)
470
entries = tree.inventory.entries()
473
if tree is not work_tree:
465
476
for path, entry in entries:
466
477
if kind and kind != entry.kind:
604
615
old_rh = branch_to.revision_history()
605
616
if tree_to is not None:
606
617
result = tree_to.pull(branch_from, overwrite, rev_id,
607
delta.ChangeReporter(tree_to.inventory))
618
delta.ChangeReporter(unversioned_filter=tree_to.is_ignored))
609
620
result = branch_to.pull(branch_from, overwrite, rev_id)
976
987
def run(self, dir=u'.'):
977
988
tree = WorkingTree.open_containing(dir)[0]
978
old_inv = tree.basis_tree().inventory
979
new_inv = tree.read_working_inventory()
980
renames = list(_mod_tree.find_renames(old_inv, new_inv))
982
for old_name, new_name in renames:
983
self.outf.write("%s => %s\n" % (old_name, new_name))
991
new_inv = tree.inventory
992
old_tree = tree.basis_tree()
995
old_inv = old_tree.inventory
996
renames = list(_mod_tree.find_renames(old_inv, new_inv))
998
for old_name, new_name in renames:
999
self.outf.write("%s => %s\n" % (old_name, new_name))
986
1006
class cmd_update(Command):
1091
1111
@display_command
1092
1112
def run(self, filename):
1093
1113
tree, relpath = WorkingTree.open_containing(filename)
1094
i = tree.inventory.path2id(relpath)
1114
i = tree.path2id(relpath)
1096
1116
raise errors.NotVersionedError(filename)
1111
1131
@display_command
1112
1132
def run(self, filename):
1113
1133
tree, relpath = WorkingTree.open_containing(filename)
1114
inv = tree.inventory
1115
fid = inv.path2id(relpath)
1134
fid = tree.path2id(relpath)
1116
1135
if fid is None:
1117
1136
raise errors.NotVersionedError(filename)
1118
for fip in inv.get_idpath(fid):
1119
self.outf.write(fip + '\n')
1137
segments = osutils.splitpath(relpath)
1138
for pos in range(1, len(segments) + 1):
1139
path = osutils.joinpath(segments[:pos])
1140
self.outf.write("%s\n" % tree.path2id(path))
1122
1143
class cmd_reconcile(Command):
1427
1448
@display_command
1428
1449
def run(self, show_ids=False):
1429
1450
tree = WorkingTree.open_containing(u'.')[0]
1430
old = tree.basis_tree()
1431
for path, ie in old.inventory.iter_entries():
1432
if not tree.has_id(ie.file_id):
1433
self.outf.write(path)
1435
self.outf.write(' ')
1436
self.outf.write(ie.file_id)
1437
self.outf.write('\n')
1453
old = tree.basis_tree()
1456
for path, ie in old.inventory.iter_entries():
1457
if not tree.has_id(ie.file_id):
1458
self.outf.write(path)
1460
self.outf.write(' ')
1461
self.outf.write(ie.file_id)
1462
self.outf.write('\n')
1440
1469
class cmd_modified(Command):
1464
1493
@display_command
1466
1495
wt = WorkingTree.open_containing(u'.')[0]
1467
basis_inv = wt.basis_tree().inventory
1470
if file_id in basis_inv:
1472
if inv.is_root(file_id) and len(basis_inv) == 0:
1474
path = inv.id2path(file_id)
1475
if not os.access(osutils.abspath(path), os.F_OK):
1477
self.outf.write(path + '\n')
1498
basis = wt.basis_tree()
1501
basis_inv = basis.inventory
1504
if file_id in basis_inv:
1506
if inv.is_root(file_id) and len(basis_inv) == 0:
1508
path = inv.id2path(file_id)
1509
if not os.access(osutils.abspath(path), os.F_OK):
1511
self.outf.write(path + '\n')
1480
1518
class cmd_root(Command):
1641
1678
def run(self, filename):
1642
1679
tree, relpath = WorkingTree.open_containing(filename)
1643
1680
b = tree.branch
1644
inv = tree.read_working_inventory()
1645
file_id = inv.path2id(relpath)
1681
file_id = tree.path2id(relpath)
1646
1682
for revno, revision_id, what in log.find_touching_revisions(b, file_id):
1647
1683
self.outf.write("%6d %s\n" % (revno, what))
1701
1737
elif tree is None:
1702
1738
tree = branch.basis_tree()
1704
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1705
if fp.startswith(relpath):
1706
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1707
if non_recursive and '/' in fp:
1709
if not all and not selection[fc]:
1711
if kind is not None and fkind != kind:
1714
kindch = entry.kind_character()
1715
outstring = '%-8s %s%s' % (fc, fp, kindch)
1716
if show_ids and fid is not None:
1717
outstring = "%-50s %s" % (outstring, fid)
1718
self.outf.write(outstring + '\n')
1720
self.outf.write(fp + '\0')
1742
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
1743
if fp.startswith(relpath):
1744
fp = osutils.pathjoin(prefix, fp[len(relpath):])
1745
if non_recursive and '/' in fp:
1747
if not all and not selection[fc]:
1749
if kind is not None and fkind != kind:
1752
kindch = entry.kind_character()
1753
outstring = '%-8s %s%s' % (fc, fp, kindch)
1754
if show_ids and fid is not None:
1755
outstring = "%-50s %s" % (outstring, fid)
1756
self.outf.write(outstring + '\n')
1758
self.outf.write(fp + '\0')
1761
self.outf.write(fid)
1762
self.outf.write('\0')
1722
1765
if fid is not None:
1723
self.outf.write(fid)
1724
self.outf.write('\0')
1732
self.outf.write('%-50s %s\n' % (fp, my_id))
1734
self.outf.write(fp + '\n')
1770
self.outf.write('%-50s %s\n' % (fp, my_id))
1772
self.outf.write(fp + '\n')
1737
1777
class cmd_unknowns(Command):
1797
1837
if not name_pattern_list:
1798
1838
raise errors.BzrCommandError("ignore requires at least one "
1799
1839
"NAME_PATTERN or --old-default-rules")
1840
name_pattern_list = [globbing.normalize_pattern(p)
1841
for p in name_pattern_list]
1800
1842
for name_pattern in name_pattern_list:
1801
if name_pattern[0] == '/':
1843
if (name_pattern[0] == '/' or
1844
(len(name_pattern) > 1 and name_pattern[1] == ':')):
1802
1845
raise errors.BzrCommandError(
1803
1846
"NAME_PATTERN should not be an absolute path")
1804
1847
tree, relpath = WorkingTree.open_containing(u'.')
1818
1861
if igns and igns[-1] != '\n':
1820
1863
for name_pattern in name_pattern_list:
1821
igns += name_pattern.rstrip('/') + '\n'
1864
igns += name_pattern + '\n'
1823
1866
f = AtomicFile(ifn, 'wb')
1842
1881
@display_command
1844
1883
tree = WorkingTree.open_containing(u'.')[0]
1845
for path, file_class, kind, file_id, entry in tree.list_files():
1846
if file_class != 'I':
1848
## XXX: Slightly inefficient since this was already calculated
1849
pat = tree.is_ignored(path)
1850
print '%-50s %s' % (path, pat)
1886
for path, file_class, kind, file_id, entry in tree.list_files():
1887
if file_class != 'I':
1889
## XXX: Slightly inefficient since this was already calculated
1890
pat = tree.is_ignored(path)
1891
print '%-50s %s' % (path, pat)
1853
1896
class cmd_lookup_revision(Command):
2124
2167
value_switches=True, title='Branch format'),
2128
2170
def run(self, url='.', format=None):
2129
2171
from bzrlib.upgrade import upgrade
2130
2172
if format is None:
2222
2264
run only tests relating to 'ignore'
2223
2265
bzr --no-plugins selftest -v
2224
2266
disable plugins and list tests as they're run
2268
For each test, that needs actual disk access, bzr create their own
2269
subdirectory in the temporary testing directory (testXXXX.tmp).
2270
By default the name of such subdirectory is based on the name of the test.
2271
If option '--numbered-dirs' is given, bzr will use sequent numbers
2272
of running tests to create such subdirectories. This is default behavior
2273
on Windows because of path length limitation.
2226
2275
# TODO: --list should give a list of all available tests
2264
2313
' without running tests'),
2265
2314
Option('first',
2266
2315
help='run all tests, but run specified tests first',
2317
Option('numbered-dirs',
2318
help='use numbered dirs for TestCaseInTempDir'),
2269
2320
encoding_type = 'replace'
2271
2322
def run(self, testspecs_list=None, verbose=None, one=False,
2272
2323
keep_output=False, transport=None, benchmark=None,
2273
2324
lsprof_timed=None, cache_dir=None, clean_output=False,
2325
first=False, numbered_dirs=None):
2275
2326
import bzrlib.ui
2276
2327
from bzrlib.tests import selftest
2277
2328
import bzrlib.benchmarks as benchmarks
2282
2333
clean_selftest_output()
2336
if numbered_dirs is None and sys.platform == 'win32':
2337
numbered_dirs = True
2285
2339
if cache_dir is not None:
2286
2340
tree_creator.TreeCreator.CACHE_ROOT = osutils.abspath(cache_dir)
2287
2341
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
2312
2366
lsprof_timed=lsprof_timed,
2313
2367
bench_history=benchfile,
2314
2368
matching_tests_first=first,
2369
numbered_dirs=numbered_dirs,
2317
2372
if benchfile is not None:
2440
2495
merge_type = _mod_merge.Merge3Merger
2442
2497
if directory is None: directory = u'.'
2498
# XXX: jam 20070225 WorkingTree should be locked before you extract its
2499
# inventory. Because merge is a mutating operation, it really
2500
# should be a lock_write() for the whole cmd_merge operation.
2501
# However, cmd_merge open's its own tree in _merge_helper, which
2502
# means if we lock here, the later lock_write() will always block.
2503
# Either the merge helper code should be updated to take a tree,
2504
# (What about tree.merge_from_branch?)
2443
2505
tree = WorkingTree.open_containing(directory)[0]
2444
change_reporter = delta.ChangeReporter(tree.inventory)
2506
change_reporter = delta.ChangeReporter(
2507
unversioned_filter=tree.is_ignored)
2446
2509
if branch is not None:
2911
2974
raise errors.BzrCommandError('bzr annotate --revision takes exactly 1 argument')
2913
2976
revision_id = revision[0].in_history(branch).rev_id
2914
file_id = tree.inventory.path2id(relpath)
2977
file_id = tree.path2id(relpath)
2915
2978
tree = branch.repository.revision_tree(revision_id)
2916
2979
file_version = tree.inventory[file_id].revision
2917
2980
annotate_file(branch, file_version, file_id, long, all, sys.stdout,
3179
3242
sys.stdout.flush()
3245
class cmd_join(Command):
3246
"""Combine a subtree into its containing tree.
3248
This is marked as a merge of the subtree into the containing tree, and all
3249
history is preserved.
3252
takes_args = ['tree']
3253
takes_options = [Option('reference', 'join by reference')]
3255
def run(self, tree, reference=False):
3256
sub_tree = WorkingTree.open(tree)
3257
parent_dir = osutils.dirname(sub_tree.basedir)
3258
containing_tree = WorkingTree.open_containing(parent_dir)[0]
3259
repo = containing_tree.branch.repository
3260
if not repo.supports_rich_root():
3261
raise errors.BzrCommandError(
3262
"Can't join trees because %s doesn't support rich root data.\n"
3263
"You can use bzr upgrade on the repository."
3267
containing_tree.add_reference(sub_tree)
3268
except errors.BadReferenceTarget, e:
3269
# XXX: Would be better to just raise a nicely printable
3270
# exception from the real origin. Also below. mbp 20070306
3271
raise errors.BzrCommandError("Cannot join %s. %s" %
3275
containing_tree.subsume(sub_tree)
3276
except errors.BadSubsumeSource, e:
3277
raise errors.BzrCommandError("Cannot join %s. %s" %
3281
class cmd_split(Command):
3282
"""Split a tree into two trees.
3285
takes_args = ['tree']
3287
def run(self, tree):
3288
containing_tree, subdir = WorkingTree.open_containing(tree)
3289
sub_id = containing_tree.path2id(subdir)
3291
raise errors.NotVersionedError(subdir)
3293
containing_tree.extract(sub_id)
3294
except errors.RootNotRich:
3295
raise errors.UpgradeRequired(containing_tree.branch.base)
3183
3299
class cmd_merge_directive(Command):
3184
3300
"""Generate a merge directive for auto-merge tools.
3395
3511
" type %s." % merge_type)
3396
3512
if reprocess and show_base:
3397
3513
raise errors.BzrCommandError("Cannot do conflict reduction and show base.")
3514
# TODO: jam 20070226 We should really lock these trees earlier. However, we
3515
# only want to take out a lock_tree_write() if we don't have to pull
3516
# any ancestry. But merge might fetch ancestry in the middle, in
3517
# which case we would need a lock_write().
3518
# Because we cannot upgrade locks, for now we live with the fact that
3519
# the tree will be locked multiple times during a merge. (Maybe
3520
# read-only some of the time, but it means things will get read
3399
3523
merger = _mod_merge.Merger(this_tree.branch, this_tree=this_tree,
3400
3524
pb=pb, change_reporter=change_reporter)