Diff options
-rw-r--r--source/ui-tree.c3
-rwxr-xr-xtests/t0104-tree.sh27
2 files changed, 29 insertions, 1 deletion
diff --git a/source/ui-tree.c b/source/ui-tree.c
index 95ff337..43de1bf 100644
--- a/source/ui-tree.c
+++ b/source/ui-tree.c
@@ -254,7 +254,7 @@ static void print_dir_chain(const struct object_id *oid, char *name, char *rev,
tree = lookup_tree(the_repository, &child.oid);
if (!tree)
- return;
+ break;
free(child.name);
child.name = NULL;
@@ -270,6 +270,7 @@ static void print_dir_chain(const struct object_id *oid, char *name, char *rev,
name = child.name;
}
+ free(child.name);
strbuf_setlen(fullpath, initial_length);
}
diff --git a/tests/t0104-tree.sh b/tests/t0104-tree.sh
index 41134a4..0ed98a6 100755
--- a/tests/t0104-tree.sh
+++ b/tests/t0104-tree.sh
@@ -198,6 +198,33 @@ test_expect_success 'a long directory chain ends on a link' '
! grep " / </td>" tmp
'
+# Git holds one object per id, as the type it was first looked up as, so a
+# folder the commit also names as its parent cannot be read as a tree and the
+# chain stops on it. The rest of the row still belongs to the first folder.
+test_expect_success 'a broken chain keeps the row links on the first folder' '
+ test_create_repo repos/cut &&
+ (
+ cd repos/cut &&
+ mkdir -p a/b &&
+ echo x >a/b/file &&
+ git add a &&
+ git commit -m base &&
+ odd=$(printf "tree %s\\nparent %s\\nauthor A <a@x> 1700000000 +0000\\ncommitter A <a@x> 1700000000 +0000\\n\\nodd\\n" \
+ $(git rev-parse HEAD^{tree}) $(git rev-parse HEAD:a/b) |
+ git hash-object -t commit -w --stdin --literally) &&
+ git update-ref refs/heads/odd $odd
+ ) &&
+ {
+ echo "virtual-root=/" &&
+ echo "cache-size=0" &&
+ echo "repo.url=cut" &&
+ echo "repo.path=$PWD/repos/cut/.git"
+ } >cutrc &&
+ CGIT_CONFIG="$PWD/cutrc" QUERY_STRING="url=cut/tree/&h=odd" cgit >tmp &&
+ grep ">b</a></td>" tmp &&
+ grep "href=./cut/log/a?h=odd.>log</a>" tmp
+'
+
test_expect_success 'a binary file in the tree shows as a hex dump' '
test_create_repo repos/bin &&
(