]> arthur.barton.de Git - bup.git/blobdiff - cmd/restore-cmd.py
Add support for "bup restore --exclude-rx <pattern> ...".
[bup.git] / cmd / restore-cmd.py
index 43209b3a3112d563e35c6c7440bac2076306c5ba..124578e42685cb65a3dab622750850121060b9ef 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-import errno, sys, stat
+import errno, sys, stat, re
 from bup import options, git, metadata, vfs
 from bup.helpers import *
 
@@ -8,6 +8,7 @@ bup restore [-C outdir] </branch/revision/path/to/dir ...>
 --
 C,outdir=   change to given outdir before extracting files
 numeric-ids restore numeric IDs (user, group, etc.) rather than names
+exclude-rx= skip paths that match the unanchored regular expression
 v,verbose   increase log output (can be used more than once)
 q,quiet     don't show progress meter
 """
@@ -31,6 +32,14 @@ def plog(s):
     qprogress(s)
 
 
+def valid_restore_path(path):
+    path = os.path.normpath(path)
+    if path.startswith('/'):
+        path = path[1:]
+    if '/' in path:
+        return True
+
+
 def print_info(n, fullname):
     if stat.S_ISDIR(n.mode):
         verbose1('%s/' % fullname)
@@ -179,6 +188,12 @@ def do_node(top, n, meta=None):
     meta_stream = None
     try:
         fullname = n.fullname(stop_at=top)
+        # Match behavior of index --exclude-rx with respect to paths.
+        exclude_candidate = '/' + fullname
+        if(stat.S_ISDIR(n.mode)):
+            exclude_candidate += '/'
+        if should_rx_exclude_path(exclude_candidate, exclude_rxs):
+            return
         # If this is a directory, its metadata is the first entry in
         # any .bupm file inside the directory.  Get it.
         if(stat.S_ISDIR(n.mode)):
@@ -214,6 +229,7 @@ def do_node(top, n, meta=None):
         if meta_stream:
             meta_stream.close()
 
+
 handle_ctrl_c()
 
 o = options.Options(optspec)
@@ -225,12 +241,17 @@ top = vfs.RefList(None)
 if not extra:
     o.fatal('must specify at least one filename to restore')
     
+exclude_rxs = parse_rx_excludes(flags, o.fatal)
+
 if opt.outdir:
     mkdirp(opt.outdir)
     os.chdir(opt.outdir)
 
 ret = 0
 for d in extra:
+    if not valid_restore_path(d):
+        add_error("ERROR: path %r doesn't include a branch and revision" % d)
+        continue
     path,name = os.path.split(d)
     try:
         n = top.lresolve(d)