]> arthur.barton.de Git - bup.git/commitdiff
Initial version of 'bup save'.
authorAvery Pennarun <apenwarr@gmail.com>
Fri, 1 Jan 2010 23:15:12 +0000 (18:15 -0500)
committerAvery Pennarun <apenwarr@gmail.com>
Fri, 1 Jan 2010 23:15:12 +0000 (18:15 -0500)
Saves a complete tree by recursively iterating into subdirs, and splits
large files into chunks using the same algorithm as 'bup split'.

Currently no support for special files (symlinks etc), and it generates the
resulting git tree incorrectly (by just turning / into _ in filenames).

.gitignore
Makefile
cmd-save.py [new file with mode: 0755]
cmd-split.py
hashsplit.py

index 7b336d5051d0e6939c2fd5bfb554cd142ac80520..81866ebcd3ac0e0e08f95d664ec04589346c3cc0 100644 (file)
@@ -1,6 +1,7 @@
 bup
 bup-split
 bup-join
+bup-save
 randomgen
 *.o
 *.so
index 8c55b26a11525ed8eb181958f3aad5b89a9ba416..a84c41f8b783298f17642fc482ac7dfbf30cfbc4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CFLAGS=-Wall -g -O2 -Werror -I/usr/include/python2.5 -g -fPIC
 
 default: all
 
-all: bup-split bup-join bup randomgen chashsplit.so
+all: bup-split bup-join bup-save bup randomgen chashsplit.so
 
 randomgen: randomgen.o
 
@@ -46,6 +46,6 @@ bup-%: cmd-%.sh
        gcc -c -o $@ $^ $(CPPFLAGS) $(CFLAGS)
 
 clean:
-       rm -f *.o *.so *~ .*~ *.pyc \
-               bup bup-split bup-join randomgen \
+       rm -f *.o *.so *~ .*~ *.pyc */*.pyc */*~ \
+               bup bup-split bup-join bup-save randomgen \
                out[12] tags[12]
diff --git a/cmd-save.py b/cmd-save.py
new file mode 100755 (executable)
index 0000000..8b32e5e
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+import sys, re, errno
+import hashsplit, git, options
+from helpers import *
+
+saved_errors = []
+
+def add_error(e):
+    saved_errors.append(e)
+    log('%s\n' % e)
+
+
+def direxpand(names):
+    for n in names:
+        log('%s\n' % n)
+        try:
+            for sub in os.listdir(n):
+                subfull = os.path.join(n, sub)
+                for sub2 in direxpand([subfull]):
+                    yield sub2
+        except OSError, e:
+            if e.errno == errno.ENOTDIR:
+                yield n
+            elif e.errno in [errno.ENOENT, errno.EPERM, errno.EACCES]:
+                add_error(e)
+            else:
+                raise
+
+
+optspec = """
+bup save [-tc] [-n name] <filenames...>
+--
+t,tree     output a tree id
+c,commit   output a commit id
+n,name=    name of backup set to update (if any)
+"""
+o = options.Options('bup save', optspec)
+(opt, flags, extra) = o.parse(sys.argv[1:])
+
+if not (opt.tree or opt.commit or opt.name):
+    log("bup save: use one or more of -t, -c, -n\n")
+    o.usage()
+
+shalist = []
+for fn in direxpand(extra):
+    try:
+        # FIXME: symlinks etc.
+        f = open(fn)
+    except IOError, e:
+        add_error(e)
+        continue
+    except OSError, e:
+        add_error(e)
+        continue
+    (mode, id) = hashsplit.split_to_blob_or_tree([f])
+    shalist.append((mode, re.sub(r'/', '_', fn), id))
+tree = git.gen_tree(shalist)
+if opt.tree:
+    print tree
+if opt.commit or opt.name:
+    msg = 'Generated by command:\n%r' % sys.argv
+    ref = opt.name and ('refs/heads/%s' % opt.name) or None
+    commit = git.gen_commit_easy(ref, tree, msg)
+    if opt.commit:
+        print commit
+
+if saved_errors:
+    log('WARNING: %d errors encountered while saving.\n' % len(saved_errors))
index 205c3f33a6379a931724a3c5f8050522431db691..096ecf67b2f5e3773bb9178fe6541bd82bfa1614 100755 (executable)
@@ -4,7 +4,7 @@ import hashsplit, git, options
 from helpers import *
 
 optspec = """
-bup split [-t] [filenames...]
+bup split [-tcb] [-n name] [--bench] [filenames...]
 --
 b,blobs    output a series of blob ids
 t,tree     output a tree id
index 76bc444655f93f837a52055688710706c8406928..eb8139529a1be6a3ffb8813861d453930f55159f 100644 (file)
@@ -1,5 +1,6 @@
 import sys
 import git, chashsplit
+from helpers import *
 
 BLOB_LWM = 8192*2
 BLOB_MAX = BLOB_LWM*2
@@ -88,7 +89,7 @@ def hashsplit_iter(files):
           
         nv = (ofs + buf.used())/1000000
         if nv != lv:
-            log('%d\t' % nv)
+            #log('%d\t' % nv)
             lv = nv
 
 
@@ -110,3 +111,13 @@ def split_to_tree(files):
         shalist.append(('100644', 'bup.chunk.%016x' % cn, sha))
     tree = git.gen_tree(shalist)
     return (shalist, tree)
+
+
+def split_to_blob_or_tree(files):
+    (shalist, tree) = split_to_tree(files)
+    if len(shalist) == 1:
+        return (shalist[0][0], shalist[0][2])
+    elif len(shalist) == 0:
+        return ('100644', git.hash_blob(''))
+    else:
+        return ('040000', tree)