60
55
Show summary of pending changes.
62
57
Make a file not versioned.
59
Show statistics about this branch.
65
# not currently working:
67
# Show some information about this branch.
71
__copyright__ = "Copyright 2005 Canonical Development Ltd."
72
__author__ = "Martin Pool <mbp@canonical.com>"
73
__docformat__ = "restructuredtext en"
77
import sys, os, random, time, sha, sets, types, re, shutil, tempfile
78
import traceback, socket, fnmatch, difflib
65
import sys, os, time, types, shutil, tempfile, traceback, fnmatch, difflib, os.path
80
66
from sets import Set
81
67
from pprint import pprint
165
151
print Branch('.').revno()
168
155
def cmd_add(file_list, verbose=False):
169
"""Add specified files.
156
"""Add specified files or directories.
158
In non-recursive mode, all the named items are added, regardless
159
of whether they were previously ignored. A warning is given if
160
any of the named files are already versioned.
162
In recursive mode (the default), files are treated the same way
163
but the behaviour for directories is different. Directories that
164
are already versioned do not give a warning. All directories,
165
whether already versioned or not, are searched for files or
166
subdirectories that are neither versioned or ignored, and these
167
are added. This search proceeds recursively into versioned
170
Therefore simply saying 'bzr add .' will version all files that
171
are currently unknown.
173
bzrlib.add.smart_add(file_list, verbose)
171
Fails if the files are already added.
173
Branch('.').add(file_list, verbose=verbose)
176
def cmd_relpath(filename):
177
"""Show path of file relative to root"""
178
print Branch(filename).relpath(filename)
176
182
def cmd_inventory(revision=None):
197
# TODO: Maybe a 'mv' command that has the combined move/rename
198
# special behaviour of Unix?
200
def cmd_move(source_list, dest):
203
b.move([b.relpath(s) for s in source_list], b.relpath(dest))
207
def cmd_rename(from_name, to_name):
208
"""Change the name of an entry.
210
usage: bzr rename FROM_NAME TO_NAME
213
bzr rename frob.c frobber.c
214
bzr rename src/frob.c lib/frob.c
216
It is an error if the destination name exists.
218
See also the 'move' command, which moves files into a different
219
directory without changing their name.
221
TODO: Some way to rename multiple files without invoking bzr for each
224
b.rename_one(b.relpath(from_name), b.relpath(to_name))
229
def cmd_renames(dir='.'):
230
"""Show list of renamed files.
232
usage: bzr renames [BRANCH]
234
TODO: Option to show renames between two historical versions.
236
TODO: Only show renames under dir, rather than in the whole branch.
239
old_inv = b.basis_tree().inventory
240
new_inv = b.read_working_inventory()
242
renames = list(bzrlib.tree.find_renames(old_inv, new_inv))
244
for old_name, new_name in renames:
245
print "%s => %s" % (old_name, new_name)
193
print 'branch format:', b.controlfile('branch-format', 'r').readline().rstrip('\n')
195
def plural(n, base='', pl=None):
203
count_version_dirs = 0
205
count_status = {'A': 0, 'D': 0, 'M': 0, 'R': 0, '?': 0, 'I': 0, '.': 0}
206
for st_tup in bzrlib.diff_trees(b.basis_tree(), b.working_tree()):
208
count_status[fs] += 1
209
if fs not in ['I', '?'] and st_tup[4] == 'directory':
210
count_version_dirs += 1
213
print 'in the working tree:'
214
for name, fs in (('unchanged', '.'),
215
('modified', 'M'), ('added', 'A'), ('removed', 'D'),
216
('renamed', 'R'), ('unknown', '?'), ('ignored', 'I'),
218
print ' %5d %s' % (count_status[fs], name)
219
print ' %5d versioned subdirector%s' % (count_version_dirs,
220
plural(count_version_dirs, 'y', 'ies'))
223
print 'branch history:'
224
history = b.revision_history()
226
print ' %5d revision%s' % (revno, plural(revno))
229
committers.add(b.get_revision(rev).committer)
230
print ' %5d committer%s' % (len(committers), plural(len(committers)))
232
firstrev = b.get_revision(history[0])
233
age = int((time.time() - firstrev.timestamp) / 3600 / 24)
234
print ' %5d day%s old' % (age, plural(age))
235
print ' first revision: %s' % format_date(firstrev.timestamp,
238
lastrev = b.get_revision(history[-1])
239
print ' latest revision: %s' % format_date(lastrev.timestamp,
250
"""info: Show statistical information for this branch
254
info.show_info(Branch('.'))
245
258
def cmd_remove(file_list, verbose=False):
246
Branch('.').remove(file_list, verbose=verbose)
259
b = Branch(file_list[0])
260
b.remove([b.relpath(f) for f in file_list], verbose=verbose)
250
264
def cmd_file_id(filename):
251
i = Branch('.').read_working_inventory().path2id(filename)
253
bailout("%s is not a versioned file" % filename)
265
"""Print file_id of a particular file or directory.
267
usage: bzr file-id FILE
269
The file_id is assigned when the file is first added and remains the
270
same through all revisions where the file exists, even when it is
274
i = b.inventory.path2id(b.relpath(filename))
276
bailout("%r is not a versioned file" % filename)
258
def cmd_find_filename(fileid):
259
n = find_filename(fileid)
261
bailout("%s is not a live file id" % fileid)
281
def cmd_file_id_path(filename):
282
"""Print path of file_ids to a file or directory.
284
usage: bzr file-id-path FILE
286
This prints one line for each directory down to the target,
287
starting at the branch root."""
290
fid = inv.path2id(b.relpath(filename))
292
bailout("%r is not a versioned file" % filename)
293
for fip in inv.get_idpath(fid):
266
297
def cmd_revision_history():
282
325
Branch('.', init=True)
285
def cmd_diff(revision=None):
286
"""Show diff from basis to working copy.
288
:todo: Take one or two revision arguments, look up those trees,
291
:todo: Allow diff across branches.
293
:todo: Mangle filenames in diff to be more relevant.
295
:todo: Shouldn't be in the cmd function.
328
def cmd_diff(revision=None, file_list=None):
329
"""bzr diff: Show differences in working tree.
331
usage: bzr diff [-r REV] [FILE...]
334
Show changes since REV, rather than predecessor.
336
If files are listed, only the changes in those files are listed.
337
Otherwise, all changes for the tree are listed.
339
TODO: Given two revision arguments, show the difference between them.
341
TODO: Allow diff across branches.
343
TODO: Option to use external diff command; could be GNU diff, wdiff,
346
TODO: If a directory is given, diff everything under that.
348
TODO: Selected-file diff is inefficient and doesn't show you deleted files.
351
## TODO: Shouldn't be in the cmd function.
434
def cmd_deleted(show_ids=False):
435
"""List files deleted in the working tree.
437
TODO: Show files deleted since a previous revision, or between two revisions.
441
new = b.working_tree()
443
## TODO: Much more efficient way to do this: read in new
444
## directories with readdir, rather than stating each one. Same
445
## level of effort but possibly much less IO. (Or possibly not,
446
## if the directories are very large...)
448
for path, ie in old.inventory.iter_entries():
449
if not new.has_id(ie.file_id):
451
print '%-50s %s' % (path, ie.file_id)
457
def cmd_parse_inventory():
460
cElementTree.ElementTree().parse(file('.bzr/inventory'))
464
def cmd_load_inventory():
465
"""Load inventory for timing purposes"""
466
Branch('.').basis_tree().inventory
469
def cmd_dump_inventory():
470
Branch('.').read_working_inventory().write_xml(sys.stdout)
473
def cmd_dump_new_inventory():
474
import bzrlib.newinventory
475
inv = Branch('.').basis_tree().inventory
476
bzrlib.newinventory.write_inventory(inv, sys.stdout)
479
def cmd_load_new_inventory():
480
import bzrlib.newinventory
481
bzrlib.newinventory.read_new_inventory(sys.stdin)
484
def cmd_dump_slacker_inventory():
485
import bzrlib.newinventory
486
inv = Branch('.').basis_tree().inventory
487
bzrlib.newinventory.write_slacker_inventory(inv, sys.stdout)
491
def cmd_root(filename=None):
492
"""Print the branch root."""
493
print bzrlib.branch.find_branch_root(filename)
371
496
def cmd_log(timezone='original'):
372
497
"""Show log of this branch.
446
def cmd_commit(message, verbose=False):
588
def cmd_commit(message=None, verbose=False):
589
"""Commit changes to a new revision.
592
Description of changes in this revision; free form text.
593
It is recommended that the first line be a single-sentence
596
Show status of changed files,
598
TODO: Commit only selected files.
600
TODO: Run hooks on tree to-be-committed, and after commit.
602
TODO: Strict commit that fails if there are unknown or deleted files.
606
bailout("please specify a commit message")
447
607
Branch('.').commit(message, verbose=verbose)
451
"""Check consistency of the branch."""
610
def cmd_check(dir='.'):
611
"""check: Consistency check of branch history.
613
usage: bzr check [-v] [BRANCH]
616
--verbose, -v Show progress of checking.
618
This command checks various invariants about the branch storage to
619
detect data corruption or bzr bugs.
622
bzrlib.check.check(Branch(dir, find_root=False))
455
625
def cmd_is(pred, *rest):
478
648
def cmd_gen_revision_id():
480
649
print bzrlib.branch._gen_revision_id(time.time())
484
"""Run internal doctest suite"""
653
"""Run internal test suite"""
485
654
## -v, if present, is seen by doctest; the argument is just here
486
655
## so our parser doesn't complain
488
657
## TODO: --verbose option
659
failures, tests = 0, 0
490
import doctest, bzrlib.store
661
import doctest, bzrlib.store, bzrlib.tests
491
662
bzrlib.trace.verbose = False
492
doctest.testmod(bzrlib.store)
493
doctest.testmod(bzrlib.inventory)
494
doctest.testmod(bzrlib.branch)
495
doctest.testmod(bzrlib.osutils)
496
doctest.testmod(bzrlib.tree)
498
# more strenuous tests;
500
doctest.testmod(bzrlib.tests)
664
for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
665
bzrlib.tree, bzrlib.tests, bzrlib.commands, bzrlib.add:
666
mf, mt = doctest.testmod(m)
669
print '%-40s %3d tests' % (m.__name__, mt),
671
print '%3d FAILED!' % mf
675
print '%-40s %3d tests' % ('total', tests),
677
print '%3d FAILED!' % failures
684
cmd_doctest = cmd_selftest
503
687
######################################################################
508
# TODO: Specific help for particular commands
691
def cmd_help(topic=None):
696
# otherwise, maybe the name of a command?
698
cmdfn = globals()['cmd_' + topic.replace('-', '_')]
700
bailout("no help for %r" % topic)
704
bailout("sorry, no detailed help yet for %r" % topic)
512
711
def cmd_version():
513
print "bzr (bazaar-ng) %s" % __version__
712
print "bzr (bazaar-ng) %s" % bzrlib.__version__
713
print bzrlib.__copyright__
515
714
print "http://bazaar-ng.org/"
569
770
'add': ['file+'],
774
'export': ['revno', 'dest'],
572
775
'file-id': ['filename'],
776
'file-id-path': ['filename'],
573
777
'get-file-text': ['text_id'],
574
778
'get-inventory': ['inventory_id'],
575
779
'get-revision': ['revision_id'],
576
780
'get-revision-inventory': ['revision_id'],
578
784
'lookup-revision': ['revno'],
579
'export': ['revno', 'dest'],
785
'move': ['source$', 'dest'],
786
'relpath': ['filename'],
580
787
'remove': ['file+'],
788
'rename': ['from_name', 'to_name'],
790
'root': ['filename?'],
744
993
## TODO: If the arguments are wrong, give a usage message rather
745
994
## than just a backtrace.
996
bzrlib.trace.create_tracefile(argv)
748
# TODO: Lift into separate function in trace.py
749
# TODO: Also show contents of /etc/lsb-release, if it can be parsed.
750
# Perhaps that should eventually go into the platform library?
751
# TODO: If the file doesn't exist, add a note describing it.
752
t = bzrlib.trace._tracefile
753
t.write('-' * 60 + '\n')
754
t.write('bzr invoked at %s\n' % format_date(time.time()))
755
t.write(' by %s on %s\n' % (bzrlib.osutils.username(), socket.getfqdn()))
756
t.write(' arguments: %r\n' % argv)
758
starttime = os.times()[4]
761
t.write(' platform: %s\n' % platform.platform())
762
t.write(' python: %s\n' % platform.python_version())
764
999
ret = run_bzr(argv)
767
mutter("finished, %.3fu/%.3fs cpu, %.3fu/%.3fs cum"
769
mutter(" %.3f elapsed" % (times[4] - starttime))
772
1001
except BzrError, e:
773
1002
log_error('bzr: error: ' + e.args[0] + '\n')
774
1003
if len(e.args) > 1:
775
1004
for h in e.args[1]:
776
1005
log_error(' ' + h + '\n')
1006
traceback.print_exc(None, bzrlib.trace._tracefile)
1007
log_error('(see $HOME/.bzr.log for debug information)\n')
778
1009
except Exception, e:
779
1010
log_error('bzr: exception: %s\n' % e)
780
log_error(' see .bzr.log for details\n')
1011
log_error('(see $HOME/.bzr.log for debug information)\n')
781
1012
traceback.print_exc(None, bzrlib.trace._tracefile)
782
traceback.print_exc(None, sys.stderr)
1013
## traceback.print_exc(None, sys.stderr)
785
1016
# TODO: Maybe nicer handling of IOError?