]> arthur.barton.de Git - bup.git/blobdiff - cmd-split.py
executable files: don't assume python2.5.
[bup.git] / cmd-split.py
index ed28fc2a7c84fdc98f24abb198e5327c315a943e..f462655a5e128fb95d212f5370f5da96cb8be442 100755 (executable)
@@ -1,7 +1,9 @@
-#!/usr/bin/env python2.5
-import sys, time, re, struct
-import hashsplit, git, options
+#!/usr/bin/env python
+import sys, time, struct
+import hashsplit, git, options, client
 from helpers import *
+from subprocess import PIPE
+
 
 optspec = """
 bup split [-tcb] [-n name] [--bench] [filenames...]
@@ -13,6 +15,9 @@ c,commit   output a commit id
 n,name=    name of backup set to update (if any)
 v,verbose  increase log output (can be used more than once)
 bench      print benchmark timings to stderr
+max-pack-size=  maximum bytes in a single pack
+max-pack-objects=  maximum number of objects in a single pack
+fanout=  maximum number of blobs in a single tree
 """
 o = options.Options('bup split', optspec)
 (opt, flags, extra) = o.parse(sys.argv[1:])
@@ -26,71 +31,29 @@ hashsplit.split_verbosely = opt.verbose
 if opt.verbose >= 2:
     git.verbose = opt.verbose - 1
     opt.bench = 1
+if opt.max_pack_size:
+    hashsplit.max_pack_size = int(opt.max_pack_size)
+if opt.max_pack_objects:
+    hashsplit.max_pack_objects = int(opt.max_pack_objects)
+if opt.fanout:
+    hashsplit.fanout = int(opt.fanout)
+if opt.blobs:
+    hashsplit.fanout = 0
 
 start_time = time.time()
 
-def server_connect(remote):
-    rs = remote.split(':', 1)
-    if len(rs) == 1:
-        (host, dir) = ('NONE', remote)
-        p = subprocess.Popen(['bup', 'server'],
-                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-    else:
-        (host, dir) = rs
-        p = subprocess.Popen(['ssh', host, '--', 'bup', 'server'],
-                             stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-    conn = Conn(p.stdout, p.stdin)
-    dir = re.sub(r'[\r\n]', ' ', dir)
-    conn.write('set-dir %s\n' % dir)
-    conn.check_ok()
-    
-    conn.write('list-indexes\n')
-    cachedir = git.repo('index-cache/%s' % re.sub(r'[^@:\w]', '_',
-                                                  "%s:%s" % (host, dir)))
-    packdir = git.repo('objects/pack')
-    mkdirp(cachedir)
-    all = {}
-    needed = {}
-    for line in linereader(conn):
-        if not line:
-            break
-        all[line] = 1
-        assert(line.find('/') < 0)
-        if (not os.path.exists(os.path.join(cachedir, line)) and
-            not os.path.exists(os.path.join(packdir, line))):
-                needed[line] = 1
-    conn.check_ok()
-                
-    for f in os.listdir(cachedir):
-        if f.endswith('.idx') and not f in all:
-            log('pruning old index: %r\n' % f)
-            os.unlink(os.path.join(cachedir, f))
-            
-    # FIXME this should be pipelined: request multiple indexes at a time, or
-    # we waste lots of network turnarounds.
-    for name in needed.keys():
-        log('requesting %r\n' % name)
-        conn.write('send-index %s\n' % name)
-        n = struct.unpack('!I', conn.read(4))[0]
-        assert(n)
-        log('   expect %d bytes\n' % n)
-        fn = os.path.join(cachedir, name)
-        f = open(fn + '.tmp', 'w')
-        for b in chunkyreader(conn, n):
-            f.write(b)
-        conn.check_ok()
-        f.close()
-        os.rename(fn + '.tmp', fn)
-    return (p, conn, cachedir)
-
+refname = opt.name and 'refs/heads/%s' % opt.name or None
 if opt.remote:
-    (p, conn, cachedir) = server_connect(opt.remote)
-    conn.write('receive-objects\n')
-    w = git.PackWriter_Remote(conn, objcache = git.MultiPackIndex(cachedir))
+    cli = client.Client(opt.remote)
+    oldref = refname and cli.read_ref(refname) or None
+    w = cli.new_packwriter()
 else:
+    cli = None
+    oldref = refname and git.read_ref(refname) or None
     w = git.PackWriter()
     
-(shalist,tree) = hashsplit.split_to_tree(w, hashsplit.autofiles(extra))
+shalist = hashsplit.split_to_shalist(w, hashsplit.autofiles(extra))
+tree = w.new_tree(shalist)
 
 if opt.verbose:
     log('\n')
@@ -102,14 +65,20 @@ if opt.tree:
 if opt.commit or opt.name:
     msg = 'bup split\n\nGenerated by command:\n%r' % sys.argv
     ref = opt.name and ('refs/heads/%s' % opt.name) or None
-    commit = w.new_commit(ref, tree, msg)
+    commit = w.new_commit(oldref, tree, msg)
     if opt.commit:
         print commit.encode('hex')
 
-if opt.remote:
-    w.close()
-    p.stdin.write('quit\n')
-    p.wait()
+w.close()  # must close before we can update the ref
+        
+if opt.name:
+    if cli:
+        cli.update_ref(refname, commit, oldref)
+    else:
+        git.update_ref(refname, commit, oldref)
+
+if cli:
+    cli.close()
 
 secs = time.time() - start_time
 size = hashsplit.total_split