65
import sys, os, time, types, shutil, tempfile, traceback, fnmatch, difflib, os.path
65
import sys, os, random, time, sha, sets, types, re, shutil, tempfile
66
import traceback, socket, fnmatch, difflib
66
68
from sets import Set
67
69
from pprint import pprint
69
71
from glob import glob
70
from inspect import getdoc
73
74
from bzrlib.store import ImmutableStore
74
75
from bzrlib.trace import mutter, note, log_error
75
from bzrlib.errors import bailout, BzrError, BzrCheckError
76
from bzrlib.errors import bailout, BzrError
76
77
from bzrlib.osutils import quotefn, pumpfile, isdir, isfile
77
78
from bzrlib.tree import RevisionTree, EmptyTree, WorkingTree, Tree
78
79
from bzrlib.revision import Revision
200
# TODO: Maybe a 'mv' command that has the combined move/rename
201
# special behaviour of Unix?
203
def cmd_move(source_list, dest):
206
b.move([b.relpath(s) for s in source_list], b.relpath(dest))
210
def cmd_rename(from_name, to_name):
211
"""Change the name of an entry.
213
usage: bzr rename FROM_NAME TO_NAME
216
bzr rename frob.c frobber.c
217
bzr rename src/frob.c lib/frob.c
219
It is an error if the destination name exists.
221
See also the 'move' command, which moves files into a different
222
directory without changing their name.
224
TODO: Some way to rename multiple files without invoking bzr for each
227
b.rename_one(b.relpath(from_name), b.relpath(to_name))
199
def cmd_mv(source_list, dest):
202
b.rename([b.relpath(s) for s in source_list], b.relpath(dest))
232
206
def cmd_renames(dir='.'):
233
207
"""Show list of renamed files.
235
usage: bzr renames [BRANCH]
237
TODO: Option to show renames between two historical versions.
239
TODO: Only show renames under dir, rather than in the whole branch.
209
usage: bzr renames [BRANCH]
211
TODO: Option to show renames between two historical versions.
213
TODO: Only show renames under dir, rather than in the whole branch.
242
216
old_inv = b.basis_tree().inventory
243
217
new_inv = b.read_working_inventory()
267
241
def cmd_file_id(filename):
268
"""Print file_id of a particular file or directory.
270
usage: bzr file-id FILE
272
The file_id is assigned when the file is first added and remains the
273
same through all revisions where the file exists, even when it is
276
242
b = Branch(filename)
277
243
i = b.inventory.path2id(b.relpath(filename))
279
bailout("%r is not a versioned file" % filename)
245
bailout("%s is not a versioned file" % filename)
284
def cmd_file_id_path(filename):
285
"""Print path of file_ids to a file or directory.
287
usage: bzr file-id-path FILE
289
This prints one line for each directory down to the target,
290
starting at the branch root."""
293
fid = inv.path2id(b.relpath(filename))
295
bailout("%r is not a versioned file" % filename)
296
for fip in inv.get_idpath(fid):
250
def cmd_find_filename(fileid):
251
n = find_filename(fileid)
253
bailout("%s is not a live file id" % fileid)
300
258
def cmd_revision_history():
328
286
Branch('.', init=True)
331
def cmd_diff(revision=None, file_list=None):
289
def cmd_diff(revision=None):
332
290
"""bzr diff: Show differences in working tree.
334
usage: bzr diff [-r REV] [FILE...]
337
Show changes since REV, rather than predecessor.
339
If files are listed, only the changes in those files are listed.
340
Otherwise, all changes for the tree are listed.
342
TODO: Given two revision arguments, show the difference between them.
344
TODO: Allow diff across branches.
346
TODO: Option to use external diff command; could be GNU diff, wdiff,
349
TODO: If a directory is given, diff everything under that.
351
TODO: Selected-file diff is inefficient and doesn't show you deleted files.
292
usage: bzr diff [-r REV]
295
Show changes since REV, rather than predecessor.
297
TODO: Given two revision arguments, show the difference between them.
299
TODO: Allow diff across branches.
301
TODO: Option to use external diff command; could be GNU diff, wdiff,
304
TODO: Diff selected files.
354
307
## TODO: Shouldn't be in the cmd function.
361
314
old_tree = b.revision_tree(b.lookup_revision(revision))
363
316
new_tree = b.working_tree()
317
old_inv = old_tree.inventory
318
new_inv = new_tree.inventory
365
320
# TODO: Options to control putting on a prefix or suffix, perhaps as a format string
375
330
# be usefully made into a much faster special case.
377
332
# TODO: Better to return them in sorted order I think.
379
# FIXME: If given a file list, compare only those files rather
380
# than comparing everything and then throwing stuff away.
382
334
for file_state, fid, old_name, new_name, kind in bzrlib.diff_trees(old_tree, new_tree):
384
if file_list and new_name not in file_list:
387
337
# Don't show this by default; maybe do it if an option is passed
388
338
# idlabel = ' {%s}' % fid
437
387
def cmd_deleted(show_ids=False):
438
388
"""List files deleted in the working tree.
440
TODO: Show files deleted since a previous revision, or between two revisions.
390
TODO: Show files deleted since a previous revision, or between two revisions.
443
393
old = b.basis_tree()
467
417
def cmd_load_inventory():
468
"""Load inventory for timing purposes"""
469
Branch('.').basis_tree().inventory
472
def cmd_dump_inventory():
473
Branch('.').read_working_inventory().write_xml(sys.stdout)
418
inv = Branch('.').basis_tree().inventory
476
422
def cmd_dump_new_inventory():
488
434
import bzrlib.newinventory
489
435
inv = Branch('.').basis_tree().inventory
490
436
bzrlib.newinventory.write_slacker_inventory(inv, sys.stdout)
494
def cmd_dump_text_inventory():
495
import bzrlib.textinv
496
inv = Branch('.').basis_tree().inventory
497
bzrlib.textinv.write_text_inventory(inv, sys.stdout)
500
def cmd_load_text_inventory():
501
import bzrlib.textinv
502
inv = bzrlib.textinv.read_text_inventory(sys.stdin)
503
print 'loaded %d entries' % len(inv)
507
440
def cmd_root(filename=None):
486
def cmd_ignored(verbose=True):
554
487
"""List ignored files and the patterns that matched them.
556
489
tree = Branch('.').working_tree()
557
for path, file_class, kind, file_id in tree.list_files():
490
for path, file_class, kind, id in tree.list_files():
558
491
if file_class != 'I':
560
493
## XXX: Slightly inefficient since this was already calculated
580
513
t = b.revision_tree(rh)
583
def cmd_cat(revision, filename):
584
"""Print file to stdout."""
586
b.print_file(b.relpath(filename), int(revision))
589
518
######################################################################
604
533
def cmd_commit(message=None, verbose=False):
605
534
"""Commit changes to a new revision.
608
Description of changes in this revision; free form text.
609
It is recommended that the first line be a single-sentence
612
Show status of changed files,
614
TODO: Commit only selected files.
616
TODO: Run hooks on tree to-be-committed, and after commit.
618
TODO: Strict commit that fails if there are unknown or deleted files.
537
Description of changes in this revision; free form text.
538
It is recommended that the first line be a single-sentence
541
Show status of changed files,
543
TODO: Commit only selected files.
545
TODO: Run hooks on tree to-be-committed, and after commit.
547
TODO: Strict commit that fails if there are unknown or deleted files.
622
551
bailout("please specify a commit message")
626
555
def cmd_check(dir='.'):
627
556
"""check: Consistency check of branch history.
629
usage: bzr check [-v] [BRANCH]
632
--verbose, -v Show progress of checking.
634
This command checks various invariants about the branch storage to
635
detect data corruption or bzr bugs.
558
usage: bzr check [-v] [BRANCH]
561
--verbose, -v Show progress of checking.
563
This command checks various invariants about the branch storage to
564
detect data corruption or bzr bugs.
637
566
import bzrlib.check
638
567
bzrlib.check.check(Branch(dir, find_root=False))
664
593
def cmd_gen_revision_id():
665
595
print bzrlib.branch._gen_revision_id(time.time())
598
def cmd_selftest(verbose=False):
669
599
"""Run internal test suite"""
670
600
## -v, if present, is seen by doctest; the argument is just here
671
601
## so our parser doesn't complain
786
715
'add': ['file+'],
790
718
'export': ['revno', 'dest'],
791
719
'file-id': ['filename'],
792
'file-id-path': ['filename'],
793
720
'get-file-text': ['text_id'],
794
721
'get-inventory': ['inventory_id'],
795
722
'get-revision': ['revision_id'],
800
727
'lookup-revision': ['revno'],
801
'move': ['source$', 'dest'],
728
'mv': ['source$', 'dest'],
802
729
'relpath': ['filename'],
803
730
'remove': ['file+'],
804
'rename': ['from_name', 'to_name'],
805
731
'renames': ['dir?'],
806
732
'root': ['filename?'],
895
821
if ap[-1] == '?':
897
823
argdict[argname] = args.pop(0)
898
elif ap[-1] == '*': # all remaining arguments
900
argdict[argname + '_list'] = args[:]
903
argdict[argname + '_list'] = None
904
826
elif ap[-1] == '+':
906
828
bailout("command %r needs one or more %s"
975
897
bailout("option %r is not allowed for command %r"
978
# TODO: give an error if there are any mandatory options which are
979
# not specified? Or maybe there shouldn't be any "mandatory
980
# options" (it is an oxymoron)
982
900
# mix arguments and options into one dictionary
983
901
cmdargs = _match_args(cmd, args)
984
902
for k, v in opts.items():
1019
935
if len(e.args) > 1:
1020
936
for h in e.args[1]:
1021
937
log_error(' ' + h + '\n')
1022
traceback.print_exc(None, bzrlib.trace._tracefile)
1023
log_error('(see $HOME/.bzr.log for debug information)\n')
1025
939
except Exception, e:
1026
940
log_error('bzr: exception: %s\n' % e)
1027
log_error('(see $HOME/.bzr.log for debug information)\n')
941
log_error(' see .bzr.log for details\n')
1028
942
traceback.print_exc(None, bzrlib.trace._tracefile)
1029
## traceback.print_exc(None, sys.stderr)
943
traceback.print_exc(None, sys.stderr)
1032
## TODO: Trap AssertionError
1034
# TODO: Maybe nicer handling of IOError especially for broken pipe.
946
# TODO: Maybe nicer handling of IOError?