546
542
wt = WorkingTree.open_containing(directory)[0]
545
self.add_cleanup(wt.unlock)
549
546
except (errors.NoWorkingTree, errors.NotLocalUrl):
551
548
b = Branch.open_containing(directory)[0]
555
if revision is not None:
556
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
557
if revision_info_list is not None:
558
for rev_str in revision_info_list:
559
rev_spec = RevisionSpec.from_string(rev_str)
560
revision_ids.append(rev_spec.as_revision_id(b))
561
# No arguments supplied, default to the last revision
562
if len(revision_ids) == 0:
565
raise errors.NoWorkingTree(directory)
566
revision_ids.append(wt.last_revision())
568
revision_ids.append(b.last_revision())
572
for revision_id in revision_ids:
574
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
575
revno = '.'.join(str(i) for i in dotted_revno)
576
except errors.NoSuchRevision:
578
maxlen = max(maxlen, len(revno))
579
revinfos.append([revno, revision_id])
550
self.add_cleanup(b.unlock)
552
if revision is not None:
553
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
554
if revision_info_list is not None:
555
for rev_str in revision_info_list:
556
rev_spec = RevisionSpec.from_string(rev_str)
557
revision_ids.append(rev_spec.as_revision_id(b))
558
# No arguments supplied, default to the last revision
559
if len(revision_ids) == 0:
562
raise errors.NoWorkingTree(directory)
563
revision_ids.append(wt.last_revision())
565
revision_ids.append(b.last_revision())
569
for revision_id in revision_ids:
571
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
572
revno = '.'.join(str(i) for i in dotted_revno)
573
except errors.NoSuchRevision:
575
maxlen = max(maxlen, len(revno))
576
revinfos.append([revno, revision_id])
586
579
for ri in revinfos:
587
580
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
736
727
revision = _get_one_revision('inventory', revision)
737
728
work_tree, file_list = tree_files(file_list)
738
729
work_tree.lock_read()
740
if revision is not None:
741
tree = revision.as_tree(work_tree.branch)
743
extra_trees = [work_tree]
749
if file_list is not None:
750
file_ids = tree.paths2ids(file_list, trees=extra_trees,
751
require_versioned=True)
752
# find_ids_across_trees may include some paths that don't
754
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
755
for file_id in file_ids if file_id in tree)
757
entries = tree.inventory.entries()
760
if tree is not work_tree:
730
self.add_cleanup(work_tree.unlock)
731
if revision is not None:
732
tree = revision.as_tree(work_tree.branch)
734
extra_trees = [work_tree]
736
self.add_cleanup(tree.unlock)
741
if file_list is not None:
742
file_ids = tree.paths2ids(file_list, trees=extra_trees,
743
require_versioned=True)
744
# find_ids_across_trees may include some paths that don't
746
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
747
for file_id in file_ids if file_id in tree)
749
entries = tree.inventory.entries()
763
752
for path, entry in entries:
764
753
if kind and kind != entry.kind:
1013
998
if branch_from is not branch_to:
1014
999
branch_from.lock_read()
1016
if revision is not None:
1017
revision_id = revision.as_revision_id(branch_from)
1019
branch_to.lock_write()
1021
if tree_to is not None:
1022
view_info = _get_view_info_for_change_reporter(tree_to)
1023
change_reporter = delta._ChangeReporter(
1024
unversioned_filter=tree_to.is_ignored,
1025
view_info=view_info)
1026
result = tree_to.pull(
1027
branch_from, overwrite, revision_id, change_reporter,
1028
possible_transports=possible_transports, local=local)
1030
result = branch_to.pull(
1031
branch_from, overwrite, revision_id, local=local)
1033
result.report(self.outf)
1034
if verbose and result.old_revid != result.new_revid:
1035
log.show_branch_change(
1036
branch_to, self.outf, result.old_revno,
1041
if branch_from is not branch_to:
1042
branch_from.unlock()
1000
self.add_cleanup(branch_from.unlock)
1001
if revision is not None:
1002
revision_id = revision.as_revision_id(branch_from)
1004
branch_to.lock_write()
1005
self.add_cleanup(branch_to.unlock)
1006
if tree_to is not None:
1007
view_info = _get_view_info_for_change_reporter(tree_to)
1008
change_reporter = delta._ChangeReporter(
1009
unversioned_filter=tree_to.is_ignored,
1010
view_info=view_info)
1011
result = tree_to.pull(
1012
branch_from, overwrite, revision_id, change_reporter,
1013
possible_transports=possible_transports, local=local)
1015
result = branch_to.pull(
1016
branch_from, overwrite, revision_id, local=local)
1018
result.report(self.outf)
1019
if verbose and result.old_revid != result.new_revid:
1020
log.show_branch_change(
1021
branch_to, self.outf, result.old_revno,
1045
1025
class cmd_push(Command):
1213
1193
revision = _get_one_revision('branch', revision)
1214
1194
br_from.lock_read()
1195
self.add_cleanup(br_from.unlock)
1196
if revision is not None:
1197
revision_id = revision.as_revision_id(br_from)
1199
# FIXME - wt.last_revision, fallback to branch, fall back to
1200
# None or perhaps NULL_REVISION to mean copy nothing
1202
revision_id = br_from.last_revision()
1203
if to_location is None:
1204
to_location = urlutils.derive_to_location(from_location)
1205
to_transport = transport.get_transport(to_location)
1216
if revision is not None:
1217
revision_id = revision.as_revision_id(br_from)
1207
to_transport.mkdir('.')
1208
except errors.FileExists:
1209
if not use_existing_dir:
1210
raise errors.BzrCommandError('Target directory "%s" '
1211
'already exists.' % to_location)
1219
# FIXME - wt.last_revision, fallback to branch, fall back to
1220
# None or perhaps NULL_REVISION to mean copy nothing
1222
revision_id = br_from.last_revision()
1223
if to_location is None:
1224
to_location = urlutils.derive_to_location(from_location)
1225
to_transport = transport.get_transport(to_location)
1227
to_transport.mkdir('.')
1228
except errors.FileExists:
1229
if not use_existing_dir:
1230
raise errors.BzrCommandError('Target directory "%s" '
1231
'already exists.' % to_location)
1214
bzrdir.BzrDir.open_from_transport(to_transport)
1215
except errors.NotBranchError:
1234
bzrdir.BzrDir.open_from_transport(to_transport)
1235
except errors.NotBranchError:
1238
raise errors.AlreadyBranchError(to_location)
1239
except errors.NoSuchFile:
1240
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1243
# preserve whatever source format we have.
1244
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1245
possible_transports=[to_transport],
1246
accelerator_tree=accelerator_tree,
1247
hardlink=hardlink, stacked=stacked,
1248
force_new_repo=standalone,
1249
create_tree_if_local=not no_tree,
1250
source_branch=br_from)
1251
branch = dir.open_branch()
1252
except errors.NoSuchRevision:
1253
to_transport.delete_tree('.')
1254
msg = "The branch %s has no revision %s." % (from_location,
1256
raise errors.BzrCommandError(msg)
1257
_merge_tags_if_possible(br_from, branch)
1258
# If the source branch is stacked, the new branch may
1259
# be stacked whether we asked for that explicitly or not.
1260
# We therefore need a try/except here and not just 'if stacked:'
1262
note('Created new stacked branch referring to %s.' %
1263
branch.get_stacked_on_url())
1264
except (errors.NotStacked, errors.UnstackableBranchFormat,
1265
errors.UnstackableRepositoryFormat), e:
1266
note('Branched %d revision(s).' % branch.revno())
1268
# Switch to the new branch
1269
wt, _ = WorkingTree.open_containing('.')
1270
_mod_switch.switch(wt.bzrdir, branch)
1271
note('Switched to branch: %s',
1272
urlutils.unescape_for_display(branch.base, 'utf-8'))
1218
raise errors.AlreadyBranchError(to_location)
1219
except errors.NoSuchFile:
1220
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1223
# preserve whatever source format we have.
1224
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1225
possible_transports=[to_transport],
1226
accelerator_tree=accelerator_tree,
1227
hardlink=hardlink, stacked=stacked,
1228
force_new_repo=standalone,
1229
create_tree_if_local=not no_tree,
1230
source_branch=br_from)
1231
branch = dir.open_branch()
1232
except errors.NoSuchRevision:
1233
to_transport.delete_tree('.')
1234
msg = "The branch %s has no revision %s." % (from_location,
1236
raise errors.BzrCommandError(msg)
1237
_merge_tags_if_possible(br_from, branch)
1238
# If the source branch is stacked, the new branch may
1239
# be stacked whether we asked for that explicitly or not.
1240
# We therefore need a try/except here and not just 'if stacked:'
1242
note('Created new stacked branch referring to %s.' %
1243
branch.get_stacked_on_url())
1244
except (errors.NotStacked, errors.UnstackableBranchFormat,
1245
errors.UnstackableRepositoryFormat), e:
1246
note('Branched %d revision(s).' % branch.revno())
1248
# Switch to the new branch
1249
wt, _ = WorkingTree.open_containing('.')
1250
_mod_switch.switch(wt.bzrdir, branch)
1251
note('Switched to branch: %s',
1252
urlutils.unescape_for_display(branch.base, 'utf-8'))
1277
1255
class cmd_checkout(Command):
1356
1334
def run(self, dir=u'.'):
1357
1335
tree = WorkingTree.open_containing(dir)[0]
1358
1336
tree.lock_read()
1360
new_inv = tree.inventory
1361
old_tree = tree.basis_tree()
1362
old_tree.lock_read()
1364
old_inv = old_tree.inventory
1366
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1367
for f, paths, c, v, p, n, k, e in iterator:
1368
if paths[0] == paths[1]:
1372
renames.append(paths)
1374
for old_name, new_name in renames:
1375
self.outf.write("%s => %s\n" % (old_name, new_name))
1337
self.add_cleanup(tree.unlock)
1338
new_inv = tree.inventory
1339
old_tree = tree.basis_tree()
1340
old_tree.lock_read()
1341
self.add_cleanup(old_tree.unlock)
1342
old_inv = old_tree.inventory
1344
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1345
for f, paths, c, v, p, n, k, e in iterator:
1346
if paths[0] == paths[1]:
1350
renames.append(paths)
1352
for old_name, new_name in renames:
1353
self.outf.write("%s => %s\n" % (old_name, new_name))
1382
1356
class cmd_update(Command):
1414
1388
tree.lock_tree_write()
1415
1389
branch_location = tree.branch.base
1390
self.add_cleanup(tree.unlock)
1416
1391
# get rid of the final '/' and be ready for display
1417
1392
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1418
1393
self.outf.encoding)
1394
existing_pending_merges = tree.get_parent_ids()[1:]
1398
# may need to fetch data into a heavyweight checkout
1399
# XXX: this may take some time, maybe we should display a
1401
old_tip = branch.update(possible_transports)
1402
if revision is not None:
1403
revision_id = revision[0].as_revision_id(branch)
1405
revision_id = branch.last_revision()
1406
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1407
revno = branch.revision_id_to_revno(revision_id)
1408
note("Tree is up to date at revision %d of branch %s" %
1409
(revno, branch_location))
1411
view_info = _get_view_info_for_change_reporter(tree)
1412
change_reporter = delta._ChangeReporter(
1413
unversioned_filter=tree.is_ignored,
1414
view_info=view_info)
1420
existing_pending_merges = tree.get_parent_ids()[1:]
1424
# may need to fetch data into a heavyweight checkout
1425
# XXX: this may take some time, maybe we should display a
1427
old_tip = branch.update(possible_transports)
1428
if revision is not None:
1429
revision_id = revision[0].as_revision_id(branch)
1431
revision_id = branch.last_revision()
1432
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1433
revno = branch.revision_id_to_revno(revision_id)
1434
note("Tree is up to date at revision %d of branch %s" %
1435
(revno, branch_location))
1437
view_info = _get_view_info_for_change_reporter(tree)
1438
change_reporter = delta._ChangeReporter(
1439
unversioned_filter=tree.is_ignored,
1440
view_info=view_info)
1442
conflicts = tree.update(
1444
possible_transports=possible_transports,
1445
revision=revision_id,
1447
except errors.NoSuchRevision, e:
1448
raise errors.BzrCommandError(
1449
"branch has no revision %s\n"
1450
"bzr update --revision only works"
1451
" for a revision in the branch history"
1453
revno = tree.branch.revision_id_to_revno(
1454
_mod_revision.ensure_null(tree.last_revision()))
1455
note('Updated to revision %d of branch %s' %
1456
(revno, branch_location))
1457
if tree.get_parent_ids()[1:] != existing_pending_merges:
1458
note('Your local commits will now show as pending merges with '
1459
"'bzr status', and can be committed with 'bzr commit'.")
1416
conflicts = tree.update(
1418
possible_transports=possible_transports,
1419
revision=revision_id,
1421
except errors.NoSuchRevision, e:
1422
raise errors.BzrCommandError(
1423
"branch has no revision %s\n"
1424
"bzr update --revision only works"
1425
" for a revision in the branch history"
1427
revno = tree.branch.revision_id_to_revno(
1428
_mod_revision.ensure_null(tree.last_revision()))
1429
note('Updated to revision %d of branch %s' %
1430
(revno, branch_location))
1431
if tree.get_parent_ids()[1:] != existing_pending_merges:
1432
note('Your local commits will now show as pending merges with '
1433
"'bzr status', and can be committed with 'bzr commit'.")
1468
1440
class cmd_info(Command):
1539
1511
file_list = [f for f in file_list]
1541
1513
tree.lock_write()
1543
# Heuristics should probably all move into tree.remove_smart or
1546
added = tree.changes_from(tree.basis_tree(),
1547
specific_files=file_list).added
1548
file_list = sorted([f[0] for f in added], reverse=True)
1549
if len(file_list) == 0:
1550
raise errors.BzrCommandError('No matching files.')
1551
elif file_list is None:
1552
# missing files show up in iter_changes(basis) as
1553
# versioned-with-no-kind.
1555
for change in tree.iter_changes(tree.basis_tree()):
1556
# Find paths in the working tree that have no kind:
1557
if change[1][1] is not None and change[6][1] is None:
1558
missing.append(change[1][1])
1559
file_list = sorted(missing, reverse=True)
1560
file_deletion_strategy = 'keep'
1561
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1562
keep_files=file_deletion_strategy=='keep',
1563
force=file_deletion_strategy=='force')
1514
self.add_cleanup(tree.unlock)
1515
# Heuristics should probably all move into tree.remove_smart or
1518
added = tree.changes_from(tree.basis_tree(),
1519
specific_files=file_list).added
1520
file_list = sorted([f[0] for f in added], reverse=True)
1521
if len(file_list) == 0:
1522
raise errors.BzrCommandError('No matching files.')
1523
elif file_list is None:
1524
# missing files show up in iter_changes(basis) as
1525
# versioned-with-no-kind.
1527
for change in tree.iter_changes(tree.basis_tree()):
1528
# Find paths in the working tree that have no kind:
1529
if change[1][1] is not None and change[6][1] is None:
1530
missing.append(change[1][1])
1531
file_list = sorted(missing, reverse=True)
1532
file_deletion_strategy = 'keep'
1533
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1534
keep_files=file_deletion_strategy=='keep',
1535
force=file_deletion_strategy=='force')
1568
1538
class cmd_file_id(Command):
2337
2299
filter_by_dir = False
2341
# find the file ids to log and check for directory filtering
2342
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2343
revision, file_list)
2344
for relpath, file_id, kind in file_info_list:
2346
raise errors.BzrCommandError(
2347
"Path unknown at end or start of revision range: %s" %
2349
# If the relpath is the top of the tree, we log everything
2354
file_ids.append(file_id)
2355
filter_by_dir = filter_by_dir or (
2356
kind in ['directory', 'tree-reference'])
2359
# FIXME ? log the current subdir only RBC 20060203
2360
if revision is not None \
2361
and len(revision) > 0 and revision[0].get_branch():
2362
location = revision[0].get_branch()
2301
# find the file ids to log and check for directory filtering
2302
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2303
revision, file_list)
2304
self.add_cleanup(b.unlock)
2305
for relpath, file_id, kind in file_info_list:
2307
raise errors.BzrCommandError(
2308
"Path unknown at end or start of revision range: %s" %
2310
# If the relpath is the top of the tree, we log everything
2365
dir, relpath = bzrdir.BzrDir.open_containing(location)
2366
b = dir.open_branch()
2368
rev1, rev2 = _get_revision_range(revision, b, self.name())
2370
# Decide on the type of delta & diff filtering to use
2371
# TODO: add an --all-files option to make this configurable & consistent
2379
diff_type = 'partial'
2383
# Build the log formatter
2384
if log_format is None:
2385
log_format = log.log_formatter_registry.get_default(b)
2386
# Make a non-encoding output to include the diffs - bug 328007
2387
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2388
lf = log_format(show_ids=show_ids, to_file=self.outf,
2389
to_exact_file=unencoded_output,
2390
show_timezone=timezone,
2391
delta_format=get_verbosity_level(),
2393
show_advice=levels is None)
2395
# Choose the algorithm for doing the logging. It's annoying
2396
# having multiple code paths like this but necessary until
2397
# the underlying repository format is faster at generating
2398
# deltas or can provide everything we need from the indices.
2399
# The default algorithm - match-using-deltas - works for
2400
# multiple files and directories and is faster for small
2401
# amounts of history (200 revisions say). However, it's too
2402
# slow for logging a single file in a repository with deep
2403
# history, i.e. > 10K revisions. In the spirit of "do no
2404
# evil when adding features", we continue to use the
2405
# original algorithm - per-file-graph - for the "single
2406
# file that isn't a directory without showing a delta" case.
2407
partial_history = revision and b.repository._format.supports_chks
2408
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2409
or delta_type or partial_history)
2411
# Build the LogRequest and execute it
2412
if len(file_ids) == 0:
2414
rqst = make_log_request_dict(
2415
direction=direction, specific_fileids=file_ids,
2416
start_revision=rev1, end_revision=rev2, limit=limit,
2417
message_search=message, delta_type=delta_type,
2418
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2419
Logger(b, rqst).show(lf)
2315
file_ids.append(file_id)
2316
filter_by_dir = filter_by_dir or (
2317
kind in ['directory', 'tree-reference'])
2320
# FIXME ? log the current subdir only RBC 20060203
2321
if revision is not None \
2322
and len(revision) > 0 and revision[0].get_branch():
2323
location = revision[0].get_branch()
2326
dir, relpath = bzrdir.BzrDir.open_containing(location)
2327
b = dir.open_branch()
2329
self.add_cleanup(b.unlock)
2330
rev1, rev2 = _get_revision_range(revision, b, self.name())
2332
# Decide on the type of delta & diff filtering to use
2333
# TODO: add an --all-files option to make this configurable & consistent
2341
diff_type = 'partial'
2345
# Build the log formatter
2346
if log_format is None:
2347
log_format = log.log_formatter_registry.get_default(b)
2348
# Make a non-encoding output to include the diffs - bug 328007
2349
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2350
lf = log_format(show_ids=show_ids, to_file=self.outf,
2351
to_exact_file=unencoded_output,
2352
show_timezone=timezone,
2353
delta_format=get_verbosity_level(),
2355
show_advice=levels is None)
2357
# Choose the algorithm for doing the logging. It's annoying
2358
# having multiple code paths like this but necessary until
2359
# the underlying repository format is faster at generating
2360
# deltas or can provide everything we need from the indices.
2361
# The default algorithm - match-using-deltas - works for
2362
# multiple files and directories and is faster for small
2363
# amounts of history (200 revisions say). However, it's too
2364
# slow for logging a single file in a repository with deep
2365
# history, i.e. > 10K revisions. In the spirit of "do no
2366
# evil when adding features", we continue to use the
2367
# original algorithm - per-file-graph - for the "single
2368
# file that isn't a directory without showing a delta" case.
2369
partial_history = revision and b.repository._format.supports_chks
2370
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2371
or delta_type or partial_history)
2373
# Build the LogRequest and execute it
2374
if len(file_ids) == 0:
2376
rqst = make_log_request_dict(
2377
direction=direction, specific_fileids=file_ids,
2378
start_revision=rev1, end_revision=rev2, limit=limit,
2379
message_search=message, delta_type=delta_type,
2380
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2381
Logger(b, rqst).show(lf)
2425
2384
def _get_revision_range(revisionspec_list, branch, command_name):
2570
2527
note("Ignoring files outside view. View is %s" % view_str)
2572
2529
tree.lock_read()
2574
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2575
from_dir=relpath, recursive=recursive):
2576
# Apply additional masking
2577
if not all and not selection[fc]:
2579
if kind is not None and fkind != kind:
2584
fullpath = osutils.pathjoin(relpath, fp)
2587
views.check_path_in_view(tree, fullpath)
2588
except errors.FileOutsideView:
2530
self.add_cleanup(tree.unlock)
2531
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2532
from_dir=relpath, recursive=recursive):
2533
# Apply additional masking
2534
if not all and not selection[fc]:
2536
if kind is not None and fkind != kind:
2541
fullpath = osutils.pathjoin(relpath, fp)
2544
views.check_path_in_view(tree, fullpath)
2545
except errors.FileOutsideView:
2593
fp = osutils.pathjoin(prefix, fp)
2594
kindch = entry.kind_character()
2595
outstring = fp + kindch
2596
ui.ui_factory.clear_term()
2598
outstring = '%-8s %s' % (fc, outstring)
2599
if show_ids and fid is not None:
2600
outstring = "%-50s %s" % (outstring, fid)
2550
fp = osutils.pathjoin(prefix, fp)
2551
kindch = entry.kind_character()
2552
outstring = fp + kindch
2553
ui.ui_factory.clear_term()
2555
outstring = '%-8s %s' % (fc, outstring)
2556
if show_ids and fid is not None:
2557
outstring = "%-50s %s" % (outstring, fid)
2558
self.outf.write(outstring + '\n')
2560
self.outf.write(fp + '\0')
2563
self.outf.write(fid)
2564
self.outf.write('\0')
2572
self.outf.write('%-50s %s\n' % (outstring, my_id))
2601
2574
self.outf.write(outstring + '\n')
2603
self.outf.write(fp + '\0')
2606
self.outf.write(fid)
2607
self.outf.write('\0')
2615
self.outf.write('%-50s %s\n' % (outstring, my_id))
2617
self.outf.write(outstring + '\n')
2622
2577
class cmd_unknowns(Command):
3570
3521
verbose = not is_quiet()
3571
3522
# TODO: should possibly lock the history file...
3572
3523
benchfile = open(".perf_history", "at", buffering=1)
3524
self.add_cleanup(benchfile.close)
3574
3526
test_suite_factory = None
3575
3527
benchfile = None
3577
selftest_kwargs = {"verbose": verbose,
3579
"stop_on_failure": one,
3580
"transport": transport,
3581
"test_suite_factory": test_suite_factory,
3582
"lsprof_timed": lsprof_timed,
3583
"lsprof_tests": lsprof_tests,
3584
"bench_history": benchfile,
3585
"matching_tests_first": first,
3586
"list_only": list_only,
3587
"random_seed": randomize,
3588
"exclude_pattern": exclude,
3590
"load_list": load_list,
3591
"debug_flags": debugflag,
3592
"starting_with": starting_with
3594
selftest_kwargs.update(self.additional_selftest_args)
3595
result = selftest(**selftest_kwargs)
3597
if benchfile is not None:
3528
selftest_kwargs = {"verbose": verbose,
3530
"stop_on_failure": one,
3531
"transport": transport,
3532
"test_suite_factory": test_suite_factory,
3533
"lsprof_timed": lsprof_timed,
3534
"lsprof_tests": lsprof_tests,
3535
"bench_history": benchfile,
3536
"matching_tests_first": first,
3537
"list_only": list_only,
3538
"random_seed": randomize,
3539
"exclude_pattern": exclude,
3541
"load_list": load_list,
3542
"debug_flags": debugflag,
3543
"starting_with": starting_with
3545
selftest_kwargs.update(self.additional_selftest_args)
3546
result = selftest(**selftest_kwargs)
3599
3547
return int(not result)
3776
3720
view_info = _get_view_info_for_change_reporter(tree)
3777
3721
change_reporter = delta._ChangeReporter(
3778
3722
unversioned_filter=tree.is_ignored, view_info=view_info)
3781
pb = ui.ui_factory.nested_progress_bar()
3782
cleanups.append(pb.finished)
3784
cleanups.append(tree.unlock)
3785
if location is not None:
3787
mergeable = bundle.read_mergeable_from_url(location,
3788
possible_transports=possible_transports)
3789
except errors.NotABundle:
3793
raise errors.BzrCommandError('Cannot use --uncommitted'
3794
' with bundles or merge directives.')
3796
if revision is not None:
3797
raise errors.BzrCommandError(
3798
'Cannot use -r with merge directives or bundles')
3799
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3802
if merger is None and uncommitted:
3803
if revision is not None and len(revision) > 0:
3804
raise errors.BzrCommandError('Cannot use --uncommitted and'
3805
' --revision at the same time.')
3806
merger = self.get_merger_from_uncommitted(tree, location, pb,
3808
allow_pending = False
3811
merger, allow_pending = self._get_merger_from_branch(tree,
3812
location, revision, remember, possible_transports, pb)
3814
merger.merge_type = merge_type
3815
merger.reprocess = reprocess
3816
merger.show_base = show_base
3817
self.sanity_check_merger(merger)
3818
if (merger.base_rev_id == merger.other_rev_id and
3819
merger.other_rev_id is not None):
3820
note('Nothing to do.')
3723
pb = ui.ui_factory.nested_progress_bar()
3724
self.add_cleanup(pb.finished)
3726
self.add_cleanup(tree.unlock)
3727
if location is not None:
3729
mergeable = bundle.read_mergeable_from_url(location,
3730
possible_transports=possible_transports)
3731
except errors.NotABundle:
3735
raise errors.BzrCommandError('Cannot use --uncommitted'
3736
' with bundles or merge directives.')
3738
if revision is not None:
3739
raise errors.BzrCommandError(
3740
'Cannot use -r with merge directives or bundles')
3741
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3744
if merger is None and uncommitted:
3745
if revision is not None and len(revision) > 0:
3746
raise errors.BzrCommandError('Cannot use --uncommitted and'
3747
' --revision at the same time.')
3748
merger = self.get_merger_from_uncommitted(tree, location, pb)
3749
allow_pending = False
3752
merger, allow_pending = self._get_merger_from_branch(tree,
3753
location, revision, remember, possible_transports, pb)
3755
merger.merge_type = merge_type
3756
merger.reprocess = reprocess
3757
merger.show_base = show_base
3758
self.sanity_check_merger(merger)
3759
if (merger.base_rev_id == merger.other_rev_id and
3760
merger.other_rev_id is not None):
3761
note('Nothing to do.')
3764
if merger.interesting_files is not None:
3765
raise errors.BzrCommandError('Cannot pull individual files')
3766
if (merger.base_rev_id == tree.last_revision()):
3767
result = tree.pull(merger.other_branch, False,
3768
merger.other_rev_id)
3769
result.report(self.outf)
3823
if merger.interesting_files is not None:
3824
raise errors.BzrCommandError('Cannot pull individual files')
3825
if (merger.base_rev_id == tree.last_revision()):
3826
result = tree.pull(merger.other_branch, False,
3827
merger.other_rev_id)
3828
result.report(self.outf)
3830
if merger.this_basis is None:
3831
raise errors.BzrCommandError(
3832
"This branch has no commits."
3833
" (perhaps you would prefer 'bzr pull')")
3835
return self._do_preview(merger, cleanups)
3837
return self._do_interactive(merger, cleanups)
3839
return self._do_merge(merger, change_reporter, allow_pending,
3842
for cleanup in reversed(cleanups):
3771
if merger.this_basis is None:
3772
raise errors.BzrCommandError(
3773
"This branch has no commits."
3774
" (perhaps you would prefer 'bzr pull')")
3776
return self._do_preview(merger)
3778
return self._do_interactive(merger)
3780
return self._do_merge(merger, change_reporter, allow_pending,
3845
def _get_preview(self, merger, cleanups):
3783
def _get_preview(self, merger):
3846
3784
tree_merger = merger.make_merger()
3847
3785
tt = tree_merger.make_preview_transform()
3848
cleanups.append(tt.finalize)
3786
self.add_cleanup(tt.finalize)
3849
3787
result_tree = tt.get_preview_tree()
3850
3788
return result_tree
3852
def _do_preview(self, merger, cleanups):
3790
def _do_preview(self, merger):
3853
3791
from bzrlib.diff import show_diff_trees
3854
result_tree = self._get_preview(merger, cleanups)
3792
result_tree = self._get_preview(merger)
3855
3793
show_diff_trees(merger.this_tree, result_tree, self.outf,
3856
3794
old_label='', new_label='')
4049
3985
merge_type = _mod_merge.Merge3Merger
4050
3986
tree, file_list = tree_files(file_list)
4051
3987
tree.lock_write()
4053
parents = tree.get_parent_ids()
4054
if len(parents) != 2:
4055
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4056
" merges. Not cherrypicking or"
4058
repository = tree.branch.repository
4059
interesting_ids = None
4061
conflicts = tree.conflicts()
4062
if file_list is not None:
4063
interesting_ids = set()
4064
for filename in file_list:
4065
file_id = tree.path2id(filename)
4067
raise errors.NotVersionedError(filename)
4068
interesting_ids.add(file_id)
4069
if tree.kind(file_id) != "directory":
3988
self.add_cleanup(tree.unlock)
3989
parents = tree.get_parent_ids()
3990
if len(parents) != 2:
3991
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3992
" merges. Not cherrypicking or"
3994
repository = tree.branch.repository
3995
interesting_ids = None
3997
conflicts = tree.conflicts()
3998
if file_list is not None:
3999
interesting_ids = set()
4000
for filename in file_list:
4001
file_id = tree.path2id(filename)
4003
raise errors.NotVersionedError(filename)
4004
interesting_ids.add(file_id)
4005
if tree.kind(file_id) != "directory":
4072
for name, ie in tree.inventory.iter_entries(file_id):
4073
interesting_ids.add(ie.file_id)
4074
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4076
# Remerge only supports resolving contents conflicts
4077
allowed_conflicts = ('text conflict', 'contents conflict')
4078
restore_files = [c.path for c in conflicts
4079
if c.typestring in allowed_conflicts]
4080
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4081
tree.set_conflicts(ConflictList(new_conflicts))
4082
if file_list is not None:
4083
restore_files = file_list
4084
for filename in restore_files:
4086
restore(tree.abspath(filename))
4087
except errors.NotConflicted:
4089
# Disable pending merges, because the file texts we are remerging
4090
# have not had those merges performed. If we use the wrong parents
4091
# list, we imply that the working tree text has seen and rejected
4092
# all the changes from the other tree, when in fact those changes
4093
# have not yet been seen.
4094
pb = ui.ui_factory.nested_progress_bar()
4095
tree.set_parent_ids(parents[:1])
4008
for name, ie in tree.inventory.iter_entries(file_id):
4009
interesting_ids.add(ie.file_id)
4010
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4012
# Remerge only supports resolving contents conflicts
4013
allowed_conflicts = ('text conflict', 'contents conflict')
4014
restore_files = [c.path for c in conflicts
4015
if c.typestring in allowed_conflicts]
4016
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4017
tree.set_conflicts(ConflictList(new_conflicts))
4018
if file_list is not None:
4019
restore_files = file_list
4020
for filename in restore_files:
4097
merger = _mod_merge.Merger.from_revision_ids(pb,
4099
merger.interesting_ids = interesting_ids
4100
merger.merge_type = merge_type
4101
merger.show_base = show_base
4102
merger.reprocess = reprocess
4103
conflicts = merger.do_merge()
4105
tree.set_parent_ids(parents)
4022
restore(tree.abspath(filename))
4023
except errors.NotConflicted:
4025
# Disable pending merges, because the file texts we are remerging
4026
# have not had those merges performed. If we use the wrong parents
4027
# list, we imply that the working tree text has seen and rejected
4028
# all the changes from the other tree, when in fact those changes
4029
# have not yet been seen.
4030
pb = ui.ui_factory.nested_progress_bar()
4031
tree.set_parent_ids(parents[:1])
4033
merger = _mod_merge.Merger.from_revision_ids(pb,
4035
merger.interesting_ids = interesting_ids
4036
merger.merge_type = merge_type
4037
merger.show_base = show_base
4038
merger.reprocess = reprocess
4039
conflicts = merger.do_merge()
4041
tree.set_parent_ids(parents)
4109
4043
if conflicts > 0:
4333
4265
if remote_branch.base == local_branch.base:
4334
4266
remote_branch = local_branch
4268
local_branch.lock_read()
4269
self.add_cleanup(local_branch.unlock)
4336
4270
local_revid_range = _revision_range_to_revid_range(
4337
4271
_get_revision_range(my_revision, local_branch,
4274
remote_branch.lock_read()
4275
self.add_cleanup(remote_branch.unlock)
4340
4276
remote_revid_range = _revision_range_to_revid_range(
4341
4277
_get_revision_range(revision,
4342
4278
remote_branch, self.name()))
4344
local_branch.lock_read()
4346
remote_branch.lock_read()
4348
local_extra, remote_extra = find_unmerged(
4349
local_branch, remote_branch, restrict,
4350
backward=not reverse,
4351
include_merges=include_merges,
4352
local_revid_range=local_revid_range,
4353
remote_revid_range=remote_revid_range)
4355
if log_format is None:
4356
registry = log.log_formatter_registry
4357
log_format = registry.get_default(local_branch)
4358
lf = log_format(to_file=self.outf,
4360
show_timezone='original')
4363
if local_extra and not theirs_only:
4364
message("You have %d extra revision(s):\n" %
4366
for revision in iter_log_revisions(local_extra,
4367
local_branch.repository,
4369
lf.log_revision(revision)
4370
printed_local = True
4373
printed_local = False
4375
if remote_extra and not mine_only:
4376
if printed_local is True:
4378
message("You are missing %d revision(s):\n" %
4380
for revision in iter_log_revisions(remote_extra,
4381
remote_branch.repository,
4383
lf.log_revision(revision)
4386
if mine_only and not local_extra:
4387
# We checked local, and found nothing extra
4388
message('This branch is up to date.\n')
4389
elif theirs_only and not remote_extra:
4390
# We checked remote, and found nothing extra
4391
message('Other branch is up to date.\n')
4392
elif not (mine_only or theirs_only or local_extra or
4394
# We checked both branches, and neither one had extra
4396
message("Branches are up to date.\n")
4398
remote_branch.unlock()
4400
local_branch.unlock()
4280
local_extra, remote_extra = find_unmerged(
4281
local_branch, remote_branch, restrict,
4282
backward=not reverse,
4283
include_merges=include_merges,
4284
local_revid_range=local_revid_range,
4285
remote_revid_range=remote_revid_range)
4287
if log_format is None:
4288
registry = log.log_formatter_registry
4289
log_format = registry.get_default(local_branch)
4290
lf = log_format(to_file=self.outf,
4292
show_timezone='original')
4295
if local_extra and not theirs_only:
4296
message("You have %d extra revision(s):\n" %
4298
for revision in iter_log_revisions(local_extra,
4299
local_branch.repository,
4301
lf.log_revision(revision)
4302
printed_local = True
4305
printed_local = False
4307
if remote_extra and not mine_only:
4308
if printed_local is True:
4310
message("You are missing %d revision(s):\n" %
4312
for revision in iter_log_revisions(remote_extra,
4313
remote_branch.repository,
4315
lf.log_revision(revision)
4318
if mine_only and not local_extra:
4319
# We checked local, and found nothing extra
4320
message('This branch is up to date.\n')
4321
elif theirs_only and not remote_extra:
4322
# We checked remote, and found nothing extra
4323
message('Other branch is up to date.\n')
4324
elif not (mine_only or theirs_only or local_extra or
4326
# We checked both branches, and neither one had extra
4328
message("Branches are up to date.\n")
4401
4330
if not status_code and parent is None and other_branch is not None:
4402
4331
local_branch.lock_write()
4404
# handle race conditions - a parent might be set while we run.
4405
if local_branch.get_parent() is None:
4406
local_branch.set_parent(remote_branch.base)
4408
local_branch.unlock()
4332
self.add_cleanup(local_branch.unlock)
4333
# handle race conditions - a parent might be set while we run.
4334
if local_branch.get_parent() is None:
4335
local_branch.set_parent(remote_branch.base)
4409
4336
return status_code
4533
4458
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4534
4459
if wt is not None:
4461
self.add_cleanup(wt.unlock)
4537
4463
branch.lock_read()
4539
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4541
file_id = wt.path2id(relpath)
4543
file_id = tree.path2id(relpath)
4545
raise errors.NotVersionedError(filename)
4546
file_version = tree.inventory[file_id].revision
4547
if wt is not None and revision is None:
4548
# If there is a tree and we're not annotating historical
4549
# versions, annotate the working tree's content.
4550
annotate_file_tree(wt, file_id, self.outf, long, all,
4553
annotate_file(branch, file_version, file_id, long, all, self.outf,
4464
self.add_cleanup(branch.unlock)
4465
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4467
self.add_cleanup(tree.unlock)
4469
file_id = wt.path2id(relpath)
4471
file_id = tree.path2id(relpath)
4473
raise errors.NotVersionedError(filename)
4474
file_version = tree.inventory[file_id].revision
4475
if wt is not None and revision is None:
4476
# If there is a tree and we're not annotating historical
4477
# versions, annotate the working tree's content.
4478
annotate_file_tree(wt, file_id, self.outf, long, all,
4481
annotate_file(branch, file_version, file_id, long, all, self.outf,
4562
4485
class cmd_re_sign(Command):
5284
5200
branch, relpath = Branch.open_containing(directory)
5285
5201
branch.lock_write()
5288
branch.tags.delete_tag(tag_name)
5289
self.outf.write('Deleted tag %s.\n' % tag_name)
5202
self.add_cleanup(branch.unlock)
5204
branch.tags.delete_tag(tag_name)
5205
self.outf.write('Deleted tag %s.\n' % tag_name)
5208
if len(revision) != 1:
5209
raise errors.BzrCommandError(
5210
"Tags can only be placed on a single revision, "
5212
revision_id = revision[0].as_revision_id(branch)
5292
if len(revision) != 1:
5293
raise errors.BzrCommandError(
5294
"Tags can only be placed on a single revision, "
5296
revision_id = revision[0].as_revision_id(branch)
5298
revision_id = branch.last_revision()
5299
if (not force) and branch.tags.has_tag(tag_name):
5300
raise errors.TagAlreadyExists(tag_name)
5301
branch.tags.set_tag(tag_name, revision_id)
5302
self.outf.write('Created tag %s.\n' % tag_name)
5214
revision_id = branch.last_revision()
5215
if (not force) and branch.tags.has_tag(tag_name):
5216
raise errors.TagAlreadyExists(tag_name)
5217
branch.tags.set_tag(tag_name, revision_id)
5218
self.outf.write('Created tag %s.\n' % tag_name)
5307
5221
class cmd_tags(Command):
5342
5256
branch.lock_read()
5345
graph = branch.repository.get_graph()
5346
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5347
revid1, revid2 = rev1.rev_id, rev2.rev_id
5348
# only show revisions between revid1 and revid2 (inclusive)
5349
tags = [(tag, revid) for tag, revid in tags if
5350
graph.is_between(revid, revid1, revid2)]
5353
elif sort == 'time':
5355
for tag, revid in tags:
5357
revobj = branch.repository.get_revision(revid)
5358
except errors.NoSuchRevision:
5359
timestamp = sys.maxint # place them at the end
5361
timestamp = revobj.timestamp
5362
timestamps[revid] = timestamp
5363
tags.sort(key=lambda x: timestamps[x[1]])
5365
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5366
for index, (tag, revid) in enumerate(tags):
5368
revno = branch.revision_id_to_dotted_revno(revid)
5369
if isinstance(revno, tuple):
5370
revno = '.'.join(map(str, revno))
5371
except errors.NoSuchRevision:
5372
# Bad tag data/merges can lead to tagged revisions
5373
# which are not in this branch. Fail gracefully ...
5375
tags[index] = (tag, revno)
5257
self.add_cleanup(branch.unlock)
5259
graph = branch.repository.get_graph()
5260
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5261
revid1, revid2 = rev1.rev_id, rev2.rev_id
5262
# only show revisions between revid1 and revid2 (inclusive)
5263
tags = [(tag, revid) for tag, revid in tags if
5264
graph.is_between(revid, revid1, revid2)]
5267
elif sort == 'time':
5269
for tag, revid in tags:
5271
revobj = branch.repository.get_revision(revid)
5272
except errors.NoSuchRevision:
5273
timestamp = sys.maxint # place them at the end
5275
timestamp = revobj.timestamp
5276
timestamps[revid] = timestamp
5277
tags.sort(key=lambda x: timestamps[x[1]])
5279
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5280
for index, (tag, revid) in enumerate(tags):
5282
revno = branch.revision_id_to_dotted_revno(revid)
5283
if isinstance(revno, tuple):
5284
revno = '.'.join(map(str, revno))
5285
except errors.NoSuchRevision:
5286
# Bad tag data/merges can lead to tagged revisions
5287
# which are not in this branch. Fail gracefully ...
5289
tags[index] = (tag, revno)
5378
5291
for tag, revspec in tags:
5379
5292
self.outf.write('%-20s %s\n' % (tag, revspec))