27
30
from bzrlib.commands import Command, display_command
28
31
from bzrlib.branch import Branch
29
32
from bzrlib.revision import common_ancestor
33
import bzrlib.errors as errors
30
34
from bzrlib.errors import (BzrError, BzrCheckError, BzrCommandError,
31
35
NotBranchError, DivergedBranches, NotConflicted,
32
36
NoSuchFile, NoWorkingTree, FileInWrongBranch)
35
39
import bzrlib.trace
36
40
from bzrlib.trace import mutter, note, log_error, warning, is_quiet
37
41
from bzrlib.workingtree import WorkingTree
40
def tree_files(file_list, default_branch='.'):
42
from bzrlib.log import show_one_log
45
def tree_files(file_list, default_branch=u'.'):
42
47
return internal_tree_files(file_list, default_branch)
43
48
except FileInWrongBranch, e:
44
49
raise BzrCommandError("%s is not in the same branch as %s" %
45
50
(e.path, file_list[0]))
47
def internal_tree_files(file_list, default_branch='.'):
52
def internal_tree_files(file_list, default_branch=u'.'):
49
54
Return a branch and list of branch-relative paths.
50
55
If supplied file_list is empty or None, the branch default will be used,
211
217
implicitly add the parent, and so on up to the root. This means
212
218
you should never need to explictly add a directory, they'll just
213
219
get added when you add a file in the directory.
221
--dry-run will show which files would be added, but not actually
215
224
takes_args = ['file*']
216
takes_options = ['no-recurse']
218
def run(self, file_list, no_recurse=False):
219
from bzrlib.add import smart_add, add_reporter_print, add_reporter_null
221
reporter = add_reporter_null
225
takes_options = ['no-recurse', 'dry-run', 'verbose']
227
def run(self, file_list, no_recurse=False, dry_run=False, verbose=False):
232
# This is pointless, but I'd rather not raise an error
233
action = bzrlib.add.add_action_null
235
action = bzrlib.add.add_action_print
237
action = bzrlib.add.add_action_add
223
reporter = add_reporter_print
224
smart_add(file_list, not no_recurse, reporter)
239
action = bzrlib.add.add_action_add_and_print
241
added, ignored = bzrlib.add.smart_add(file_list, not no_recurse,
244
for glob in sorted(ignored.keys()):
245
match_len = len(ignored[glob])
247
for path in ignored[glob]:
248
print "ignored %s matching \"%s\"" % (path, glob)
250
print "ignored %d file(s) matching \"%s\"" % (match_len,
252
print "If you wish to add some of these files, please add them"\
227
256
class cmd_mkdir(Command):
383
412
print "Using saved location: %s" % stored_loc
384
413
location = stored_loc
385
415
br_from = Branch.open(location)
386
416
br_to = tree_to.branch
388
old_rh = br_to.revision_history()
389
count = tree_to.pull(br_from, overwrite)
390
except DivergedBranches:
391
# FIXME: Just make DivergedBranches display the right message
393
raise BzrCommandError("These branches have diverged."
418
old_rh = br_to.revision_history()
419
count = tree_to.pull(br_from, overwrite)
395
421
if br_to.get_parent() is None or remember:
396
422
br_to.set_parent(location)
397
note('%d revision(s) pulled.', count)
423
note('%d revision(s) pulled.' % (count,))
399
426
new_rh = tree_to.branch.revision_history()
400
427
if old_rh != new_rh:
476
503
raise BzrCommandError("Could not creeate "
478
505
br_to = Branch.initialize(location)
506
old_rh = br_to.revision_history()
480
old_rh = br_to.revision_history()
481
count = br_to.pull(br_from, overwrite)
509
tree_to = br_to.working_tree()
510
except NoWorkingTree:
511
# TODO: This should be updated for branches which don't have a
512
# working tree, as opposed to ones where we just couldn't
514
warning('Unable to update the working tree of: %s' % (br_to.base,))
515
count = br_to.pull(br_from, overwrite)
517
count = tree_to.pull(br_from, overwrite)
482
518
except DivergedBranches:
483
519
raise BzrCommandError("These branches have diverged."
484
520
" Try a merge then push with overwrite.")
485
521
if br_from.get_push_location() is None or remember:
486
522
br_from.set_push_location(location)
487
523
note('%d revision(s) pushed.' % (count,))
489
526
new_rh = br_to.revision_history()
490
527
if old_rh != new_rh:
1127
1168
is found exports to a directory (equivalent to --format=dir).
1129
1170
Root may be the top directory for tar, tgz and tbz2 formats. If none
1130
is given, the top directory will be the root name of the file."""
1131
# TODO: list known exporters
1171
is given, the top directory will be the root name of the file.
1173
Note: export of tree with non-ascii filenames to zip is not supported.
1175
Supported formats Autodetected by extension
1176
----------------- -------------------------
1179
tbz2 .tar.bz2, .tbz2
1132
1183
takes_args = ['dest']
1133
1184
takes_options = ['revision', 'format', 'root']
1134
1185
def run(self, dest, revision=None, format=None, root=None):
1136
tree = WorkingTree.open_containing('.')[0]
1187
from bzrlib.export import export
1188
tree = WorkingTree.open_containing(u'.')[0]
1137
1189
b = tree.branch
1138
1190
if revision is None:
1139
1191
# should be tree.last_revision FIXME
1140
rev_id = tree.branch.last_revision()
1192
rev_id = b.last_revision()
1142
1194
if len(revision) != 1:
1143
1195
raise BzrError('bzr export --revision takes exactly 1 argument')
1144
1196
rev_id = revision[0].in_history(b).rev_id
1145
1197
t = b.revision_tree(rev_id)
1146
arg_root, ext = os.path.splitext(os.path.basename(dest))
1147
if ext in ('.gz', '.bz2'):
1148
new_root, new_ext = os.path.splitext(arg_root)
1149
if new_ext == '.tar':
1155
if ext in (".tar",):
1157
elif ext in (".tar.gz", ".tgz"):
1159
elif ext in (".tar.bz2", ".tbz2"):
1163
t.export(dest, format, root)
1199
export(t, dest, format, root)
1200
except errors.NoSuchExportFormat, e:
1201
raise BzrCommandError('Unsupported export format: %s' % e.format)
1166
1204
class cmd_cat(Command):
1234
1275
unchanged=False, strict=False):
1235
1276
from bzrlib.errors import (PointlessCommit, ConflictsInTree,
1236
1277
StrictCommitFailed)
1237
from bzrlib.msgeditor import edit_commit_message
1278
from bzrlib.msgeditor import edit_commit_message, \
1279
make_commit_message_template
1238
1280
from bzrlib.status import show_status
1239
from cStringIO import StringIO
1281
from tempfile import TemporaryFile
1284
# TODO: Need a blackbox test for invoking the external editor; may be
1285
# slightly problematic to run this cross-platform.
1287
# TODO: do more checks that the commit will succeed before
1288
# spending the user's valuable time typing a commit message.
1290
# TODO: if the commit *does* happen to fail, then save the commit
1291
# message to a temporary file where it can be recovered
1241
1292
tree, selected_list = tree_files(selected_list)
1242
1293
if message is None and not file:
1243
catcher = StringIO()
1244
show_status(tree.branch, specific_files=selected_list,
1246
message = edit_commit_message(catcher.getvalue())
1294
template = make_commit_message_template(tree, selected_list)
1295
message = edit_commit_message(template)
1248
1296
if message is None:
1249
1297
raise BzrCommandError("please specify a commit message"
1250
1298
" with either --message or --file")
1281
1329
This command checks various invariants about the branch storage to
1282
1330
detect data corruption or bzr bugs.
1284
takes_args = ['dir?']
1332
takes_args = ['branch?']
1285
1333
takes_options = ['verbose']
1287
def run(self, dir='.', verbose=False):
1335
def run(self, branch=None, verbose=False):
1288
1336
from bzrlib.check import check
1289
check(WorkingTree.open_containing(dir)[0].branch, verbose)
1338
tree = WorkingTree.open_containing()[0]
1339
branch = tree.branch
1341
branch = Branch.open(branch)
1342
check(branch, verbose)
1292
1345
class cmd_scan_cache(Command):
1712
1765
class cmd_missing(Command):
1713
"""What is missing in this branch relative to other branch.
1715
# TODO: rewrite this in terms of ancestry so that it shows only
1718
takes_args = ['remote?']
1719
aliases = ['mis', 'miss']
1720
takes_options = ['verbose']
1723
def run(self, remote=None, verbose=False):
1724
from bzrlib.errors import BzrCommandError
1725
from bzrlib.missing import show_missing
1727
if verbose and is_quiet():
1728
raise BzrCommandError('Cannot pass both quiet and verbose')
1730
tree = WorkingTree.open_containing('.')[0]
1731
parent = tree.branch.get_parent()
1766
"""Show unmerged/unpulled revisions between two branches.
1768
OTHER_BRANCH may be local or remote."""
1769
takes_args = ['other_branch?']
1770
takes_options = [Option('reverse', 'Reverse the order of revisions'),
1772
'Display changes in the local branch only'),
1773
Option('theirs-only',
1774
'Display changes in the remote branch only'),
1782
def run(self, other_branch=None, reverse=False, mine_only=False,
1783
theirs_only=False, long=True, short=False, line=False,
1784
show_ids=False, verbose=False):
1785
from bzrlib.missing import find_unmerged, iter_log_data
1786
from bzrlib.log import log_formatter
1787
local_branch = bzrlib.branch.Branch.open_containing(u".")[0]
1788
parent = local_branch.get_parent()
1789
if other_branch is None:
1790
other_branch = parent
1791
if other_branch is None:
1734
1792
raise BzrCommandError("No missing location known or specified.")
1737
print "Using last location: %s" % parent
1739
elif parent is None:
1740
# We only update parent if it did not exist, missing
1741
# should not change the parent
1742
tree.branch.set_parent(remote)
1743
br_remote = Branch.open_containing(remote)[0]
1744
return show_missing(tree.branch, br_remote, verbose=verbose,
1793
print "Using last location: " + local_branch.get_parent()
1794
remote_branch = bzrlib.branch.Branch.open(other_branch)
1795
local_extra, remote_extra = find_unmerged(local_branch, remote_branch)
1796
log_format = get_log_format(long=long, short=short, line=line)
1797
lf = log_formatter(log_format, sys.stdout,
1799
show_timezone='original')
1800
if reverse is False:
1801
local_extra.reverse()
1802
remote_extra.reverse()
1803
if local_extra and not theirs_only:
1804
print "You have %d extra revision(s):" % len(local_extra)
1805
for data in iter_log_data(local_extra, local_branch, verbose):
1807
printed_local = True
1809
printed_local = False
1810
if remote_extra and not mine_only:
1811
if printed_local is True:
1813
print "You are missing %d revision(s):" % len(remote_extra)
1814
for data in iter_log_data(remote_extra, remote_branch, verbose):
1816
if not remote_extra and not local_extra:
1818
print "Branches are up to date."
1821
if parent is None and other_branch is not None:
1822
local_branch.set_parent(other_branch)
1748
1826
class cmd_plugins(Command):
1861
1939
raise BzrCommandError('Please supply either one revision, or a range.')
1942
class cmd_uncommit(bzrlib.commands.Command):
1943
"""Remove the last committed revision.
1945
By supplying the --all flag, it will not only remove the entry
1946
from revision_history, but also remove all of the entries in the
1949
--verbose will print out what is being removed.
1950
--dry-run will go through all the motions, but not actually
1953
In the future, uncommit will create a changeset, which can then
1956
takes_options = ['all', 'verbose', 'revision',
1957
Option('dry-run', help='Don\'t actually make changes'),
1958
Option('force', help='Say yes to all questions.')]
1959
takes_args = ['location?']
1962
def run(self, location=None, all=False,
1963
dry_run=False, verbose=False,
1964
revision=None, force=False):
1965
from bzrlib.branch import Branch
1966
from bzrlib.log import log_formatter
1968
from bzrlib.uncommit import uncommit
1970
if location is None:
1972
b, relpath = Branch.open_containing(location)
1974
if revision is None:
1976
rev_id = b.last_revision()
1978
revno, rev_id = revision[0].in_history(b)
1980
print 'No revisions to uncommit.'
1982
for r in range(revno, b.revno()+1):
1983
rev_id = b.get_rev_id(r)
1984
lf = log_formatter('short', to_file=sys.stdout,show_timezone='original')
1985
lf.show(r, b.get_revision(rev_id), None)
1988
print 'Dry-run, pretending to remove the above revisions.'
1990
val = raw_input('Press <enter> to continue')
1992
print 'The above revision(s) will be removed.'
1994
val = raw_input('Are you sure [y/N]? ')
1995
if val.lower() not in ('y', 'yes'):
1999
uncommit(b, remove_files=all,
2000
dry_run=dry_run, verbose=verbose,
1864
2004
# these get imported and then picked up by the scan for cmd_*
1865
2005
# TODO: Some more consistent way to split command definitions across files;
1866
2006
# we do need to load at least some information about them to know of