]> arthur.barton.de Git - bup.git/blob - cmd/restore-cmd.py
6066b6545412d697711d7b0f13763eb0c4962afc
[bup.git] / cmd / restore-cmd.py
1 #!/usr/bin/env python
2 import sys, stat, time
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 = last_progress = 0
15
16
17 def verbose1(s):
18     global last_progress
19     if opt.verbose >= 1:
20         print s
21         last_progress = 0
22
23
24 def verbose2(s):
25     global last_progress
26     if opt.verbose >= 2:
27         print s
28         last_progress = 0
29
30
31 def plog(s):
32     global last_progress
33     if opt.quiet:
34         return
35     now = time.time()
36     if now - last_progress > 0.2:
37         progress(s)
38         last_progress = now
39
40
41 def do_node(top, n):
42     global total_restored
43     fullname = n.fullname(stop_at=top)
44     unlink(fullname)
45     if stat.S_ISDIR(n.mode):
46         verbose1('%s/' % fullname)
47         mkdirp(fullname)
48     elif stat.S_ISLNK(n.mode):
49         verbose2('%s@ -> %s' % (fullname, n.readlink()))
50         os.symlink(n.readlink(), fullname)
51     else:
52         verbose2(fullname)
53         outf = open(fullname, 'wb')
54         try:
55             for b in chunkyreader(n.open()):
56                 outf.write(b)
57         finally:
58             outf.close()
59     total_restored += 1
60     plog('Restoring: %d\r' % total_restored)
61     for sub in n:
62         do_node(top, sub)
63
64         
65 handle_ctrl_c()
66
67 o = options.Options('bup restore', optspec)
68 (opt, flags, extra) = o.parse(sys.argv[1:])
69
70 git.check_repo_or_die()
71 top = vfs.RefList(None)
72
73 if not extra:
74     o.fatal('must specify at least one filename to restore')
75     
76 if opt.outdir:
77     mkdirp(opt.outdir)
78     os.chdir(opt.outdir)
79
80 ret = 0
81 for d in extra:
82     path,name = os.path.split(d)
83     try:
84         n = top.lresolve(d)
85     except vfs.NodeError, e:
86         add_error(e)
87         continue
88     isdir = stat.S_ISDIR(n.mode)
89     if not name or name == '.':
90         # trailing slash: extract children to cwd
91         if not isdir:
92             add_error('%r: not a directory' % d)
93         else:
94             for sub in n:
95                 do_node(n, sub)
96     else:
97         # no trailing slash: extract node and its children to cwd
98         do_node(n.parent, n)
99
100 if not opt.quiet:
101     log('Restoring: %d, done.\n' % total_restored)
102
103 if saved_errors:
104     log('WARNING: %d errors encountered while restoring.\n' % len(saved_errors))
105     sys.exit(1)