]> arthur.barton.de Git - bup.git/blob - cmd/restore-cmd.py
Merge branch 'bl/bloomcheck' into ap/cleanups
[bup.git] / cmd / restore-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 restore [-C outdir] </branch/revision/path/to/dir ...>
8 --
9 C,outdir=  change to given outdir before extracting files
10 v,verbose  increase log output (can be used more than once)
11 q,quiet    don't show progress meter
12 """
13
14 total_restored = 0
15
16
17 def verbose1(s):
18     if opt.verbose >= 1:
19         print s
20
21
22 def verbose2(s):
23     if opt.verbose >= 2:
24         print s
25
26
27 def plog(s):
28     if opt.quiet:
29         return
30     qprogress(s)
31
32
33 def do_node(top, n):
34     global total_restored
35     fullname = n.fullname(stop_at=top)
36     unlink(fullname)
37     if stat.S_ISDIR(n.mode):
38         verbose1('%s/' % fullname)
39         mkdirp(fullname)
40     elif stat.S_ISLNK(n.mode):
41         verbose2('%s@ -> %s' % (fullname, n.readlink()))
42         os.symlink(n.readlink(), fullname)
43     else:
44         verbose2(fullname)
45         outf = open(fullname, 'wb')
46         try:
47             for b in chunkyreader(n.open()):
48                 outf.write(b)
49         finally:
50             outf.close()
51     total_restored += 1
52     plog('Restoring: %d\r' % total_restored)
53     for sub in n:
54         do_node(top, sub)
55
56         
57 handle_ctrl_c()
58
59 o = options.Options(optspec)
60 (opt, flags, extra) = o.parse(sys.argv[1:])
61
62 git.check_repo_or_die()
63 top = vfs.RefList(None)
64
65 if not extra:
66     o.fatal('must specify at least one filename to restore')
67     
68 if opt.outdir:
69     mkdirp(opt.outdir)
70     os.chdir(opt.outdir)
71
72 ret = 0
73 for d in extra:
74     path,name = os.path.split(d)
75     try:
76         n = top.lresolve(d)
77     except vfs.NodeError, e:
78         add_error(e)
79         continue
80     isdir = stat.S_ISDIR(n.mode)
81     if not name or name == '.':
82         # trailing slash: extract children to cwd
83         if not isdir:
84             add_error('%r: not a directory' % d)
85         else:
86             for sub in n:
87                 do_node(n, sub)
88     else:
89         # no trailing slash: extract node and its children to cwd
90         do_node(n.parent, n)
91
92 if not opt.quiet:
93     progress('Restoring: %d, done.\n' % total_restored)
94
95 if saved_errors:
96     log('WARNING: %d errors encountered while restoring.\n' % len(saved_errors))
97     sys.exit(1)