534
Option('tree', help='Show revno of working tree'),
538
def run(self, revision=None, directory=u'.', tree=False,
539
revision_info_list=[]):
500
def run(self, revision=None, directory=u'.', revision_info_list=[]):
542
wt = WorkingTree.open_containing(directory)[0]
545
self.add_cleanup(wt.unlock)
546
except (errors.NoWorkingTree, errors.NotLocalUrl):
548
b = Branch.open_containing(directory)[0]
550
self.add_cleanup(b.unlock)
552
503
if revision is not None:
553
revision_ids.extend(rev.as_revision_id(b) for rev in revision)
504
revs.extend(revision)
554
505
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:
506
for rev in revision_info_list:
507
revs.append(RevisionSpec.from_string(rev))
509
b = Branch.open_containing(directory)[0]
512
revs.append(RevisionSpec.from_string('-1'))
515
revision_id = rev.as_revision_id(b)
571
dotted_revno = b.revision_id_to_dotted_revno(revision_id)
572
revno = '.'.join(str(i) for i in dotted_revno)
517
revno = '%4d' % (b.revision_id_to_revno(revision_id))
573
518
except errors.NoSuchRevision:
575
maxlen = max(maxlen, len(revno))
576
revinfos.append([revno, revision_id])
580
self.outf.write('%*s %s\n' % (maxlen, ri[0], ri[1]))
519
dotted_map = b.get_revision_id_to_revno_map()
520
revno = '.'.join(str(i) for i in dotted_map[revision_id])
521
print '%s %s' % (revno, revision_id)
583
524
class cmd_add(Command):
727
675
revision = _get_one_revision('inventory', revision)
728
676
work_tree, file_list = tree_files(file_list)
729
677
work_tree.lock_read()
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()
679
if revision is not None:
680
tree = revision.as_tree(work_tree.branch)
682
extra_trees = [work_tree]
688
if file_list is not None:
689
file_ids = tree.paths2ids(file_list, trees=extra_trees,
690
require_versioned=True)
691
# find_ids_across_trees may include some paths that don't
693
entries = sorted((tree.id2path(file_id), tree.inventory[file_id])
694
for file_id in file_ids if file_id in tree)
696
entries = tree.inventory.entries()
699
if tree is not work_tree:
752
702
for path, entry in entries:
753
703
if kind and kind != entry.kind:
892
845
dest = osutils.pathjoin(dest_parent, dest_tail)
893
846
mutter("attempting to move %s => %s", src, dest)
894
847
tree.rename_one(src, dest, after=after)
896
self.outf.write("%s => %s\n" % (src, dest))
848
self.outf.write("%s => %s\n" % (src, dest))
899
851
class cmd_pull(Command):
900
852
"""Turn this branch into a mirror of another branch.
902
By default, this command only works on branches that have not diverged.
903
Branches are considered diverged if the destination branch's most recent
904
commit is one that has not been merged (directly or indirectly) into the
854
This command only works on branches that have not diverged. Branches are
855
considered diverged if the destination branch's most recent commit is one
856
that has not been merged (directly or indirectly) into the parent.
907
858
If branches have diverged, you can use 'bzr merge' to integrate the changes
908
859
from one into the other. Once one branch has merged, the other should
909
860
be able to pull it again.
911
If you want to replace your local changes and just want your branch to
912
match the remote one, use pull --overwrite. This will work even if the two
913
branches have diverged.
862
If you want to forget your local changes and just update your branch to
863
match the remote one, use pull --overwrite.
915
865
If there is no default location set, the first pull will set it. After
916
866
that, you can omit the location to use the default. To change the
995
945
if branch_to.get_parent() is None or remember:
996
946
branch_to.set_parent(branch_from.base)
998
if branch_from is not branch_to:
999
branch_from.lock_read()
1000
self.add_cleanup(branch_from.unlock)
1001
948
if revision is not None:
1002
949
revision_id = revision.as_revision_id(branch_from)
1004
951
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)
953
if tree_to is not None:
954
view_info = _get_view_info_for_change_reporter(tree_to)
955
change_reporter = delta._ChangeReporter(
956
unversioned_filter=tree_to.is_ignored, view_info=view_info)
957
result = tree_to.pull(branch_from, overwrite, revision_id,
959
possible_transports=possible_transports,
962
result = branch_to.pull(branch_from, overwrite, revision_id,
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,
965
result.report(self.outf)
966
if verbose and result.old_revid != result.new_revid:
967
log.show_branch_change(branch_to, self.outf, result.old_revno,
1025
973
class cmd_push(Command):
1082
1027
def run(self, location=None, remember=False, overwrite=False,
1083
1028
create_prefix=False, verbose=False, revision=None,
1084
1029
use_existing_dir=False, directory=None, stacked_on=None,
1085
stacked=False, strict=None):
1086
1031
from bzrlib.push import _show_push_branch
1033
# Get the source branch and revision_id
1088
1034
if directory is None:
1089
1035
directory = '.'
1090
# Get the source branch
1092
_unused) = bzrdir.BzrDir.open_containing_tree_or_branch(directory)
1094
strict = br_from.get_config().get_user_option_as_bool('push_strict')
1095
if strict is None: strict = True # default value
1096
# Get the tip's revision_id
1036
br_from = Branch.open_containing(directory)[0]
1097
1037
revision = _get_one_revision('push', revision)
1098
1038
if revision is not None:
1099
1039
revision_id = revision.in_history(br_from).rev_id
1101
1041
revision_id = None
1102
if strict and tree is not None and revision_id is None:
1103
if (tree.has_changes()):
1104
raise errors.UncommittedChanges(
1105
tree, more='Use --no-strict to force the push.')
1106
if tree.last_revision() != tree.branch.last_revision():
1107
# The tree has lost sync with its branch, there is little
1108
# chance that the user is aware of it but he can still force
1109
# the push with --no-strict
1110
raise errors.OutOfDateTree(
1111
tree, more='Use --no-strict to force the push.')
1113
1043
# Get the stacked_on branch, if any
1114
1044
if stacked_on is not None:
1166
1096
help='Hard-link working tree files where possible.'),
1167
1097
Option('no-tree',
1168
1098
help="Create a branch without a working-tree."),
1170
help="Switch the checkout in the current directory "
1171
"to the new branch."),
1172
1099
Option('stacked',
1173
1100
help='Create a stacked branch referring to the source branch. '
1174
1101
'The new branch will depend on the availability of the source '
1175
1102
'branch for all operations.'),
1176
1103
Option('standalone',
1177
1104
help='Do not use a shared repository, even if available.'),
1178
Option('use-existing-dir',
1179
help='By default branch will fail if the target'
1180
' directory exists, but does not already'
1181
' have a control directory. This flag will'
1182
' allow branch to proceed.'),
1184
help="Bind new branch to from location."),
1186
1106
aliases = ['get', 'clone']
1188
1108
def run(self, from_location, to_location=None, revision=None,
1189
hardlink=False, stacked=False, standalone=False, no_tree=False,
1190
use_existing_dir=False, switch=False, bind=False):
1191
from bzrlib import switch as _mod_switch
1109
hardlink=False, stacked=False, standalone=False, no_tree=False):
1192
1110
from bzrlib.tag import _merge_tags_if_possible
1193
1112
accelerator_tree, br_from = bzrdir.BzrDir.open_tree_or_branch(
1195
1114
revision = _get_one_revision('branch', revision)
1196
1115
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)
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)
1117
if revision is not None:
1118
revision_id = revision.as_revision_id(br_from)
1216
bzrdir.BzrDir.open_from_transport(to_transport)
1217
except errors.NotBranchError:
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'))
1120
# FIXME - wt.last_revision, fallback to branch, fall back to
1121
# None or perhaps NULL_REVISION to mean copy nothing
1123
revision_id = br_from.last_revision()
1124
if to_location is None:
1125
to_location = urlutils.derive_to_location(from_location)
1126
to_transport = transport.get_transport(to_location)
1128
to_transport.mkdir('.')
1129
except errors.FileExists:
1130
raise errors.BzrCommandError('Target directory "%s" already'
1131
' exists.' % to_location)
1132
except errors.NoSuchFile:
1133
raise errors.BzrCommandError('Parent of "%s" does not exist.'
1136
# preserve whatever source format we have.
1137
dir = br_from.bzrdir.sprout(to_transport.base, revision_id,
1138
possible_transports=[to_transport],
1139
accelerator_tree=accelerator_tree,
1140
hardlink=hardlink, stacked=stacked,
1141
force_new_repo=standalone,
1142
create_tree_if_local=not no_tree,
1143
source_branch=br_from)
1144
branch = dir.open_branch()
1145
except errors.NoSuchRevision:
1146
to_transport.delete_tree('.')
1147
msg = "The branch %s has no revision %s." % (from_location,
1149
raise errors.BzrCommandError(msg)
1150
_merge_tags_if_possible(br_from, branch)
1151
# If the source branch is stacked, the new branch may
1152
# be stacked whether we asked for that explicitly or not.
1153
# We therefore need a try/except here and not just 'if stacked:'
1155
note('Created new stacked branch referring to %s.' %
1156
branch.get_stacked_on_url())
1157
except (errors.NotStacked, errors.UnstackableBranchFormat,
1158
errors.UnstackableRepositoryFormat), e:
1159
note('Branched %d revision(s).' % branch.revno())
1262
1164
class cmd_checkout(Command):
1341
1243
def run(self, dir=u'.'):
1342
1244
tree = WorkingTree.open_containing(dir)[0]
1343
1245
tree.lock_read()
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))
1247
new_inv = tree.inventory
1248
old_tree = tree.basis_tree()
1249
old_tree.lock_read()
1251
old_inv = old_tree.inventory
1253
iterator = tree.iter_changes(old_tree, include_unchanged=True)
1254
for f, paths, c, v, p, n, k, e in iterator:
1255
if paths[0] == paths[1]:
1259
renames.append(paths)
1261
for old_name, new_name in renames:
1262
self.outf.write("%s => %s\n" % (old_name, new_name))
1363
1269
class cmd_update(Command):
1370
1276
If you want to discard your local changes, you can just do a
1371
1277
'bzr revert' instead of 'bzr commit' after the update.
1373
If the tree's branch is bound to a master branch, it will also update
1374
the branch from the master.
1377
1280
_see_also = ['pull', 'working-trees', 'status-flags']
1378
1281
takes_args = ['dir?']
1379
takes_options = ['revision']
1380
1282
aliases = ['up']
1382
def run(self, dir='.', revision=None):
1383
if revision is not None and len(revision) != 1:
1384
raise errors.BzrCommandError(
1385
"bzr update --revision takes exactly one revision")
1284
def run(self, dir='.'):
1386
1285
tree = WorkingTree.open_containing(dir)[0]
1387
branch = tree.branch
1388
1286
possible_transports = []
1389
master = branch.get_master_branch(
1287
master = tree.branch.get_master_branch(
1390
1288
possible_transports=possible_transports)
1391
1289
if master is not None:
1392
1290
tree.lock_write()
1393
branch_location = master.base
1395
1292
tree.lock_tree_write()
1396
branch_location = tree.branch.base
1397
self.add_cleanup(tree.unlock)
1398
# get rid of the final '/' and be ready for display
1399
branch_location = urlutils.unescape_for_display(branch_location[:-1],
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)
1294
existing_pending_merges = tree.get_parent_ids()[1:]
1295
last_rev = _mod_revision.ensure_null(tree.last_revision())
1296
if last_rev == _mod_revision.ensure_null(
1297
tree.branch.last_revision()):
1298
# may be up to date, check master too.
1299
if master is None or last_rev == _mod_revision.ensure_null(
1300
master.last_revision()):
1301
revno = tree.branch.revision_id_to_revno(last_rev)
1302
note("Tree is up to date at revision %d." % (revno,))
1304
view_info = _get_view_info_for_change_reporter(tree)
1423
1305
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'.")
1306
delta._ChangeReporter(unversioned_filter=tree.is_ignored,
1307
view_info=view_info), possible_transports=possible_transports)
1308
revno = tree.branch.revision_id_to_revno(
1309
_mod_revision.ensure_null(tree.last_revision()))
1310
note('Updated to revision %d.' % (revno,))
1311
if tree.get_parent_ids()[1:] != existing_pending_merges:
1312
note('Your local commits will now show as pending merges with '
1313
"'bzr status', and can be committed with 'bzr commit'.")
1447
1322
class cmd_info(Command):
1518
1393
file_list = [f for f in file_list]
1520
1395
tree.lock_write()
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')
1397
# Heuristics should probably all move into tree.remove_smart or
1400
added = tree.changes_from(tree.basis_tree(),
1401
specific_files=file_list).added
1402
file_list = sorted([f[0] for f in added], reverse=True)
1403
if len(file_list) == 0:
1404
raise errors.BzrCommandError('No matching files.')
1405
elif file_list is None:
1406
# missing files show up in iter_changes(basis) as
1407
# versioned-with-no-kind.
1409
for change in tree.iter_changes(tree.basis_tree()):
1410
# Find paths in the working tree that have no kind:
1411
if change[1][1] is not None and change[6][1] is None:
1412
missing.append(change[1][1])
1413
file_list = sorted(missing, reverse=True)
1414
file_deletion_strategy = 'keep'
1415
tree.remove(file_list, verbose=verbose, to_file=self.outf,
1416
keep_files=file_deletion_strategy=='keep',
1417
force=file_deletion_strategy=='force')
1545
1422
class cmd_file_id(Command):
2347
2211
diff_type = 'full'
2349
# Build the log formatter
2350
if log_format is None:
2351
log_format = log.log_formatter_registry.get_default(b)
2352
# Make a non-encoding output to include the diffs - bug 328007
2353
unencoded_output = ui.ui_factory.make_output_stream(encoding_type='exact')
2354
lf = log_format(show_ids=show_ids, to_file=self.outf,
2355
to_exact_file=unencoded_output,
2356
show_timezone=timezone,
2357
delta_format=get_verbosity_level(),
2359
show_advice=levels is None)
2361
# Choose the algorithm for doing the logging. It's annoying
2362
# having multiple code paths like this but necessary until
2363
# the underlying repository format is faster at generating
2364
# deltas or can provide everything we need from the indices.
2365
# The default algorithm - match-using-deltas - works for
2366
# multiple files and directories and is faster for small
2367
# amounts of history (200 revisions say). However, it's too
2368
# slow for logging a single file in a repository with deep
2369
# history, i.e. > 10K revisions. In the spirit of "do no
2370
# evil when adding features", we continue to use the
2371
# original algorithm - per-file-graph - for the "single
2372
# file that isn't a directory without showing a delta" case.
2373
partial_history = revision and b.repository._format.supports_chks
2374
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2375
or delta_type or partial_history)
2377
# Build the LogRequest and execute it
2378
if len(file_ids) == 0:
2380
rqst = make_log_request_dict(
2381
direction=direction, specific_fileids=file_ids,
2382
start_revision=rev1, end_revision=rev2, limit=limit,
2383
message_search=message, delta_type=delta_type,
2384
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2385
Logger(b, rqst).show(lf)
2215
# Build the log formatter
2216
if log_format is None:
2217
log_format = log.log_formatter_registry.get_default(b)
2218
lf = log_format(show_ids=show_ids, to_file=self.outf,
2219
show_timezone=timezone,
2220
delta_format=get_verbosity_level(),
2222
show_advice=levels is None)
2224
# Choose the algorithm for doing the logging. It's annoying
2225
# having multiple code paths like this but necessary until
2226
# the underlying repository format is faster at generating
2227
# deltas or can provide everything we need from the indices.
2228
# The default algorithm - match-using-deltas - works for
2229
# multiple files and directories and is faster for small
2230
# amounts of history (200 revisions say). However, it's too
2231
# slow for logging a single file in a repository with deep
2232
# history, i.e. > 10K revisions. In the spirit of "do no
2233
# evil when adding features", we continue to use the
2234
# original algorithm - per-file-graph - for the "single
2235
# file that isn't a directory without showing a delta" case.
2236
partial_history = revision and b.repository._format.supports_chks
2237
match_using_deltas = (len(file_ids) != 1 or filter_by_dir
2238
or delta_type or partial_history)
2240
# Build the LogRequest and execute it
2241
if len(file_ids) == 0:
2243
rqst = make_log_request_dict(
2244
direction=direction, specific_fileids=file_ids,
2245
start_revision=rev1, end_revision=rev2, limit=limit,
2246
message_search=message, delta_type=delta_type,
2247
diff_type=diff_type, _match_using_deltas=match_using_deltas)
2248
Logger(b, rqst).show(lf)
2388
2253
def _get_revision_range(revisionspec_list, branch, command_name):
2531
2390
note("Ignoring files outside view. View is %s" % view_str)
2533
2392
tree.lock_read()
2534
self.add_cleanup(tree.unlock)
2535
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False,
2536
from_dir=relpath, recursive=recursive):
2537
# Apply additional masking
2538
if not all and not selection[fc]:
2540
if kind is not None and fkind != kind:
2545
fullpath = osutils.pathjoin(relpath, fp)
2548
views.check_path_in_view(tree, fullpath)
2549
except errors.FileOutsideView:
2554
fp = osutils.pathjoin(prefix, fp)
2555
kindch = entry.kind_character()
2556
outstring = fp + kindch
2557
ui.ui_factory.clear_term()
2559
outstring = '%-8s %s' % (fc, outstring)
2560
if show_ids and fid is not None:
2561
outstring = "%-50s %s" % (outstring, fid)
2562
self.outf.write(outstring + '\n')
2564
self.outf.write(fp + '\0')
2567
self.outf.write(fid)
2568
self.outf.write('\0')
2576
self.outf.write('%-50s %s\n' % (outstring, my_id))
2578
self.outf.write(outstring + '\n')
2394
for fp, fc, fkind, fid, entry in tree.list_files(include_root=False):
2395
if fp.startswith(relpath):
2396
rp = fp[len(relpath):]
2397
fp = osutils.pathjoin(prefix, rp)
2398
if not recursive and '/' in rp:
2400
if not all and not selection[fc]:
2402
if kind is not None and fkind != kind:
2406
views.check_path_in_view(tree, fp)
2407
except errors.FileOutsideView:
2409
kindch = entry.kind_character()
2410
outstring = fp + kindch
2412
outstring = '%-8s %s' % (fc, outstring)
2413
if show_ids and fid is not None:
2414
outstring = "%-50s %s" % (outstring, fid)
2415
self.outf.write(outstring + '\n')
2417
self.outf.write(fp + '\0')
2420
self.outf.write(fid)
2421
self.outf.write('\0')
2429
self.outf.write('%-50s %s\n' % (outstring, my_id))
2431
self.outf.write(outstring + '\n')
2581
2436
class cmd_unknowns(Command):
3161
2958
The working tree and branch checks will only give output if a problem is
3162
2959
detected. The output fields of the repository check are:
3165
This is just the number of revisions checked. It doesn't
3169
This is just the number of versionedfiles checked. It
3170
doesn't indicate a problem.
3172
unreferenced ancestors
3173
Texts that are ancestors of other texts, but
3174
are not properly referenced by the revision ancestry. This is a
3175
subtle problem that Bazaar can work around.
3178
This is the total number of unique file contents
3179
seen in the checked revisions. It does not indicate a problem.
3182
This is the total number of repeated texts seen
3183
in the checked revisions. Texts can be repeated when their file
3184
entries are modified, but the file contents are not. It does not
2961
revisions: This is just the number of revisions checked. It doesn't
2963
versionedfiles: This is just the number of versionedfiles checked. It
2964
doesn't indicate a problem.
2965
unreferenced ancestors: Texts that are ancestors of other texts, but
2966
are not properly referenced by the revision ancestry. This is a
2967
subtle problem that Bazaar can work around.
2968
unique file texts: This is the total number of unique file contents
2969
seen in the checked revisions. It does not indicate a problem.
2970
repeated file texts: This is the total number of repeated texts seen
2971
in the checked revisions. Texts can be repeated when their file
2972
entries are modified, but the file contents are not. It does not
3187
2975
If no restrictions are specified, all Bazaar data that is found at the given
3188
2976
location will be checked.
3547
3330
verbose = not is_quiet()
3548
3331
# TODO: should possibly lock the history file...
3549
3332
benchfile = open(".perf_history", "at", buffering=1)
3550
self.add_cleanup(benchfile.close)
3552
3334
test_suite_factory = None
3553
3335
benchfile = None
3554
selftest_kwargs = {"verbose": verbose,
3556
"stop_on_failure": one,
3557
"transport": transport,
3558
"test_suite_factory": test_suite_factory,
3559
"lsprof_timed": lsprof_timed,
3560
"lsprof_tests": lsprof_tests,
3561
"bench_history": benchfile,
3562
"matching_tests_first": first,
3563
"list_only": list_only,
3564
"random_seed": randomize,
3565
"exclude_pattern": exclude,
3567
"load_list": load_list,
3568
"debug_flags": debugflag,
3569
"starting_with": starting_with
3571
selftest_kwargs.update(self.additional_selftest_args)
3572
result = selftest(**selftest_kwargs)
3337
selftest_kwargs = {"verbose": verbose,
3339
"stop_on_failure": one,
3340
"transport": transport,
3341
"test_suite_factory": test_suite_factory,
3342
"lsprof_timed": lsprof_timed,
3343
"bench_history": benchfile,
3344
"matching_tests_first": first,
3345
"list_only": list_only,
3346
"random_seed": randomize,
3347
"exclude_pattern": exclude,
3349
"load_list": load_list,
3350
"debug_flags": debugflag,
3351
"starting_with": starting_with
3353
selftest_kwargs.update(self.additional_selftest_args)
3354
result = selftest(**selftest_kwargs)
3356
if benchfile is not None:
3573
3358
return int(not result)
3745
3515
verified = 'inapplicable'
3746
3516
tree = WorkingTree.open_containing(directory)[0]
3518
# die as quickly as possible if there are uncommitted changes
3749
3520
basis_tree = tree.revision_tree(tree.last_revision())
3750
3521
except errors.NoSuchRevision:
3751
3522
basis_tree = tree.basis_tree()
3753
# die as quickly as possible if there are uncommitted changes
3755
if tree.has_changes():
3524
changes = tree.changes_from(basis_tree)
3525
if changes.has_changed():
3756
3526
raise errors.UncommittedChanges(tree)
3758
3528
view_info = _get_view_info_for_change_reporter(tree)
3759
3529
change_reporter = delta._ChangeReporter(
3760
3530
unversioned_filter=tree.is_ignored, view_info=view_info)
3761
pb = ui.ui_factory.nested_progress_bar()
3762
self.add_cleanup(pb.finished)
3764
self.add_cleanup(tree.unlock)
3765
if location is not None:
3767
mergeable = bundle.read_mergeable_from_url(location,
3768
possible_transports=possible_transports)
3769
except errors.NotABundle:
3533
pb = ui.ui_factory.nested_progress_bar()
3534
cleanups.append(pb.finished)
3536
cleanups.append(tree.unlock)
3537
if location is not None:
3539
mergeable = bundle.read_mergeable_from_url(location,
3540
possible_transports=possible_transports)
3541
except errors.NotABundle:
3545
raise errors.BzrCommandError('Cannot use --uncommitted'
3546
' with bundles or merge directives.')
3548
if revision is not None:
3549
raise errors.BzrCommandError(
3550
'Cannot use -r with merge directives or bundles')
3551
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3554
if merger is None and uncommitted:
3555
if revision is not None and len(revision) > 0:
3556
raise errors.BzrCommandError('Cannot use --uncommitted and'
3557
' --revision at the same time.')
3558
location = self._select_branch_location(tree, location)[0]
3559
other_tree, other_path = WorkingTree.open_containing(location)
3560
merger = _mod_merge.Merger.from_uncommitted(tree, other_tree,
3562
allow_pending = False
3563
if other_path != '':
3564
merger.interesting_files = [other_path]
3567
merger, allow_pending = self._get_merger_from_branch(tree,
3568
location, revision, remember, possible_transports, pb)
3570
merger.merge_type = merge_type
3571
merger.reprocess = reprocess
3572
merger.show_base = show_base
3573
self.sanity_check_merger(merger)
3574
if (merger.base_rev_id == merger.other_rev_id and
3575
merger.other_rev_id is not None):
3576
note('Nothing to do.')
3579
if merger.interesting_files is not None:
3580
raise errors.BzrCommandError('Cannot pull individual files')
3581
if (merger.base_rev_id == tree.last_revision()):
3582
result = tree.pull(merger.other_branch, False,
3583
merger.other_rev_id)
3584
result.report(self.outf)
3586
merger.check_basis(False)
3588
return self._do_preview(merger)
3773
raise errors.BzrCommandError('Cannot use --uncommitted'
3774
' with bundles or merge directives.')
3776
if revision is not None:
3777
raise errors.BzrCommandError(
3778
'Cannot use -r with merge directives or bundles')
3779
merger, verified = _mod_merge.Merger.from_mergeable(tree,
3782
if merger is None and uncommitted:
3783
if revision is not None and len(revision) > 0:
3784
raise errors.BzrCommandError('Cannot use --uncommitted and'
3785
' --revision at the same time.')
3786
merger = self.get_merger_from_uncommitted(tree, location, pb)
3787
allow_pending = False
3790
merger, allow_pending = self._get_merger_from_branch(tree,
3791
location, revision, remember, possible_transports, pb)
3793
merger.merge_type = merge_type
3794
merger.reprocess = reprocess
3795
merger.show_base = show_base
3796
self.sanity_check_merger(merger)
3797
if (merger.base_rev_id == merger.other_rev_id and
3798
merger.other_rev_id is not None):
3799
note('Nothing to do.')
3802
if merger.interesting_files is not None:
3803
raise errors.BzrCommandError('Cannot pull individual files')
3804
if (merger.base_rev_id == tree.last_revision()):
3805
result = tree.pull(merger.other_branch, False,
3806
merger.other_rev_id)
3807
result.report(self.outf)
3809
if merger.this_basis is None:
3810
raise errors.BzrCommandError(
3811
"This branch has no commits."
3812
" (perhaps you would prefer 'bzr pull')")
3814
return self._do_preview(merger)
3816
return self._do_interactive(merger)
3818
return self._do_merge(merger, change_reporter, allow_pending,
3821
def _get_preview(self, merger):
3590
return self._do_merge(merger, change_reporter, allow_pending,
3593
for cleanup in reversed(cleanups):
3596
def _do_preview(self, merger):
3597
from bzrlib.diff import show_diff_trees
3822
3598
tree_merger = merger.make_merger()
3823
3599
tt = tree_merger.make_preview_transform()
3824
self.add_cleanup(tt.finalize)
3825
result_tree = tt.get_preview_tree()
3828
def _do_preview(self, merger):
3829
from bzrlib.diff import show_diff_trees
3830
result_tree = self._get_preview(merger)
3831
show_diff_trees(merger.this_tree, result_tree, self.outf,
3832
old_label='', new_label='')
3601
result_tree = tt.get_preview_tree()
3602
show_diff_trees(merger.this_tree, result_tree, self.outf,
3603
old_label='', new_label='')
3834
3607
def _do_merge(self, merger, change_reporter, allow_pending, verified):
3835
3608
merger.change_reporter = change_reporter
4023
3764
merge_type = _mod_merge.Merge3Merger
4024
3765
tree, file_list = tree_files(file_list)
4025
3766
tree.lock_write()
4026
self.add_cleanup(tree.unlock)
4027
parents = tree.get_parent_ids()
4028
if len(parents) != 2:
4029
raise errors.BzrCommandError("Sorry, remerge only works after normal"
4030
" merges. Not cherrypicking or"
4032
repository = tree.branch.repository
4033
interesting_ids = None
4035
conflicts = tree.conflicts()
4036
if file_list is not None:
4037
interesting_ids = set()
4038
for filename in file_list:
4039
file_id = tree.path2id(filename)
4041
raise errors.NotVersionedError(filename)
4042
interesting_ids.add(file_id)
4043
if tree.kind(file_id) != "directory":
3768
parents = tree.get_parent_ids()
3769
if len(parents) != 2:
3770
raise errors.BzrCommandError("Sorry, remerge only works after normal"
3771
" merges. Not cherrypicking or"
3773
repository = tree.branch.repository
3774
interesting_ids = None
3776
conflicts = tree.conflicts()
3777
if file_list is not None:
3778
interesting_ids = set()
3779
for filename in file_list:
3780
file_id = tree.path2id(filename)
3782
raise errors.NotVersionedError(filename)
3783
interesting_ids.add(file_id)
3784
if tree.kind(file_id) != "directory":
4046
for name, ie in tree.inventory.iter_entries(file_id):
4047
interesting_ids.add(ie.file_id)
4048
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
4050
# Remerge only supports resolving contents conflicts
4051
allowed_conflicts = ('text conflict', 'contents conflict')
4052
restore_files = [c.path for c in conflicts
4053
if c.typestring in allowed_conflicts]
4054
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
4055
tree.set_conflicts(ConflictList(new_conflicts))
4056
if file_list is not None:
4057
restore_files = file_list
4058
for filename in restore_files:
3787
for name, ie in tree.inventory.iter_entries(file_id):
3788
interesting_ids.add(ie.file_id)
3789
new_conflicts = conflicts.select_conflicts(tree, file_list)[0]
3791
# Remerge only supports resolving contents conflicts
3792
allowed_conflicts = ('text conflict', 'contents conflict')
3793
restore_files = [c.path for c in conflicts
3794
if c.typestring in allowed_conflicts]
3795
_mod_merge.transform_tree(tree, tree.basis_tree(), interesting_ids)
3796
tree.set_conflicts(ConflictList(new_conflicts))
3797
if file_list is not None:
3798
restore_files = file_list
3799
for filename in restore_files:
3801
restore(tree.abspath(filename))
3802
except errors.NotConflicted:
3804
# Disable pending merges, because the file texts we are remerging
3805
# have not had those merges performed. If we use the wrong parents
3806
# list, we imply that the working tree text has seen and rejected
3807
# all the changes from the other tree, when in fact those changes
3808
# have not yet been seen.
3809
pb = ui.ui_factory.nested_progress_bar()
3810
tree.set_parent_ids(parents[:1])
4060
restore(tree.abspath(filename))
4061
except errors.NotConflicted:
4063
# Disable pending merges, because the file texts we are remerging
4064
# have not had those merges performed. If we use the wrong parents
4065
# list, we imply that the working tree text has seen and rejected
4066
# all the changes from the other tree, when in fact those changes
4067
# have not yet been seen.
4068
pb = ui.ui_factory.nested_progress_bar()
4069
tree.set_parent_ids(parents[:1])
4071
merger = _mod_merge.Merger.from_revision_ids(pb,
4073
merger.interesting_ids = interesting_ids
4074
merger.merge_type = merge_type
4075
merger.show_base = show_base
4076
merger.reprocess = reprocess
4077
conflicts = merger.do_merge()
3812
merger = _mod_merge.Merger.from_revision_ids(pb,
3814
merger.interesting_ids = interesting_ids
3815
merger.merge_type = merge_type
3816
merger.show_base = show_base
3817
merger.reprocess = reprocess
3818
conflicts = merger.do_merge()
3820
tree.set_parent_ids(parents)
4079
tree.set_parent_ids(parents)
4081
3824
if conflicts > 0:
4105
3848
name. If you name a directory, all the contents of that directory will be
4108
If you have newly added files since the target revision, they will be
4109
removed. If the files to be removed have been changed, backups will be
4110
created as above. Directories containing unknown files will not be
3851
Any files that have been newly added since that revision will be deleted,
3852
with a backup kept if appropriate. Directories containing unknown files
3853
will not be deleted.
4113
The working tree contains a list of revisions that have been merged but
4114
not yet committed. These revisions will be included as additional parents
4115
of the next commit. Normally, using revert clears that list as well as
4116
reverting the files. If any files are specified, revert leaves the list
4117
of uncommitted merges alone and reverts only the files. Use ``bzr revert
4118
.`` in the tree root to revert all files but keep the recorded merges,
4119
and ``bzr revert --forget-merges`` to clear the pending merge list without
3855
The working tree contains a list of pending merged revisions, which will
3856
be included as parents in the next commit. Normally, revert clears that
3857
list as well as reverting the files. If any files are specified, revert
3858
leaves the pending merge list alone and reverts only the files. Use "bzr
3859
revert ." in the tree root to revert all files but keep the merge record,
3860
and "bzr revert --forget-merges" to clear the pending merge list without
4120
3861
reverting any files.
4122
Using "bzr revert --forget-merges", it is possible to apply all of the
4123
changes from a branch in a single revision. To do this, perform the merge
4124
as desired. Then doing revert with the "--forget-merges" option will keep
4125
the content of the tree as it was, but it will clear the list of pending
4126
merges. The next commit will then contain all of the changes that are
4127
present in the other branch, but without any other parent revisions.
4128
Because this technique forgets where these changes originated, it may
4129
cause additional conflicts on later merges involving the same source and
4133
3864
_see_also = ['cat', 'export']
4304
4033
if remote_branch.base == local_branch.base:
4305
4034
remote_branch = local_branch
4307
local_branch.lock_read()
4308
self.add_cleanup(local_branch.unlock)
4309
4036
local_revid_range = _revision_range_to_revid_range(
4310
4037
_get_revision_range(my_revision, local_branch,
4313
remote_branch.lock_read()
4314
self.add_cleanup(remote_branch.unlock)
4315
4040
remote_revid_range = _revision_range_to_revid_range(
4316
4041
_get_revision_range(revision,
4317
4042
remote_branch, self.name()))
4319
local_extra, remote_extra = find_unmerged(
4320
local_branch, remote_branch, restrict,
4321
backward=not reverse,
4322
include_merges=include_merges,
4323
local_revid_range=local_revid_range,
4324
remote_revid_range=remote_revid_range)
4326
if log_format is None:
4327
registry = log.log_formatter_registry
4328
log_format = registry.get_default(local_branch)
4329
lf = log_format(to_file=self.outf,
4331
show_timezone='original')
4334
if local_extra and not theirs_only:
4335
message("You have %d extra revision(s):\n" %
4337
for revision in iter_log_revisions(local_extra,
4338
local_branch.repository,
4340
lf.log_revision(revision)
4341
printed_local = True
4344
printed_local = False
4346
if remote_extra and not mine_only:
4347
if printed_local is True:
4349
message("You are missing %d revision(s):\n" %
4351
for revision in iter_log_revisions(remote_extra,
4352
remote_branch.repository,
4354
lf.log_revision(revision)
4357
if mine_only and not local_extra:
4358
# We checked local, and found nothing extra
4359
message('This branch is up to date.\n')
4360
elif theirs_only and not remote_extra:
4361
# We checked remote, and found nothing extra
4362
message('Other branch is up to date.\n')
4363
elif not (mine_only or theirs_only or local_extra or
4365
# We checked both branches, and neither one had extra
4367
message("Branches are up to date.\n")
4044
local_branch.lock_read()
4046
remote_branch.lock_read()
4048
local_extra, remote_extra = find_unmerged(
4049
local_branch, remote_branch, restrict,
4050
backward=not reverse,
4051
include_merges=include_merges,
4052
local_revid_range=local_revid_range,
4053
remote_revid_range=remote_revid_range)
4055
if log_format is None:
4056
registry = log.log_formatter_registry
4057
log_format = registry.get_default(local_branch)
4058
lf = log_format(to_file=self.outf,
4060
show_timezone='original')
4063
if local_extra and not theirs_only:
4064
message("You have %d extra revision(s):\n" %
4066
for revision in iter_log_revisions(local_extra,
4067
local_branch.repository,
4069
lf.log_revision(revision)
4070
printed_local = True
4073
printed_local = False
4075
if remote_extra and not mine_only:
4076
if printed_local is True:
4078
message("You are missing %d revision(s):\n" %
4080
for revision in iter_log_revisions(remote_extra,
4081
remote_branch.repository,
4083
lf.log_revision(revision)
4086
if mine_only and not local_extra:
4087
# We checked local, and found nothing extra
4088
message('This branch is up to date.\n')
4089
elif theirs_only and not remote_extra:
4090
# We checked remote, and found nothing extra
4091
message('Other branch is up to date.\n')
4092
elif not (mine_only or theirs_only or local_extra or
4094
# We checked both branches, and neither one had extra
4096
message("Branches are up to date.\n")
4098
remote_branch.unlock()
4100
local_branch.unlock()
4369
4101
if not status_code and parent is None and other_branch is not None:
4370
4102
local_branch.lock_write()
4371
self.add_cleanup(local_branch.unlock)
4372
# handle race conditions - a parent might be set while we run.
4373
if local_branch.get_parent() is None:
4374
local_branch.set_parent(remote_branch.base)
4104
# handle race conditions - a parent might be set while we run.
4105
if local_branch.get_parent() is None:
4106
local_branch.set_parent(remote_branch.base)
4108
local_branch.unlock()
4375
4109
return status_code
4497
4233
bzrdir.BzrDir.open_containing_tree_or_branch(filename)
4498
4234
if wt is not None:
4500
self.add_cleanup(wt.unlock)
4502
4237
branch.lock_read()
4503
self.add_cleanup(branch.unlock)
4504
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4506
self.add_cleanup(tree.unlock)
4508
file_id = wt.path2id(relpath)
4510
file_id = tree.path2id(relpath)
4512
raise errors.NotVersionedError(filename)
4513
file_version = tree.inventory[file_id].revision
4514
if wt is not None and revision is None:
4515
# If there is a tree and we're not annotating historical
4516
# versions, annotate the working tree's content.
4517
annotate_file_tree(wt, file_id, self.outf, long, all,
4520
annotate_file(branch, file_version, file_id, long, all, self.outf,
4239
tree = _get_one_revision_tree('annotate', revision, branch=branch)
4241
file_id = wt.path2id(relpath)
4243
file_id = tree.path2id(relpath)
4245
raise errors.NotVersionedError(filename)
4246
file_version = tree.inventory[file_id].revision
4247
if wt is not None and revision is None:
4248
# If there is a tree and we're not annotating historical
4249
# versions, annotate the working tree's content.
4250
annotate_file_tree(wt, file_id, self.outf, long, all,
4253
annotate_file(branch, file_version, file_id, long, all, self.outf,
4524
4262
class cmd_re_sign(Command):
4813
4552
Option('allow-writes',
4814
4553
help='By default the server is a readonly server. Supplying '
4815
4554
'--allow-writes enables write access to the contents of '
4816
'the served directory and below. Note that ``bzr serve`` '
4817
'does not perform authentication, so unless some form of '
4818
'external authentication is arranged supplying this '
4819
'option leads to global uncontrolled write access to your '
4555
'the served directory and below.'
4559
def run_smart_server(self, smart_server):
4560
"""Run 'smart_server' forever, with no UI output at all."""
4561
# For the duration of this server, no UI output is permitted. note
4562
# that this may cause problems with blackbox tests. This should be
4563
# changed with care though, as we dont want to use bandwidth sending
4564
# progress over stderr to smart server clients!
4565
from bzrlib import lockdir
4566
old_factory = ui.ui_factory
4567
old_lockdir_timeout = lockdir._DEFAULT_TIMEOUT_SECONDS
4569
ui.ui_factory = ui.SilentUIFactory()
4570
lockdir._DEFAULT_TIMEOUT_SECONDS = 0
4571
smart_server.serve()
4573
ui.ui_factory = old_factory
4574
lockdir._DEFAULT_TIMEOUT_SECONDS = old_lockdir_timeout
4824
4576
def get_host_and_port(self, port):
4825
4577
"""Return the host and port to run the smart server on.
4827
If 'port' is None, None will be returned for the host and port.
4579
If 'port' is None, the default host (`medium.BZR_DEFAULT_INTERFACE`)
4580
and port (`medium.BZR_DEFAULT_PORT`) will be used.
4829
4582
If 'port' has a colon in it, the string before the colon will be
4830
4583
interpreted as the host.
4833
4586
:return: A tuple of (host, port), where 'host' is a host name or IP,
4834
4587
and port is an integer TCP/IP port.
4837
if port is not None:
4589
from bzrlib.smart import medium
4590
host = medium.BZR_DEFAULT_INTERFACE
4592
port = medium.BZR_DEFAULT_PORT
4838
4594
if ':' in port:
4839
4595
host, port = port.split(':')
4840
4596
port = int(port)
4841
4597
return host, port
4843
def run(self, port=None, inet=False, directory=None, allow_writes=False,
4845
from bzrlib.transport import get_transport, transport_server_registry
4599
def get_smart_server(self, transport, inet, port):
4600
"""Construct a smart server.
4602
:param transport: The base transport from which branches will be
4604
:param inet: If True, serve over stdin and stdout. Used for running
4606
:param port: The port to listen on. By default, it's `
4607
medium.BZR_DEFAULT_PORT`. See `get_host_and_port` for more
4609
:return: A smart server.
4611
from bzrlib.smart import medium, server
4613
smart_server = medium.SmartServerPipeStreamMedium(
4614
sys.stdin, sys.stdout, transport)
4616
host, port = self.get_host_and_port(port)
4617
smart_server = server.SmartTCPServer(
4618
transport, host=host, port=port)
4619
note('listening on port: %s' % smart_server.port)
4622
def run(self, port=None, inet=False, directory=None, allow_writes=False):
4623
from bzrlib.transport import get_transport
4624
from bzrlib.transport.chroot import ChrootServer
4846
4625
if directory is None:
4847
4626
directory = os.getcwd()
4848
if protocol is None:
4849
protocol = transport_server_registry.get()
4850
host, port = self.get_host_and_port(port)
4851
4627
url = urlutils.local_path_to_url(directory)
4852
4628
if not allow_writes:
4853
4629
url = 'readonly+' + url
4854
transport = get_transport(url)
4855
protocol(transport, host, port, inet)
4630
chroot_server = ChrootServer(get_transport(url))
4631
chroot_server.setUp()
4632
t = get_transport(chroot_server.get_url())
4633
smart_server = self.get_smart_server(t, inet, port)
4634
self.run_smart_server(smart_server)
4858
4637
class cmd_join(Command):
5039
4818
directly from the merge directive, without retrieving data from a
5042
`bzr send` creates a compact data set that, when applied using bzr
5043
merge, has the same effect as merging from the source branch.
5045
By default the merge directive is self-contained and can be applied to any
5046
branch containing submit_branch in its ancestory without needing access to
5049
If --no-bundle is specified, then Bazaar doesn't send the contents of the
5050
revisions, but only a structured request to merge from the
5051
public_location. In that case the public_branch is needed and it must be
5052
up-to-date and accessible to the recipient. The public_branch is always
5053
included if known, so that people can check it later.
5055
The submit branch defaults to the parent of the source branch, but can be
5056
overridden. Both submit branch and public branch will be remembered in
5057
branch.conf the first time they are used for a particular branch. The
5058
source branch defaults to that containing the working directory, but can
5059
be changed using --from.
5061
In order to calculate those changes, bzr must analyse the submit branch.
5062
Therefore it is most efficient for the submit branch to be a local mirror.
5063
If a public location is known for the submit_branch, that location is used
5064
in the merge directive.
5066
The default behaviour is to send the merge directive by mail, unless -o is
5067
given, in which case it is sent to a file.
4821
If --no-bundle is specified, then public_branch is needed (and must be
4822
up-to-date), so that the receiver can perform the merge using the
4823
public_branch. The public_branch is always included if known, so that
4824
people can check it later.
4826
The submit branch defaults to the parent, but can be overridden. Both
4827
submit branch and public branch will be remembered if supplied.
4829
If a public_branch is known for the submit_branch, that public submit
4830
branch is used in the merge instructions. This means that a local mirror
4831
can be used as your actual submit branch, once you have set public_branch
5069
4834
Mail is sent using your preferred mail program. This should be transparent
5070
4835
on Windows (it uses MAPI). On Linux, it requires the xdg-email utility.
5118
4878
help='Write merge directive to this file; '
5119
4879
'use - for stdout.',
5122
help='Refuse to send if there are uncommitted changes in'
5123
' the working tree, --no-strict disables the check.'),
5124
4881
Option('mail-to', help='Mail the request to this address.',
5128
4885
Option('body', help='Body for the email.', type=unicode),
5129
RegistryOption('format',
5130
help='Use the specified output format.',
5131
lazy_registry=('bzrlib.send', 'format_registry')),
4886
RegistryOption.from_kwargs('format',
4887
'Use the specified output format.',
4888
**{'4': 'Bundle format 4, Merge Directive 2 (default)',
4889
'0.9': 'Bundle format 0.9, Merge Directive 1',})
5134
4892
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5135
4893
no_patch=False, revision=None, remember=False, output=None,
5136
format=None, mail_to=None, message=None, body=None,
5137
strict=None, **kwargs):
5138
from bzrlib.send import send
5139
return send(submit_branch, revision, public_branch, remember,
5140
format, no_bundle, no_patch, output,
5141
kwargs.get('from', '.'), mail_to, message, body,
4894
format=None, mail_to=None, message=None, body=None, **kwargs):
4895
return self._run(submit_branch, revision, public_branch, remember,
4896
format, no_bundle, no_patch, output,
4897
kwargs.get('from', '.'), mail_to, message, body)
4899
def _run(self, submit_branch, revision, public_branch, remember, format,
4900
no_bundle, no_patch, output, from_, mail_to, message, body):
4901
from bzrlib.revision import NULL_REVISION
4902
tree, branch = bzrdir.BzrDir.open_containing_tree_or_branch(from_)[:2]
4903
# we may need to write data into branch's repository to calculate
4908
config = branch.get_config()
4910
mail_to = config.get_user_option('submit_to')
4911
mail_client = config.get_mail_client()
4912
if (not getattr(mail_client, 'supports_body', False)
4913
and body is not None):
4914
raise errors.BzrCommandError(
4915
'Mail client "%s" does not support specifying body' %
4916
mail_client.__class__.__name__)
4917
if remember and submit_branch is None:
4918
raise errors.BzrCommandError(
4919
'--remember requires a branch to be specified.')
4920
stored_submit_branch = branch.get_submit_branch()
4921
remembered_submit_branch = None
4922
if submit_branch is None:
4923
submit_branch = stored_submit_branch
4924
remembered_submit_branch = "submit"
4926
if stored_submit_branch is None or remember:
4927
branch.set_submit_branch(submit_branch)
4928
if submit_branch is None:
4929
submit_branch = branch.get_parent()
4930
remembered_submit_branch = "parent"
4931
if submit_branch is None:
4932
raise errors.BzrCommandError('No submit branch known or'
4934
if remembered_submit_branch is not None:
4935
note('Using saved %s location "%s" to determine what '
4936
'changes to submit.', remembered_submit_branch,
4939
if mail_to is None or format is None:
4940
submit_config = Branch.open(submit_branch).get_config()
4942
mail_to = submit_config.get_user_option("child_submit_to")
4944
format = submit_config.get_user_option("child_submit_format")
4946
stored_public_branch = branch.get_public_branch()
4947
if public_branch is None:
4948
public_branch = stored_public_branch
4949
elif stored_public_branch is None or remember:
4950
branch.set_public_branch(public_branch)
4951
if no_bundle and public_branch is None:
4952
raise errors.BzrCommandError('No public branch specified or'
4954
base_revision_id = None
4956
if revision is not None:
4957
if len(revision) > 2:
4958
raise errors.BzrCommandError('bzr send takes '
4959
'at most two one revision identifiers')
4960
revision_id = revision[-1].as_revision_id(branch)
4961
if len(revision) == 2:
4962
base_revision_id = revision[0].as_revision_id(branch)
4963
if revision_id is None:
4964
revision_id = branch.last_revision()
4965
if revision_id == NULL_REVISION:
4966
raise errors.BzrCommandError('No revisions to submit.')
4970
directive = merge_directive.MergeDirective2.from_objects(
4971
branch.repository, revision_id, time.time(),
4972
osutils.local_time_offset(), submit_branch,
4973
public_branch=public_branch, include_patch=not no_patch,
4974
include_bundle=not no_bundle, message=message,
4975
base_revision_id=base_revision_id)
4976
elif format == '0.9':
4979
patch_type = 'bundle'
4981
raise errors.BzrCommandError('Format 0.9 does not'
4982
' permit bundle with no patch')
4988
directive = merge_directive.MergeDirective.from_objects(
4989
branch.repository, revision_id, time.time(),
4990
osutils.local_time_offset(), submit_branch,
4991
public_branch=public_branch, patch_type=patch_type,
4994
raise errors.BzrCommandError("No such send format '%s'." %
4998
directive.compose_merge_request(mail_client, mail_to, body,
5004
outfile = open(output, 'wb')
5006
outfile.writelines(directive.to_lines())
5008
if outfile is not self.outf:
5146
5014
class cmd_bundle_revisions(cmd_send):
5147
5016
"""Create a merge-directive for submitting changes.
5149
5018
A merge directive provides many things needed for requesting merges:
5207
5074
def run(self, submit_branch=None, public_branch=None, no_bundle=False,
5208
5075
no_patch=False, revision=None, remember=False, output=None,
5209
format=None, strict=None, **kwargs):
5076
format=None, **kwargs):
5210
5077
if output is None:
5212
from bzrlib.send import send
5213
return send(submit_branch, revision, public_branch, remember,
5079
return self._run(submit_branch, revision, public_branch, remember,
5214
5080
format, no_bundle, no_patch, output,
5215
kwargs.get('from', '.'), None, None, None,
5216
self.outf, strict=strict)
5081
kwargs.get('from', '.'), None, None, None)
5219
5084
class cmd_tag(Command):
5259
5124
branch, relpath = Branch.open_containing(directory)
5260
5125
branch.lock_write()
5261
self.add_cleanup(branch.unlock)
5263
branch.tags.delete_tag(tag_name)
5264
self.outf.write('Deleted tag %s.\n' % tag_name)
5267
if len(revision) != 1:
5268
raise errors.BzrCommandError(
5269
"Tags can only be placed on a single revision, "
5271
revision_id = revision[0].as_revision_id(branch)
5128
branch.tags.delete_tag(tag_name)
5129
self.outf.write('Deleted tag %s.\n' % tag_name)
5273
revision_id = branch.last_revision()
5274
if (not force) and branch.tags.has_tag(tag_name):
5275
raise errors.TagAlreadyExists(tag_name)
5276
branch.tags.set_tag(tag_name, revision_id)
5277
self.outf.write('Created tag %s.\n' % tag_name)
5132
if len(revision) != 1:
5133
raise errors.BzrCommandError(
5134
"Tags can only be placed on a single revision, "
5136
revision_id = revision[0].as_revision_id(branch)
5138
revision_id = branch.last_revision()
5139
if (not force) and branch.tags.has_tag(tag_name):
5140
raise errors.TagAlreadyExists(tag_name)
5141
branch.tags.set_tag(tag_name, revision_id)
5142
self.outf.write('Created tag %s.\n' % tag_name)
5280
5147
class cmd_tags(Command):
5389
5250
Option('bind-to', help='Branch to bind checkout to.', type=str),
5390
5251
Option('force',
5391
help='Perform reconfiguration even if local changes'
5393
Option('stacked-on',
5394
help='Reconfigure a branch to be stacked on another branch.',
5398
help='Reconfigure a branch to be unstacked. This '
5399
'may require copying substantial data into it.',
5252
help='Perform reconfiguration even if local changes'
5403
def run(self, location=None, target_type=None, bind_to=None, force=False,
5256
def run(self, location=None, target_type=None, bind_to=None, force=False):
5406
5257
directory = bzrdir.BzrDir.open(location)
5407
if stacked_on and unstacked:
5408
raise BzrCommandError("Can't use both --stacked-on and --unstacked")
5409
elif stacked_on is not None:
5410
reconfigure.ReconfigureStackedOn().apply(directory, stacked_on)
5412
reconfigure.ReconfigureUnstacked().apply(directory)
5413
# At the moment you can use --stacked-on and a different
5414
# reconfiguration shape at the same time; there seems no good reason
5416
5258
if target_type is None:
5417
if stacked_on or unstacked:
5420
raise errors.BzrCommandError('No target configuration '
5259
raise errors.BzrCommandError('No target configuration specified')
5422
5260
elif target_type == 'branch':
5423
5261
reconfiguration = reconfigure.Reconfigure.to_branch(directory)
5424
5262
elif target_type == 'tree':
5461
5299
/path/to/newbranch.
5463
5301
Bound branches use the nickname of its master branch unless it is set
5464
locally, in which case switching will update the local nickname to be
5302
locally, in which case switching will update the the local nickname to be
5465
5303
that of the master.
5468
takes_args = ['to_location?']
5306
takes_args = ['to_location']
5469
5307
takes_options = [Option('force',
5470
help='Switch even if local commits will be lost.'),
5472
Option('create-branch', short_name='b',
5473
help='Create the target branch from this one before'
5474
' switching to it.'),
5308
help='Switch even if local commits will be lost.')
5477
def run(self, to_location=None, force=False, create_branch=False,
5311
def run(self, to_location, force=False):
5479
5312
from bzrlib import switch
5480
5313
tree_location = '.'
5481
revision = _get_one_revision('switch', revision)
5482
5314
control_dir = bzrdir.BzrDir.open_containing(tree_location)[0]
5483
if to_location is None:
5484
if revision is None:
5485
raise errors.BzrCommandError('You must supply either a'
5486
' revision or a location')
5489
5316
branch = control_dir.open_branch()
5490
5317
had_explicit_nick = branch.get_config().has_explicit_nickname()
5491
5318
except errors.NotBranchError:
5493
5319
had_explicit_nick = False
5496
raise errors.BzrCommandError('cannot create branch without'
5498
to_location = directory_service.directories.dereference(
5500
if '/' not in to_location and '\\' not in to_location:
5501
# This path is meant to be relative to the existing branch
5502
this_url = self._get_branch_location(control_dir)
5503
to_location = urlutils.join(this_url, '..', to_location)
5504
to_branch = branch.bzrdir.sprout(to_location,
5505
possible_transports=[branch.bzrdir.root_transport],
5506
source_branch=branch).open_branch()
5509
to_branch = Branch.open(to_location)
5510
except errors.NotBranchError:
5511
this_url = self._get_branch_location(control_dir)
5512
to_branch = Branch.open(
5513
urlutils.join(this_url, '..', to_location))
5514
if revision is not None:
5515
revision = revision.as_revision_id(to_branch)
5516
switch.switch(control_dir, to_branch, force, revision_id=revision)
5321
to_branch = Branch.open(to_location)
5322
except errors.NotBranchError:
5323
this_url = self._get_branch_location(control_dir)
5324
to_branch = Branch.open(
5325
urlutils.join(this_url, '..', to_location))
5326
switch.switch(control_dir, to_branch, force)
5517
5327
if had_explicit_nick:
5518
5328
branch = control_dir.open_branch() #get the new branch!
5519
5329
branch.nick = to_branch.nick
5761
5571
if writer is None:
5762
5572
writer = bzrlib.option.diff_writer_registry.get()
5764
shelver = Shelver.from_args(writer(sys.stdout), revision, all,
5765
file_list, message, destroy=destroy)
5574
Shelver.from_args(writer(sys.stdout), revision, all, file_list,
5575
message, destroy=destroy).run()
5770
5576
except errors.UserAbort:
5773
5579
def run_for_list(self):
5774
5580
tree = WorkingTree.open_containing('.')[0]
5775
5581
tree.lock_read()
5776
self.add_cleanup(tree.unlock)
5777
manager = tree.get_shelf_manager()
5778
shelves = manager.active_shelves()
5779
if len(shelves) == 0:
5780
note('No shelved changes.')
5782
for shelf_id in reversed(shelves):
5783
message = manager.get_metadata(shelf_id).get('message')
5785
message = '<no message>'
5786
self.outf.write('%3d: %s\n' % (shelf_id, message))
5583
manager = tree.get_shelf_manager()
5584
shelves = manager.active_shelves()
5585
if len(shelves) == 0:
5586
note('No shelved changes.')
5588
for shelf_id in reversed(shelves):
5589
message = manager.get_metadata(shelf_id).get('message')
5591
message = '<no message>'
5592
self.outf.write('%3d: %s\n' % (shelf_id, message))
5790
5598
class cmd_unshelve(Command):