-#!/usr/bin/env bash
-
-set -eo pipefail
-
-# Usage: subtree-hash ROOT_HASH [SUBDIR ...]
-
-subtree_hash()
-{
- root_hash="$1"
- if test "$#" -eq 1; then
- echo $root_hash
- else
- subdir="$2"
- subtree_info="$(git ls-tree "$root_hash" | grep -E " $subdir\$")" || true
- if test "$(echo "$subtree_info" | wc -l)" -ne 1; then
- echo "Found more than one matching line in subtree $root_hash" 1>&2
- return 1
- fi
-
- subtree_hash="$(echo "$subtree_info" | cut -d' ' -f 3 | cut -d$'\t' -f 1)" || true
- if test -z "$subtree_hash"; then
- echo "Unable to find subtree hash in git output: $subtree_info" 1>&2
- return 1
- fi
-
- shift 2
- subtree_hash "$subtree_hash" "$@"
- fi
-}
-
-subtree_hash "$@"
+#!/bin/sh
+"""": # -*-python-*-
+bup_python="$(dirname "$0")/../cmd/bup-python" || exit $?
+exec "$bup_python" "$0" ${1+"$@"}
+"""
+# end of bup preamble
+
+from __future__ import absolute_import, print_function
+import sys
+
+from bup.compat import argv_bytes
+from bup.helpers import handle_ctrl_c, readpipe
+from bup.io import byte_stream
+from bup import options
+
+
+optspec = """
+subtree-hash ROOT_HASH [PATH_ITEM...]
+--
+"""
+
+handle_ctrl_c()
+
+o = options.Options(optspec)
+(opt, flags, extra) = o.parse(sys.argv[1:])
+
+if len(extra) < 1:
+ o.fatal('must specify a root hash')
+
+tree_hash = argv_bytes(extra[0])
+path = [argv_bytes(x) for x in extra[1:]]
+
+while path:
+ target_name = path[0]
+ subtree_items = readpipe([b'git', b'ls-tree', b'-z', tree_hash])
+ target_hash = None
+ for entry in subtree_items.split(b'\0'):
+ if not entry:
+ break
+ info, name = entry.split(b'\t', 1)
+ if name == target_name:
+ _, _, target_hash = info.split(b' ')
+ break
+ if not target_hash:
+ print("Can't find %r in %s" % (target_name, tree_hash.decode('ascii')),
+ file=sys.stderr)
+ break
+ tree_hash = target_hash
+ path = path[1:]
+
+if path:
+ sys.exit(1)
+
+sys.stdout.flush()
+out = byte_stream(sys.stdout)
+out.write(tree_hash + b'\n')