]> arthur.barton.de Git - bup.git/commitdiff
subtree-hash: handle non-ASCII path chars 0.27-rc2
authorRob Browning <rlb@defaultvalue.org>
Fri, 13 Mar 2015 02:41:50 +0000 (21:41 -0500)
committerRob Browning <rlb@defaultvalue.org>
Fri, 13 Mar 2015 03:06:22 +0000 (22:06 -0500)
Pass "-z" to git ls-files to turn off git's core.quotepath, so we can
handle non-ASCII path characters directly, and rewrite the code in
python to make that easier.

Thanks to Jiří Martínek for reporting the issue -- that
test-redundant-saves.sh would fail when there was a "ý" character in the
source tree path.

Signed-off-by: Rob Browning <rlb@defaultvalue.org>
Tested-by: Rob Browning <rlb@defaultvalue.org>
t/subtree-hash

index e85b37fff5ffd2382fb5ec0e9f359a5fb6dc960c..94cd3b36d1f7e77c59a57fd344dbd1fd79132b53 100755 (executable)
@@ -1,29 +1,34 @@
-#!/usr/bin/env bash
+#!/usr/bin/env python
 
-# Usage: subtree-hash ROOT_HASH [SUBDIR ...]
+from subprocess import check_output
+import argparse
+import sys
 
-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 "Didn't find just one matching line in subtree $root_hash" 1>&2
-            return 1
-        fi
+parser = argparse.ArgumentParser()
+parser.add_argument("ROOT_HASH", help="root tree for the search")
+parser.add_argument("PATH_ITEM", help="path component", nargs='*')
+opts = parser.parse_args()
+tree_hash = opts.ROOT_HASH
+path = opts.PATH_ITEM
 
-        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
+while path:
+    target_name = path[0]
+    subtree_items = check_output(['git', 'ls-tree', '-z', tree_hash])
+    target_hash = None
+    for entry in subtree_items.split('\0'):
+        if not entry:
+            break
+        info, name = entry.split('\t', 1)
+        if name == target_name:
+            _, _, target_hash = info.split(' ')
+            break
+    if not target_hash:
+        print >> sys.stderr, "Can't find %r in %s" % (target_name, tree_hash)
+        break
+    tree_hash = target_hash
+    path = path[1:]
 
-        shift 2 || exit $?
-        subtree_hash "$subtree_hash" "$@" || exit $?
-    fi
-}
+if path:
+    sys.exit(1)
 
-subtree_hash "$@"
+print tree_hash