545
542
wt = WorkingTree.open_containing(directory)[0]
545
self.add_cleanup(wt.unlock)
548
546
except (errors.NoWorkingTree, errors.NotLocalUrl):
550
548
b = Branch.open_containing(directory)[0]
554
if revision is not None:
555
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
556
if revision_info_list is not None:
557
for rev_str in revision_info_list:
558
rev_spec = RevisionSpec.from_string(rev_str)
559
revision_ids.append(rev_spec.as_revision_id(b))
560
# No arguments supplied, default to the last revision
561
if len(revision_ids) == 0:
564
raise errors.NoWorkingTree(directory)
565
revision_ids.append(wt.last_revision())
567
revision_ids.append(b.last_revision())
571
for revision_id in revision_ids:
573
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
574
revno = '.'.join(str(i) for i in dotted_revno)
575
except errors.NoSuchRevision:
577
maxlen = max(maxlen, len(revno))
578
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])
585
579
for ri in revinfos:
586
580
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
735
727
revision = _get_one_revision('inventory', revision)
736
728
work_tree, file_list = tree_files(file_list)
737
729
work_tree.lock_read()
739
if revision is not None:
740
tree = revision.as_tree(work_tree.branch)
742
extra_trees = [work_tree]
748
if file_list is not None:
749
file_ids = tree.paths2ids(file_list, trees=extra_trees,
750
require_versioned=True)
751
# find_ids_across_trees may include some paths that don't
753
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
754
for file_id in file_ids if file_id in tree)
756
entries = tree.inventory.entries()
759
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()
762
752
for path, entry in entries:
763
753
if kind and kind != entry.kind:
1012
998
if branch_from is not branch_to:
1013
999
branch_from.lock_read()
1015
if revision is not None:
1016
revision_id = revision.as_revision_id(branch_from)
1018
branch_to.lock_write()
1020
if tree_to is not None:
1021
view_info = _get_view_info_for_change_reporter(tree_to)
1022
change_reporter = delta._ChangeReporter(
1023
unversioned_filter=tree_to.is_ignored,
1024
view_info=view_info)
1025
result = tree_to.pull(
1026
branch_from, overwrite, revision_id, change_reporter,
1027
possible_transports=possible_transports, local=local)
1029
result = branch_to.pull(
1030
branch_from, overwrite, revision_id, local=local)
1032
result.report(self.outf)
1033
if verbose and result.old_revid != result.new_revid:
1034
log.show_branch_change(
1035
branch_to, self.outf, result.old_revno,
1040
if branch_from is not branch_to:
1041
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,
1044
1025
class cmd_push(Command):
1199
1180
' directory exists, but does not already'
1200
1181
' have a control directory. This flag will'
1201
1182
' allow branch to proceed.'),
1184
help="Bind new branch to from location."),
1203
1186
aliases = ['get', 'clone']
1205
1188
def run(self, from_location, to_location=None, revision=None,
1206
1189
hardlink=False, stacked=False, standalone=False, no_tree=False,
1207
use_existing_dir=False, switch=False):
1190
use_existing_dir=False, switch=False, bind=False):
1208
1191
from bzrlib import switch as _mod_switch
1209
1192
from bzrlib.tag import _merge_tags_if_possible
1210
1193
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1212
1195
revision = _get_one_revision('branch', revision)
1213
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)
1215
if revision is not None:
1216
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)
1218
# FIXME - wt.last_revision, fallback to branch, fall back to
1219
# None or perhaps NULL_REVISION to mean copy nothing
1221
revision_id = br_from.last_revision()
1222
if to_location is None:
1223
to_location = urlutils.derive_to_location(from_location)
1224
to_transport = transport.get_transport(to_location)
1226
to_transport.mkdir('.')
1227
except errors.FileExists:
1228
if not use_existing_dir:
1229
raise errors.BzrCommandError('Target directory "%s" '
1230
'already exists.' % to_location)
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1217
except errors.NotBranchError:
1233
bzrdir.BzrDir.open_from_transport(to_transport)
1234
except errors.NotBranchError:
1237
raise errors.AlreadyBranchError(to_location)
1238
except errors.NoSuchFile:
1239
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1242
# preserve whatever source format we have.
1243
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1244
possible_transports=[to_transport],
1245
accelerator_tree=accelerator_tree,
1246
hardlink=hardlink, stacked=stacked,
1247
force_new_repo=standalone,
1248
create_tree_if_local=not no_tree,
1249
source_branch=br_from)
1250
branch = dir.open_branch()
1251
except errors.NoSuchRevision:
1252
to_transport.delete_tree('.')
1253
msg = "The branch %s has no revision %s." % (from_location,
1255
raise errors.BzrCommandError(msg)
1256
_merge_tags_if_possible(br_from, branch)
1257
# If the source branch is stacked, the new branch may
1258
# be stacked whether we asked for that explicitly or not.
1259
# We therefore need a try/except here and not just 'if stacked:'
1261
note('Created new stacked branch referring to %s.' %
1262
branch.get_stacked_on_url())
1263
except (errors.NotStacked, errors.UnstackableBranchFormat,
1264
errors.UnstackableRepositoryFormat), e:
1265
note('Branched %d revision(s).' % branch.revno())
1267
# Switch to the new branch
1268
wt, _ = WorkingTree.open_containing('.')
1269
_mod_switch.switch(wt.bzrdir, branch)
1270
note('Switched to branch: %s',
1271
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'))
1276
1262
class cmd_checkout(Command):
1355
1341
def run(self, dir=u'.'):
1356
1342
tree = WorkingTree.open_containing(dir)[0]
1357
1343
tree.lock_read()
1359
new_inv = tree.inventory
1360
old_tree = tree.basis_tree()
1361
old_tree.lock_read()
1363
old_inv = old_tree.inventory
1365
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1366
for f, paths, c, v, p, n, k, e in iterator:
1367
if paths[0] == paths[1]:
1371
renames.append(paths)
1373
for old_name, new_name in renames:
1374
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))
1381
1363
class cmd_update(Command):
1405
1395
tree.lock_tree_write()
1406
1396
branch_location = tree.branch.base
1397
self.add_cleanup(tree.unlock)
1407
1398
# get rid of the final '/' and be ready for display
1408
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
1409
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)
1411
existing_pending_merges = tree.get_parent_ids()[1:]
1412
last_rev = _mod_revision.ensure_null(tree.last_revision())
1413
if last_rev == _mod_revision.ensure_null(
1414
tree.branch.last_revision()):
1415
# may be up to date, check master too.
1416
if master is None or last_rev == _mod_revision.ensure_null(
1417
master.last_revision()):
1418
revno = tree.branch.revision_id_to_revno(last_rev)
1419
note('Tree is up to date at revision %d of branch %s'
1420
% (revno, branch_location))
1422
view_info = _get_view_info_for_change_reporter(tree)
1423
1423
conflicts = tree.update(
1424
delta._ChangeReporter(unversioned_filter=tree.is_ignored,
1425
view_info=view_info), possible_transports=possible_transports)
1426
revno = tree.branch.revision_id_to_revno(
1427
_mod_revision.ensure_null(tree.last_revision()))
1428
note('Updated to revision %d of branch %s' %
1429
(revno, branch_location))
1430
if tree.get_parent_ids()[1:] != existing_pending_merges:
1431
note('Your local commits will now show as pending merges with '
1432
"'bzr status', and can be committed with 'bzr commit'.")
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'.")
1441
1447
class cmd_info(Command):
1512
1518
file_list = [f for f in file_list]
1514
1520
tree.lock_write()
1516
# Heuristics should probably all move into tree.remove_smart or
1519
added = tree.changes_from(tree.basis_tree(),
1520
specific_files=file_list).added
1521
file_list = sorted([f[0] for f in added], reverse=True)
1522
if len(file_list) == 0:
1523
raise errors.BzrCommandError('No matching files.')
1524
elif file_list is None:
1525
# missing files show up in iter_changes(basis) as
1526
# versioned-with-no-kind.
1528
for change in tree.iter_changes(tree.basis_tree()):
1529
# Find paths in the working tree that have no kind:
1530
if change[1][1] is not None and change[6][1] is None:
1531
missing.append(change[1][1])
1532
file_list = sorted(missing, reverse=True)
1533
file_deletion_strategy = 'keep'
1534
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1535
keep_files=file_deletion_strategy=='keep',
1536
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')
1541
1545
class cmd_file_id(Command):
2310
2306
filter_by_dir = False
2314
# find the file ids to log and check for directory filtering
2315
b, file_info_list, rev1, rev2 = _get_info_for_log_files(
2316
revision, file_list)
2317
for relpath, file_id, kind in file_info_list:
2319
raise errors.BzrCommandError(
2320
"Path unknown at end or start of revision range: %s" %
2322
# If the relpath is the top of the tree, we log everything
2327
file_ids.append(file_id)
2328
filter_by_dir = filter_by_dir or (
2329
kind in ['directory', 'tree-reference'])
2332
# FIXME ? log the current subdir only RBC 20060203
2333
if revision is not None \
2334
and len(revision) > 0 and revision[0].get_branch():
2335
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
2338
dir, relpath = bzrdir.BzrDir.open_containing(location)
2339
b = dir.open_branch()
2341
rev1, rev2 = _get_revision_range(revision, b, self.name())
2343
# Decide on the type of delta & diff filtering to use
2344
# TODO: add an --all-files option to make this configurable & consistent
2352
diff_type = 'partial'
2356
# Build the log formatter
2357
if log_format is None:
2358
log_format = log.log_formatter_registry.get_default(b)
2359
# Make a non-encoding output to include the diffs - bug 328007
2360
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2361
lf = log_format(show_ids=show_ids, to_file=self.outf,
2362
to_exact_file=unencoded_output,
2363
show_timezone=timezone,
2364
delta_format=get_verbosity_level(),
2366
show_advice=levels is None)
2368
# Choose the algorithm for doing the logging. It's annoying
2369
# having multiple code paths like this but necessary until
2370
# the underlying repository format is faster at generating
2371
# deltas or can provide everything we need from the indices.
2372
# The default algorithm - match-using-deltas - works for
2373
# multiple files and directories and is faster for small
2374
# amounts of history (200 revisions say). However, it's too
2375
# slow for logging a single file in a repository with deep
2376
# history, i.e. > 10K revisions. In the spirit of "do no
2377
# evil when adding features", we continue to use the
2378
# original algorithm - per-file-graph - for the "single
2379
# file that isn't a directory without showing a delta" case.
2380
partial_history = revision and b.repository._format.supports_chks
2381
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2382
or delta_type or partial_history)
2384
# Build the LogRequest and execute it
2385
if len(file_ids) == 0:
2387
rqst = make_log_request_dict(
2388
direction=direction, specific_fileids=file_ids,
2389
start_revision=rev1, end_revision=rev2, limit=limit,
2390
message_search=message, delta_type=delta_type,
2391
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2392
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)
2398
2391
def _get_revision_range(revisionspec_list, branch, command_name):
2543
2534
note("Ignoring files outside view. View is %s" % view_str)
2545
2536
tree.lock_read()
2547
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2548
from_dir=relpath, recursive=recursive):
2549
# Apply additional masking
2550
if not all and not selection[fc]:
2552
if kind is not None and fkind != kind:
2557
fullpath = osutils.pathjoin(relpath, fp)
2560
views.check_path_in_view(tree, fullpath)
2561
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:
2566
fp = osutils.pathjoin(prefix, fp)
2567
kindch = entry.kind_character()
2568
outstring = fp + kindch
2569
ui.ui_factory.clear_term()
2571
outstring = '%-8s %s' % (fc, outstring)
2572
if show_ids and fid is not None:
2573
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))
2574
2581
self.outf.write(outstring + '\n')
2576
self.outf.write(fp + '\0')
2579
self.outf.write(fid)
2580
self.outf.write('\0')
2588
self.outf.write('%-50s %s\n' % (outstring, my_id))
2590
self.outf.write(outstring + '\n')
2595
2584
class cmd_unknowns(Command):
3543
3532
verbose = not is_quiet()
3544
3533
# TODO: should possibly lock the history file...
3545
3534
benchfile = open(".perf_history", "at", buffering=1)
3535
self.add_cleanup(benchfile.close)
3547
3537
test_suite_factory = None
3548
3538
benchfile = None
3550
selftest_kwargs = {"verbose": verbose,
3552
"stop_on_failure": one,
3553
"transport": transport,
3554
"test_suite_factory": test_suite_factory,
3555
"lsprof_timed": lsprof_timed,
3556
"lsprof_tests": lsprof_tests,
3557
"bench_history": benchfile,
3558
"matching_tests_first": first,
3559
"list_only": list_only,
3560
"random_seed": randomize,
3561
"exclude_pattern": exclude,
3563
"load_list": load_list,
3564
"debug_flags": debugflag,
3565
"starting_with": starting_with
3567
selftest_kwargs.update(self.additional_selftest_args)
3568
result = selftest(**selftest_kwargs)
3570
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)
3572
3558
return int(not result)
3749
3731
view_info = _get_view_info_for_change_reporter(tree)
3750
3732
change_reporter = delta._ChangeReporter(
3751
3733
unversioned_filter=tree.is_ignored, view_info=view_info)
3754
pb = ui.ui_factory.nested_progress_bar()
3755
cleanups.append(pb.finished)
3757
cleanups.append(tree.unlock)
3758
if location is not None:
3760
mergeable = bundle.read_mergeable_from_url(location,
3761
possible_transports=possible_transports)
3762
except errors.NotABundle:
3766
raise errors.BzrCommandError('Cannot use --uncommitted'
3767
' with bundles or merge directives.')
3769
if revision is not None:
3770
raise errors.BzrCommandError(
3771
'Cannot use -r with merge directives or bundles')
3772
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3775
if merger is None and uncommitted:
3776
if revision is not None and len(revision) > 0:
3777
raise errors.BzrCommandError('Cannot use --uncommitted and'
3778
' --revision at the same time.')
3779
merger = self.get_merger_from_uncommitted(tree, location, pb,
3781
allow_pending = False
3784
merger, allow_pending = self._get_merger_from_branch(tree,
3785
location, revision, remember, possible_transports, pb)
3787
merger.merge_type = merge_type
3788
merger.reprocess = reprocess
3789
merger.show_base = show_base
3790
self.sanity_check_merger(merger)
3791
if (merger.base_rev_id == merger.other_rev_id and
3792
merger.other_rev_id is not None):
3793
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)
3796
if merger.interesting_files is not None:
3797
raise errors.BzrCommandError('Cannot pull individual files')
3798
if (merger.base_rev_id == tree.last_revision()):
3799
result = tree.pull(merger.other_branch, False,
3800
merger.other_rev_id)
3801
result.report(self.outf)
3803
if merger.this_basis is None:
3804
raise errors.BzrCommandError(
3805
"This branch has no commits."
3806
" (perhaps you would prefer 'bzr pull')")
3808
return self._do_preview(merger, cleanups)
3810
return self._do_interactive(merger, cleanups)
3812
return self._do_merge(merger, change_reporter, allow_pending,
3815
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,
3818
def _get_preview(self, merger, cleanups):
3794
def _get_preview(self, merger):
3819
3795
tree_merger = merger.make_merger()
3820
3796
tt = tree_merger.make_preview_transform()
3821
cleanups.append(tt.finalize)
3797
self.add_cleanup(tt.finalize)
3822
3798
result_tree = tt.get_preview_tree()
3823
3799
return result_tree
3825
def _do_preview(self, merger, cleanups):
3801
def _do_preview(self, merger):
3826
3802
from bzrlib.diff import show_diff_trees
3827
result_tree = self._get_preview(merger, cleanups)
3803
result_tree = self._get_preview(merger)
3828
3804
show_diff_trees(merger.this_tree, result_tree, self.outf,
3829
3805
old_label='', new_label='')
4022
3996
merge_type = _mod_merge.Merge3Merger
4023
3997
tree, file_list = tree_files(file_list)
4024
3998
tree.lock_write()
4026
parents = tree.get_parent_ids()
4027
if len(parents) != 2:
4028
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4029
" merges. Not cherrypicking or"
4031
repository = tree.branch.repository
4032
interesting_ids = None
4034
conflicts = tree.conflicts()
4035
if file_list is not None:
4036
interesting_ids = set()
4037
for filename in file_list:
4038
file_id = tree.path2id(filename)
4040
raise errors.NotVersionedError(filename)
4041
interesting_ids.add(file_id)
4042
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":
4045
for name, ie in tree.inventory.iter_entries(file_id):
4046
interesting_ids.add(ie.file_id)
4047
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4049
# Remerge only supports resolving contents conflicts
4050
allowed_conflicts = ('text conflict', 'contents conflict')
4051
restore_files = [c.path for c in conflicts
4052
if c.typestring in allowed_conflicts]
4053
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4054
tree.set_conflicts(ConflictList(new_conflicts))
4055
if file_list is not None:
4056
restore_files = file_list
4057
for filename in restore_files:
4059
restore(tree.abspath(filename))
4060
except errors.NotConflicted:
4062
# Disable pending merges, because the file texts we are remerging
4063
# have not had those merges performed. If we use the wrong parents
4064
# list, we imply that the working tree text has seen and rejected
4065
# all the changes from the other tree, when in fact those changes
4066
# have not yet been seen.
4067
pb = ui.ui_factory.nested_progress_bar()
4068
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:
4070
merger = _mod_merge.Merger.from_revision_ids(pb,
4072
merger.interesting_ids = interesting_ids
4073
merger.merge_type = merge_type
4074
merger.show_base = show_base
4075
merger.reprocess = reprocess
4076
conflicts = merger.do_merge()
4078
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)
4082
4054
if conflicts > 0:
4306
4276
if remote_branch.base == local_branch.base:
4307
4277
remote_branch = local_branch
4279
local_branch.lock_read()
4280
self.add_cleanup(local_branch.unlock)
4309
4281
local_revid_range = _revision_range_to_revid_range(
4310
4282
_get_revision_range(my_revision, local_branch,
4285
remote_branch.lock_read()
4286
self.add_cleanup(remote_branch.unlock)
4313
4287
remote_revid_range = _revision_range_to_revid_range(
4314
4288
_get_revision_range(revision,
4315
4289
remote_branch, self.name()))
4317
local_branch.lock_read()
4319
remote_branch.lock_read()
4321
local_extra, remote_extra = find_unmerged(
4322
local_branch, remote_branch, restrict,
4323
backward=not reverse,
4324
include_merges=include_merges,
4325
local_revid_range=local_revid_range,
4326
remote_revid_range=remote_revid_range)
4328
if log_format is None:
4329
registry = log.log_formatter_registry
4330
log_format = registry.get_default(local_branch)
4331
lf = log_format(to_file=self.outf,
4333
show_timezone='original')
4336
if local_extra and not theirs_only:
4337
message("You have %d extra revision(s):\n" %
4339
for revision in iter_log_revisions(local_extra,
4340
local_branch.repository,
4342
lf.log_revision(revision)
4343
printed_local = True
4346
printed_local = False
4348
if remote_extra and not mine_only:
4349
if printed_local is True:
4351
message("You are missing %d revision(s):\n" %
4353
for revision in iter_log_revisions(remote_extra,
4354
remote_branch.repository,
4356
lf.log_revision(revision)
4359
if mine_only and not local_extra:
4360
# We checked local, and found nothing extra
4361
message('This branch is up to date.\n')
4362
elif theirs_only and not remote_extra:
4363
# We checked remote, and found nothing extra
4364
message('Other branch is up to date.\n')
4365
elif not (mine_only or theirs_only or local_extra or
4367
# We checked both branches, and neither one had extra
4369
message("Branches are up to date.\n")
4371
remote_branch.unlock()
4373
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")
4374
4341
if not status_code and parent is None and other_branch is not None:
4375
4342
local_branch.lock_write()
4377
# handle race conditions - a parent might be set while we run.
4378
if local_branch.get_parent() is None:
4379
local_branch.set_parent(remote_branch.base)
4381
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)
4382
4347
return status_code
4506
4469
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4507
4470
if wt is not None:
4472
self.add_cleanup(wt.unlock)
4510
4474
branch.lock_read()
4512
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4514
file_id = wt.path2id(relpath)
4516
file_id = tree.path2id(relpath)
4518
raise errors.NotVersionedError(filename)
4519
file_version = tree.inventory[file_id].revision
4520
if wt is not None and revision is None:
4521
# If there is a tree and we're not annotating historical
4522
# versions, annotate the working tree's content.
4523
annotate_file_tree(wt, file_id, self.outf, long, all,
4526
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,
4535
4496
class cmd_re_sign(Command):
5257
5211
branch, relpath = Branch.open_containing(directory)
5258
5212
branch.lock_write()
5261
branch.tags.delete_tag(tag_name)
5262
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)
5265
if len(revision) != 1:
5266
raise errors.BzrCommandError(
5267
"Tags can only be placed on a single revision, "
5269
revision_id = revision[0].as_revision_id(branch)
5271
revision_id = branch.last_revision()
5272
if (not force) and branch.tags.has_tag(tag_name):
5273
raise errors.TagAlreadyExists(tag_name)
5274
branch.tags.set_tag(tag_name, revision_id)
5275
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)
5280
5232
class cmd_tags(Command):
5315
5267
branch.lock_read()
5318
graph = branch.repository.get_graph()
5319
rev1, rev2 = _get_revision_range(revision, branch, self.name())
5320
revid1, revid2 = rev1.rev_id, rev2.rev_id
5321
# only show revisions between revid1 and revid2 (inclusive)
5322
tags = [(tag, revid) for tag, revid in tags if
5323
graph.is_between(revid, revid1, revid2)]
5326
elif sort == 'time':
5328
for tag, revid in tags:
5330
revobj = branch.repository.get_revision(revid)
5331
except errors.NoSuchRevision:
5332
timestamp = sys.maxint # place them at the end
5334
timestamp = revobj.timestamp
5335
timestamps[revid] = timestamp
5336
tags.sort(key=lambda x: timestamps[x[1]])
5338
# [ (tag, revid), ... ] -> [ (tag, dotted_revno), ... ]
5339
for index, (tag, revid) in enumerate(tags):
5341
revno = branch.revision_id_to_dotted_revno(revid)
5342
if isinstance(revno, tuple):
5343
revno = '.'.join(map(str, revno))
5344
except errors.NoSuchRevision:
5345
# Bad tag data/merges can lead to tagged revisions
5346
# which are not in this branch. Fail gracefully ...
5348
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)
5351
5302
for tag, revspec in tags:
5352
5303
self.outf.write('%-20s %s\n' % (tag, revspec))