]> arthur.barton.de Git - bup.git/blobdiff - cmd/server-cmd.py
rev_list: handle multiple results/ref from remote for custom formats
[bup.git] / cmd / server-cmd.py
index d13abc92935013e8b9ecc9944d31bd577f5b22b3..6fa9a67a96d8ac68dd7f748315cf6003a4999184 100755 (executable)
@@ -5,17 +5,19 @@ exec "$bup_python" "$0" ${1+"$@"}
 """
 # end of bup preamble
 
+from __future__ import absolute_import
 import os, sys, struct, subprocess
 
-from bup import options, git
+from bup import options, git, vfs, vint
 from bup.git import MissingObject
 from bup.helpers import (Conn, debug1, debug2, linereader, lines_until_sentinel,
                          log)
+from bup.repo import LocalRepo
 
 
 suspended_w = None
 dumb_server_mode = False
-
+repo = None
 
 def do_help(conn, junk):
     conn.write('Commands:\n    %s\n' % '\n    '.join(sorted(commands)))
@@ -30,9 +32,15 @@ def _set_mode():
 
 
 def _init_session(reinit_with_new_repopath=None):
+    global repo
     if reinit_with_new_repopath is None and git.repodir:
+        if not repo:
+            repo = LocalRepo()
         return
     git.check_repo_or_die(reinit_with_new_repopath)
+    if repo:
+        repo.close()
+    repo = LocalRepo()
     # OK. we now know the path is a proper repository. Record this path in the
     # environment so that subprocesses inherit it and know where to operate.
     os.environ['BUP_DIR'] = git.repodir
@@ -218,6 +226,7 @@ def rev_list(conn, _):
         if not out:
             break
         conn.write(out)
+    conn.write('\n')
     rv = p.wait()  # not fatal
     if rv:
         msg = 'git rev-list returned error %d' % rv
@@ -225,6 +234,29 @@ def rev_list(conn, _):
         raise GitError(msg)
     conn.ok()
 
+def resolve(conn, args):
+    _init_session()
+    (flags,) = args.split()
+    flags = int(flags)
+    want_meta = bool(flags & 1)
+    follow = bool(flags & 2)
+    have_parent = bool(flags & 4)
+    parent = vfs.read_resolution(conn) if have_parent else None
+    path = vint.read_bvec(conn)
+    if not len(path):
+        raise Exception('Empty resolve path')
+    try:
+        res = list(vfs.resolve(repo, path, parent=parent, want_meta=want_meta,
+                               follow=follow))
+    except vfs.IOError as ex:
+        res = ex
+    if isinstance(res, vfs.IOError):
+        conn.write(b'\0')  # error
+        vfs.write_ioerror(conn, res)
+    else:
+        conn.write(b'\1')  # success
+        vfs.write_resolution(conn, res)
+    conn.ok()
 
 optspec = """
 bup server
@@ -251,7 +283,8 @@ commands = {
     'cat': join,  # apocryphal alias
     'cat-batch' : cat_batch,
     'refs': refs,
-    'rev-list': rev_list
+    'rev-list': rev_list,
+    'resolve': resolve
 }
 
 # FIXME: this protocol is totally lame and not at all future-proof.