]> arthur.barton.de Git - bup.git/blob - cmd/cat-file-cmd.py
cleanup-mounts-under: Don't fail when /proc/mounts isn't readable
[bup.git] / cmd / cat-file-cmd.py
1 #!/usr/bin/env python
2 import sys, stat
3 from bup import options, git, vfs
4 from bup.helpers import *
5
6 optspec = """
7 bup cat-file [--meta|--bupm] /branch/revision/[path]
8 --
9 meta        print the target's metadata entry (decoded then reencoded) to stdout
10 bupm        print the target directory's .bupm file directly to stdout
11 """
12
13 handle_ctrl_c()
14
15 o = options.Options(optspec)
16 (opt, flags, extra) = o.parse(sys.argv[1:])
17
18 git.check_repo_or_die()
19 top = vfs.RefList(None)
20
21 if not extra:
22     o.fatal('must specify a target')
23 if len(extra) > 1:
24     o.fatal('only one target file allowed')
25 if opt.bupm and opt.meta:
26     o.fatal('--meta and --bupm are incompatible')
27     
28 target = extra[0]
29
30 if not re.match(r'/*[^/]+/[^/]+', target):
31     o.fatal("path %r doesn't include a branch and revision" % target)
32
33 try:
34     n = top.lresolve(target)
35 except vfs.NodeError, e:
36     o.fatal(e)
37
38 if isinstance(n, vfs.FakeSymlink):
39     # Source is actually /foo/what, i.e. a top-level commit
40     # like /foo/latest, which is a symlink to ../.commit/SHA.
41     # So dereference it.
42     target = n.dereference()
43
44 if opt.bupm:
45     if not stat.S_ISDIR(n.mode):
46         o.fatal('%r is not a directory' % target)
47     mfile = n.metadata_file() # VFS file -- cannot close().
48     if mfile:
49         meta_stream = mfile.open()
50         sys.stdout.write(meta_stream.read())
51 elif opt.meta:
52     sys.stdout.write(n.metadata().encode())
53 else:
54     if stat.S_ISREG(n.mode):
55         for b in chunkyreader(n.open()):
56             sys.stdout.write(b)
57     else:
58         o.fatal('%r is not a plain file' % target)
59
60 if saved_errors:
61     log('warning: %d errors encountered\n' % len(saved_errors))
62     sys.exit(1)