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):
1200
1180
' directory exists, but does not already'
1201
1181
' have a control directory. This flag will'
1202
1182
' allow branch to proceed.'),
1184
help="Bind new branch to from location."),
1204
1186
aliases = ['get', 'clone']
1206
1188
def run(self, from_location, to_location=None, revision=None,
1207
1189
hardlink=False, stacked=False, standalone=False, no_tree=False,
1208
use_existing_dir=False, switch=False):
1190
use_existing_dir=False, switch=False, bind=False):
1209
1191
from bzrlib import switch as _mod_switch
1210
1192
from bzrlib.tag import _merge_tags_if_possible
1211
1193
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1213
1195
revision = _get_one_revision('branch', revision)
1214
1196
br_from.lock_read()
1197
self.add_cleanup(br_from.unlock)
1198
if revision is not None:
1199
revision_id = revision.as_revision_id(br_from)
1201
# FIXME - wt.last_revision, fallback to branch, fall back to
1202
# None or perhaps NULL_REVISION to mean copy nothing
1204
revision_id = br_from.last_revision()
1205
if to_location is None:
1206
to_location = urlutils.derive_to_location(from_location)
1207
to_transport = transport.get_transport(to_location)
1216
if revision is not None:
1217
revision_id = revision.as_revision_id(br_from)
1209
to_transport.mkdir('.')
1210
except errors.FileExists:
1211
if not use_existing_dir:
1212
raise errors.BzrCommandError('Target directory "%s" '
1213
'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)
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1217
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'))
1220
raise errors.AlreadyBranchError(to_location)
1221
except errors.NoSuchFile:
1222
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1225
# preserve whatever source format we have.
1226
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1227
possible_transports=[to_transport],
1228
accelerator_tree=accelerator_tree,
1229
hardlink=hardlink, stacked=stacked,
1230
force_new_repo=standalone,
1231
create_tree_if_local=not no_tree,
1232
source_branch=br_from)
1233
branch = dir.open_branch()
1234
except errors.NoSuchRevision:
1235
to_transport.delete_tree('.')
1236
msg = "The branch %s has no revision %s." % (from_location,
1238
raise errors.BzrCommandError(msg)
1239
_merge_tags_if_possible(br_from, branch)
1240
# If the source branch is stacked, the new branch may
1241
# be stacked whether we asked for that explicitly or not.
1242
# We therefore need a try/except here and not just 'if stacked:'
1244
note('Created new stacked branch referring to %s.' %
1245
branch.get_stacked_on_url())
1246
except (errors.NotStacked, errors.UnstackableBranchFormat,
1247
errors.UnstackableRepositoryFormat), e:
1248
note('Branched %d revision(s).' % branch.revno())
1250
# Bind to the parent
1251
parent_branch = Branch.open(from_location)
1252
branch.bind(parent_branch)
1253
note('New branch bound to %s' % from_location)
1255
# Switch to the new branch
1256
wt, _ = WorkingTree.open_containing('.')
1257
_mod_switch.switch(wt.bzrdir, branch)
1258
note('Switched to branch: %s',
1259
urlutils.unescape_for_display(branch.base, 'utf-8'))
1277
1262
class cmd_checkout(Command):
1356
1341
def run(self, dir=u'.'):
1357
1342
tree = WorkingTree.open_containing(dir)[0]
1358
1343
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))
1344
self.add_cleanup(tree.unlock)
1345
new_inv = tree.inventory
1346
old_tree = tree.basis_tree()
1347
old_tree.lock_read()
1348
self.add_cleanup(old_tree.unlock)
1349
old_inv = old_tree.inventory
1351
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1352
for f, paths, c, v, p, n, k, e in iterator:
1353
if paths[0] == paths[1]:
1357
renames.append(paths)
1359
for old_name, new_name in renames:
1360
self.outf.write("%s => %s\n" % (old_name, new_name))
1382
1363
class cmd_update(Command):
1414
1395
tree.lock_tree_write()
1415
1396
branch_location = tree.branch.base
1397
self.add_cleanup(tree.unlock)
1416
1398
# get rid of the final '/' and be ready for display
1417
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1418
1400
self.outf.encoding)
1401
existing_pending_merges = tree.get_parent_ids()[1:]
1405
# may need to fetch data into a heavyweight checkout
1406
# XXX: this may take some time, maybe we should display a
1408
old_tip = branch.update(possible_transports)
1409
if revision is not None:
1410
revision_id = revision[0].as_revision_id(branch)
1412
revision_id = branch.last_revision()
1413
if revision_id == _mod_revision.ensure_null(tree.last_revision()):
1414
revno = branch.revision_id_to_revno(revision_id)
1415
note("Tree is up to date at revision %d of branch %s" %
1416
(revno, branch_location))
1418
view_info = _get_view_info_for_change_reporter(tree)
1419
change_reporter = delta._ChangeReporter(
1420
unversioned_filter=tree.is_ignored,
1421
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'.")
1423
conflicts = tree.update(
1425
possible_transports=possible_transports,
1426
revision=revision_id,
1428
except errors.NoSuchRevision, e:
1429
raise errors.BzrCommandError(
1430
"branch has no revision %s\n"
1431
"bzr update --revision only works"
1432
" for a revision in the branch history"
1434
revno = tree.branch.revision_id_to_revno(
1435
_mod_revision.ensure_null(tree.last_revision()))
1436
note('Updated to revision %d of branch %s' %
1437
(revno, branch_location))
1438
if tree.get_parent_ids()[1:] != existing_pending_merges:
1439
note('Your local commits will now show as pending merges with '
1440
"'bzr status', and can be committed with 'bzr commit'.")
1468
1447
class cmd_info(Command):
1539
1518
file_list = [f for f in file_list]
1541
1520
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')
1521
self.add_cleanup(tree.unlock)
1522
# Heuristics should probably all move into tree.remove_smart or
1525
added = tree.changes_from(tree.basis_tree(),
1526
specific_files=file_list).added
1527
file_list = sorted([f[0] for f in added], reverse=True)
1528
if len(file_list) == 0:
1529
raise errors.BzrCommandError('No matching files.')
1530
elif file_list is None:
1531
# missing files show up in iter_changes(basis) as
1532
# versioned-with-no-kind.
1534
for change in tree.iter_changes(tree.basis_tree()):
1535
# Find paths in the working tree that have no kind:
1536
if change[1][1] is not None and change[6][1] is None:
1537
missing.append(change[1][1])
1538
file_list = sorted(missing, reverse=True)
1539
file_deletion_strategy = 'keep'
1540
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1541
keep_files=file_deletion_strategy=='keep',
1542
force=file_deletion_strategy=='force')
1568
1545
class cmd_file_id(Command):
2337
2306
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()
2308
# find the file ids to log and check for directory filtering
2309
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2310
revision, file_list)
2311
self.add_cleanup(b.unlock)
2312
for relpath, file_id, kind in file_info_list:
2314
raise errors.BzrCommandError(
2315
"Path unknown at end or start of revision range: %s" %
2317
# 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)
2322
file_ids.append(file_id)
2323
filter_by_dir = filter_by_dir or (
2324
kind in ['directory', 'tree-reference'])
2327
# FIXME ? log the current subdir only RBC 20060203
2328
if revision is not None \
2329
and len(revision) > 0 and revision[0].get_branch():
2330
location = revision[0].get_branch()
2333
dir, relpath = bzrdir.BzrDir.open_containing(location)
2334
b = dir.open_branch()
2336
self.add_cleanup(b.unlock)
2337
rev1, rev2 = _get_revision_range(revision, b, self.name())
2339
# Decide on the type of delta & diff filtering to use
2340
# TODO: add an --all-files option to make this configurable & consistent
2348
diff_type = 'partial'
2352
# Build the log formatter
2353
if log_format is None:
2354
log_format = log.log_formatter_registry.get_default(b)
2355
# Make a non-encoding output to include the diffs - bug 328007
2356
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2357
lf = log_format(show_ids=show_ids, to_file=self.outf,
2358
to_exact_file=unencoded_output,
2359
show_timezone=timezone,
2360
delta_format=get_verbosity_level(),
2362
show_advice=levels is None)
2364
# Choose the algorithm for doing the logging. It's annoying
2365
# having multiple code paths like this but necessary until
2366
# the underlying repository format is faster at generating
2367
# deltas or can provide everything we need from the indices.
2368
# The default algorithm - match-using-deltas - works for
2369
# multiple files and directories and is faster for small
2370
# amounts of history (200 revisions say). However, it's too
2371
# slow for logging a single file in a repository with deep
2372
# history, i.e. > 10K revisions. In the spirit of "do no
2373
# evil when adding features", we continue to use the
2374
# original algorithm - per-file-graph - for the "single
2375
# file that isn't a directory without showing a delta" case.
2376
partial_history = revision and b.repository._format.supports_chks
2377
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2378
or delta_type or partial_history)
2380
# Build the LogRequest and execute it
2381
if len(file_ids) == 0:
2383
rqst = make_log_request_dict(
2384
direction=direction, specific_fileids=file_ids,
2385
start_revision=rev1, end_revision=rev2, limit=limit,
2386
message_search=message, delta_type=delta_type,
2387
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2388
Logger(b, rqst).show(lf)
2425
2391
def _get_revision_range(revisionspec_list, branch, command_name):
2570
2534
note("Ignoring files outside view. View is %s" % view_str)
2572
2536
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:
2537
self.add_cleanup(tree.unlock)
2538
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2539
from_dir=relpath, recursive=recursive):
2540
# Apply additional masking
2541
if not all and not selection[fc]:
2543
if kind is not None and fkind != kind:
2548
fullpath = osutils.pathjoin(relpath, fp)
2551
views.check_path_in_view(tree, fullpath)
2552
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)
2557
fp = osutils.pathjoin(prefix, fp)
2558
kindch = entry.kind_character()
2559
outstring = fp + kindch
2560
ui.ui_factory.clear_term()
2562
outstring = '%-8s %s' % (fc, outstring)
2563
if show_ids and fid is not None:
2564
outstring = "%-50s %s" % (outstring, fid)
2565
self.outf.write(outstring + '\n')
2567
self.outf.write(fp + '\0')
2570
self.outf.write(fid)
2571
self.outf.write('\0')
2579
self.outf.write('%-50s %s\n' % (outstring, my_id))
2601
2581
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
2584
class cmd_unknowns(Command):
3570
3532
verbose = not is_quiet()
3571
3533
# TODO: should possibly lock the history file...
3572
3534
benchfile = open(".perf_history", "at", buffering=1)
3535
self.add_cleanup(benchfile.close)
3574
3537
test_suite_factory = None
3575
3538
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:
3539
selftest_kwargs = {"verbose": verbose,
3541
"stop_on_failure": one,
3542
"transport": transport,
3543
"test_suite_factory": test_suite_factory,
3544
"lsprof_timed": lsprof_timed,
3545
"lsprof_tests": lsprof_tests,
3546
"bench_history": benchfile,
3547
"matching_tests_first": first,
3548
"list_only": list_only,
3549
"random_seed": randomize,
3550
"exclude_pattern": exclude,
3552
"load_list": load_list,
3553
"debug_flags": debugflag,
3554
"starting_with": starting_with
3556
selftest_kwargs.update(self.additional_selftest_args)
3557
result = selftest(**selftest_kwargs)
3599
3558
return int(not result)
3776
3731
view_info = _get_view_info_for_change_reporter(tree)
3777
3732
change_reporter = delta._ChangeReporter(
3778
3733
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.')
3734
pb = ui.ui_factory.nested_progress_bar()
3735
self.add_cleanup(pb.finished)
3737
self.add_cleanup(tree.unlock)
3738
if location is not None:
3740
mergeable = bundle.read_mergeable_from_url(location,
3741
possible_transports=possible_transports)
3742
except errors.NotABundle:
3746
raise errors.BzrCommandError('Cannot use --uncommitted'
3747
' with bundles or merge directives.')
3749
if revision is not None:
3750
raise errors.BzrCommandError(
3751
'Cannot use -r with merge directives or bundles')
3752
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3755
if merger is None and uncommitted:
3756
if revision is not None and len(revision) > 0:
3757
raise errors.BzrCommandError('Cannot use --uncommitted and'
3758
' --revision at the same time.')
3759
merger = self.get_merger_from_uncommitted(tree, location, pb)
3760
allow_pending = False
3763
merger, allow_pending = self._get_merger_from_branch(tree,
3764
location, revision, remember, possible_transports, pb)
3766
merger.merge_type = merge_type
3767
merger.reprocess = reprocess
3768
merger.show_base = show_base
3769
self.sanity_check_merger(merger)
3770
if (merger.base_rev_id == merger.other_rev_id and
3771
merger.other_rev_id is not None):
3772
note('Nothing to do.')
3775
if merger.interesting_files is not None:
3776
raise errors.BzrCommandError('Cannot pull individual files')
3777
if (merger.base_rev_id == tree.last_revision()):
3778
result = tree.pull(merger.other_branch, False,
3779
merger.other_rev_id)
3780
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):
3782
if merger.this_basis is None:
3783
raise errors.BzrCommandError(
3784
"This branch has no commits."
3785
" (perhaps you would prefer 'bzr pull')")
3787
return self._do_preview(merger)
3789
return self._do_interactive(merger)
3791
return self._do_merge(merger, change_reporter, allow_pending,
3845
def _get_preview(self, merger, cleanups):
3794
def _get_preview(self, merger):
3846
3795
tree_merger = merger.make_merger()
3847
3796
tt = tree_merger.make_preview_transform()
3848
cleanups.append(tt.finalize)
3797
self.add_cleanup(tt.finalize)
3849
3798
result_tree = tt.get_preview_tree()
3850
3799
return result_tree
3852
def _do_preview(self, merger, cleanups):
3801
def _do_preview(self, merger):
3853
3802
from bzrlib.diff import show_diff_trees
3854
result_tree = self._get_preview(merger, cleanups)
3803
result_tree = self._get_preview(merger)
3855
3804
show_diff_trees(merger.this_tree, result_tree, self.outf,
3856
3805
old_label='', new_label='')
4049
3996
merge_type = _mod_merge.Merge3Merger
4050
3997
tree, file_list = tree_files(file_list)
4051
3998
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":
3999
self.add_cleanup(tree.unlock)
4000
parents = tree.get_parent_ids()
4001
if len(parents) != 2:
4002
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4003
" merges. Not cherrypicking or"
4005
repository = tree.branch.repository
4006
interesting_ids = None
4008
conflicts = tree.conflicts()
4009
if file_list is not None:
4010
interesting_ids = set()
4011
for filename in file_list:
4012
file_id = tree.path2id(filename)
4014
raise errors.NotVersionedError(filename)
4015
interesting_ids.add(file_id)
4016
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])
4019
for name, ie in tree.inventory.iter_entries(file_id):
4020
interesting_ids.add(ie.file_id)
4021
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4023
# Remerge only supports resolving contents conflicts
4024
allowed_conflicts = ('text conflict', 'contents conflict')
4025
restore_files = [c.path for c in conflicts
4026
if c.typestring in allowed_conflicts]
4027
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4028
tree.set_conflicts(ConflictList(new_conflicts))
4029
if file_list is not None:
4030
restore_files = file_list
4031
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)
4033
restore(tree.abspath(filename))
4034
except errors.NotConflicted:
4036
# Disable pending merges, because the file texts we are remerging
4037
# have not had those merges performed. If we use the wrong parents
4038
# list, we imply that the working tree text has seen and rejected
4039
# all the changes from the other tree, when in fact those changes
4040
# have not yet been seen.
4041
pb = ui.ui_factory.nested_progress_bar()
4042
tree.set_parent_ids(parents[:1])
4044
merger = _mod_merge.Merger.from_revision_ids(pb,
4046
merger.interesting_ids = interesting_ids
4047
merger.merge_type = merge_type
4048
merger.show_base = show_base
4049
merger.reprocess = reprocess
4050
conflicts = merger.do_merge()
4052
tree.set_parent_ids(parents)
4109
4054
if conflicts > 0:
4333
4276
if remote_branch.base == local_branch.base:
4334
4277
remote_branch = local_branch
4279
local_branch.lock_read()
4280
self.add_cleanup(local_branch.unlock)
4336
4281
local_revid_range = _revision_range_to_revid_range(
4337
4282
_get_revision_range(my_revision, local_branch,
4285
remote_branch.lock_read()
4286
self.add_cleanup(remote_branch.unlock)
4340
4287
remote_revid_range = _revision_range_to_revid_range(
4341
4288
_get_revision_range(revision,
4342
4289
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()
4291
local_extra, remote_extra = find_unmerged(
4292
local_branch, remote_branch, restrict,
4293
backward=not reverse,
4294
include_merges=include_merges,
4295
local_revid_range=local_revid_range,
4296
remote_revid_range=remote_revid_range)
4298
if log_format is None:
4299
registry = log.log_formatter_registry
4300
log_format = registry.get_default(local_branch)
4301
lf = log_format(to_file=self.outf,
4303
show_timezone='original')
4306
if local_extra and not theirs_only:
4307
message("You have %d extra revision(s):\n" %
4309
for revision in iter_log_revisions(local_extra,
4310
local_branch.repository,
4312
lf.log_revision(revision)
4313
printed_local = True
4316
printed_local = False
4318
if remote_extra and not mine_only:
4319
if printed_local is True:
4321
message("You are missing %d revision(s):\n" %
4323
for revision in iter_log_revisions(remote_extra,
4324
remote_branch.repository,
4326
lf.log_revision(revision)
4329
if mine_only and not local_extra:
4330
# We checked local, and found nothing extra
4331
message('This branch is up to date.\n')
4332
elif theirs_only and not remote_extra:
4333
# We checked remote, and found nothing extra
4334
message('Other branch is up to date.\n')
4335
elif not (mine_only or theirs_only or local_extra or
4337
# We checked both branches, and neither one had extra
4339
message("Branches are up to date.\n")
4401
4341
if not status_code and parent is None and other_branch is not None:
4402
4342
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()
4343
self.add_cleanup(local_branch.unlock)
4344
# handle race conditions - a parent might be set while we run.
4345
if local_branch.get_parent() is None:
4346
local_branch.set_parent(remote_branch.base)
4409
4347
return status_code
4533
4469
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4534
4470
if wt is not None:
4472
self.add_cleanup(wt.unlock)
4537
4474
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,
4475
self.add_cleanup(branch.unlock)
4476
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4478
self.add_cleanup(tree.unlock)
4480
file_id = wt.path2id(relpath)
4482
file_id = tree.path2id(relpath)
4484
raise errors.NotVersionedError(filename)
4485
file_version = tree.inventory[file_id].revision
4486
if wt is not None and revision is None:
4487
# If there is a tree and we're not annotating historical
4488
# versions, annotate the working tree's content.
4489
annotate_file_tree(wt, file_id, self.outf, long, all,
4492
annotate_file(branch, file_version, file_id, long, all, self.outf,
4562
4496
class cmd_re_sign(Command):
5284
5211
branch, relpath = Branch.open_containing(directory)
5285
5212
branch.lock_write()
5288
branch.tags.delete_tag(tag_name)
5289
self.outf.write('Deleted tag %s.\n' % tag_name)
5213
self.add_cleanup(branch.unlock)
5215
branch.tags.delete_tag(tag_name)
5216
self.outf.write('Deleted tag %s.\n' % tag_name)
5219
if len(revision) != 1:
5220
raise errors.BzrCommandError(
5221
"Tags can only be placed on a single revision, "
5223
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)
5225
revision_id = branch.last_revision()
5226
if (not force) and branch.tags.has_tag(tag_name):
5227
raise errors.TagAlreadyExists(tag_name)
5228
branch.tags.set_tag(tag_name, revision_id)
5229
self.outf.write('Created tag %s.\n' % tag_name)
5307
5232
class cmd_tags(Command):
5342
5267
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)
5268
self.add_cleanup(branch.unlock)
5270
graph = branch.repository.get_graph()
5271
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5272
revid1, revid2 = rev1.rev_id, rev2.rev_id
5273
# only show revisions between revid1 and revid2 (inclusive)
5274
tags = [(tag, revid) for tag, revid in tags if
5275
graph.is_between(revid, revid1, revid2)]
5278
elif sort == 'time':
5280
for tag, revid in tags:
5282
revobj = branch.repository.get_revision(revid)
5283
except errors.NoSuchRevision:
5284
timestamp = sys.maxint # place them at the end
5286
timestamp = revobj.timestamp
5287
timestamps[revid] = timestamp
5288
tags.sort(key=lambda x: timestamps[x[1]])
5290
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5291
for index, (tag, revid) in enumerate(tags):
5293
revno = branch.revision_id_to_dotted_revno(revid)
5294
if isinstance(revno, tuple):
5295
revno = '.'.join(map(str, revno))
5296
except errors.NoSuchRevision:
5297
# Bad tag data/merges can lead to tagged revisions
5298
# which are not in this branch. Fail gracefully ...
5300
tags[index] = (tag, revno)
5378
5302
for tag, revspec in tags:
5379
5303
self.outf.write('%-20s %s\n' % (tag, revspec))