3 from bup import options, git, metadata, vfs
4 from bup.helpers import *
7 bup restore [-C outdir] </branch/revision/path/to/dir ...>
9 C,outdir= change to given outdir before extracting files
10 numeric-ids restore numeric IDs (user, group, etc.) rather than names
11 v,verbose increase log output (can be used more than once)
12 q,quiet don't show progress meter
34 def print_info(n, fullname):
35 if stat.S_ISDIR(n.mode):
36 verbose1('%s/' % fullname)
37 elif stat.S_ISLNK(n.mode):
38 verbose2('%s@ -> %s' % (fullname, n.readlink()))
43 def create_path(n, fullname, meta):
45 meta.create_path(fullname)
47 # These fallbacks are important -- meta could be null if, for
48 # example, save created a "fake" item, i.e. a new strip/graft
49 # path element, etc. You can find cases like that by
50 # searching for "Metadata()".
52 if stat.S_ISDIR(n.mode):
54 elif stat.S_ISLNK(n.mode):
55 os.symlink(n.readlink(), fullname)
58 def do_node(top, n, meta=None):
59 # meta will be None for dirs, and when there is no .bupm (i.e. no metadata)
60 global total_restored, opt
63 fullname = n.fullname(stop_at=top)
64 # If this is a directory, its metadata is the first entry in
65 # any .bupm file inside the directory. Get it.
66 if(stat.S_ISDIR(n.mode)):
67 mfile = n.metadata_file() # VFS file -- cannot close().
69 meta_stream = mfile.open()
70 meta = metadata.Metadata.read(meta_stream)
71 print_info(n, fullname)
72 create_path(n, fullname, meta)
74 # Write content if appropriate (only regular files have content).
77 plain_file = stat.S_ISREG(meta.mode)
79 plain_file = stat.S_ISREG(n.mode)
82 outf = open(fullname, 'wb')
84 for b in chunkyreader(n.open()):
90 plog('Restoring: %d\r' % total_restored)
93 # Don't get metadata if this is a dir -- handled in sub do_node().
94 if meta_stream and not stat.S_ISDIR(sub.mode):
95 m = metadata.Metadata.read(meta_stream)
98 meta.apply_to_path(fullname,
99 restore_numeric_ids=opt.numeric_ids)
106 o = options.Options(optspec)
107 (opt, flags, extra) = o.parse(sys.argv[1:])
109 git.check_repo_or_die()
110 top = vfs.RefList(None)
113 o.fatal('must specify at least one filename to restore')
121 path,name = os.path.split(d)
124 except vfs.NodeError, e:
127 isdir = stat.S_ISDIR(n.mode)
128 if not name or name == '.':
129 # trailing slash: extract children to cwd
131 add_error('%r: not a directory' % d)
136 # no trailing slash: extract node and its children to cwd
140 progress('Restoring: %d, done.\n' % total_restored)
143 log('WARNING: %d errors encountered while restoring.\n' % len(saved_errors))