115
113
## TODO: Perhaps make UUIDs predictable in test mode to make it easier
116
114
## to compare output?
121
######################################################################
116
## TODO: Some kind of global code to generate the right Branch object
117
## to work on. Almost, but not quite all, commands need one, and it
118
## can be taken either from their parameters or their working
121
## TODO: rename command, needed soon: check destination doesn't exist
122
## either in working copy or tree; move working copy; update
123
## inventory; write out
125
## TODO: move command; check destination is a directory and will not
128
## TODO: command to show renames, one per line, as to->from
125
133
def cmd_status(all=False):
141
149
Branch('.').get_revision(revision_id).write_xml(sys.stdout)
144
def cmd_get_inventory(inventory_id):
145
"""Return inventory in XML by hash"""
146
Branch('.').get_inventory(inventory_hash).write_xml(sys.stdout)
149
def cmd_get_revision_inventory(revision_id):
150
"""Output inventory for a revision."""
152
b.get_revision_inventory(revision_id).write_xml(sys.stdout)
155
152
def cmd_get_file_text(text_id):
156
153
"""Get contents of a file by hash."""
157
154
sf = Branch('.').text_store[text_id]
196
193
print 'branch format:', b.controlfile('branch-format', 'r').readline().rstrip('\n')
197
print 'revision number:', b.revno()
198
print 'number of versioned files:', len(b.read_working_inventory())
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,
201
245
def cmd_remove(file_list, verbose=False):
371
def cmd_log(timezone='original'):
328
372
"""Show log of this branch.
330
374
:todo: Options for utc; to show ids; to limit range; etc.
332
Branch('.').write_log()
376
Branch('.').write_log(show_timezone=timezone)
335
379
def cmd_ls(revision=None, verbose=False):
513
558
'commit': ['message', 'verbose'],
514
559
'diff': ['revision'],
515
560
'inventory': ['revision'],
561
'log': ['show-ids', 'timezone'],
516
562
'ls': ['revision', 'verbose'],
563
'remove': ['verbose'],
517
564
'status': ['all'],
519
'remove': ['verbose'],
546
591
lookup table, something about the available options, what optargs
547
592
they take, and which commands will accept them.
549
>>> parse_args('bzr --help'.split())
594
>>> parse_args('--help'.split())
550
595
([], {'help': True})
551
>>> parse_args('bzr --version'.split())
596
>>> parse_args('--version'.split())
552
597
([], {'version': True})
553
>>> parse_args('bzr status --all'.split())
598
>>> parse_args('status --all'.split())
554
599
(['status'], {'all': True})
600
>>> parse_args('commit --message=biter'.split())
601
(['commit'], {'message': u'biter'})
559
606
# TODO: Maybe handle '--' to end options?
566
613
mutter(" got option %r" % a)
615
optname, optarg = a[2:].split('=', 1)
568
618
if optname not in OPTIONS:
569
619
bailout('unknown long option %r' % a)
576
626
if optname in opts:
577
627
# XXX: Do we ever want to support this, e.g. for -r?
578
628
bailout('repeated option %r' % a)
579
630
optargfn = OPTIONS[optname]
582
bailout('option %r needs an argument' % a)
583
opts[optname] = optargfn(it.next())
634
bailout('option %r needs an argument' % a)
637
opts[optname] = optargfn(optarg)
584
638
mutter(" option argument %r" % opts[optname])
586
# takes no option argument
641
bailout('option %r takes no argument' % optname)
587
642
opts[optname] = True
589
bailout('unknown short option %r' % a)
648
702
logging and error handling.
651
args, opts = parse_args(argv)
705
args, opts = parse_args(argv[1:])
652
706
if 'help' in opts:
653
707
# TODO: pass down other arguments in case they asked for
654
708
# help on a command name?
692
746
## than just a backtrace.
749
# TODO: Lift into separate function in trace.py
750
# TODO: Also show contents of /etc/lsb-release, if it can be parsed.
751
# Perhaps that should eventually go into the platform library?
752
# TODO: If the file doesn't exist, add a note describing it.
695
753
t = bzrlib.trace._tracefile
696
754
t.write('-' * 60 + '\n')
697
755
t.write('bzr invoked at %s\n' % format_date(time.time()))
698
t.write(' by %s on %s\n' % (bzrlib.osutils.username(), socket.gethostname()))
756
t.write(' by %s on %s\n' % (bzrlib.osutils.username(), socket.getfqdn()))
699
757
t.write(' arguments: %r\n' % argv)
701
759
starttime = os.times()[4]