diff mbox series

[v3,31/32] blame: emit a better error on 'git blame directory'

Message ID 20210316155829.31242-32-avarab@gmail.com (mailing list archive)
State New, archived
Headers show
Series tree-walk: mostly replace "mode" with "enum object_type" | expand

Commit Message

Ævar Arnfjörð Bjarmason March 16, 2021, 3:58 p.m. UTC
Change an early check for non-blobs in verify_working_tree_path() to
let any such objects pass, and instead die shortly thereafter in the
fake_working_tree_commit() caller's type check.

Now e.g. doing "git blame t" in git.git emits:

    fatal: unsupported file type t

Instead of:

    fatal: no such path 't' in HEAD

The main point of this test is to assert that we're not doing
something uniquely bad when in a conflicted merge. See
cd8ae20195 (git-blame shouldn't crash if run in an unmerged tree,
2007-10-18) and 9aeaab6811 (blame: allow "blame file" in the middle of
a conflicted merge, 2012-09-11) for the bug the t8004 test was
originally meant to address.

But when extending it let's grep out the specific error message for
good measure. Having to change it in the future (e.g. as part of my
parallel series to improve such 'OID does not match type' messages) is
a small price for ensuring it doesn't regress.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 blame.c                         |  8 ++------
 t/t8004-blame-with-conflicts.sh | 21 +++++++++++++++++++++
 2 files changed, 23 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/blame.c b/blame.c
index 9e0543e13d..7da162cd58 100644
--- a/blame.c
+++ b/blame.c
@@ -100,12 +100,8 @@  static void verify_working_tree_path(struct repository *r,
 
 	for (parents = work_tree->parents; parents; parents = parents->next) {
 		const struct object_id *commit_oid = &parents->item->object.oid;
-		struct object_id blob_oid;
-		unsigned short mode;
-		int ret = get_tree_entry_mode(r, commit_oid, path, &blob_oid,
-					      &mode);
-
-		if (!ret && oid_object_info(r, &blob_oid, NULL) == OBJ_BLOB)
+		struct object_id oid;
+		if (!get_tree_entry_path(r, commit_oid, path, &oid))
 			return;
 	}
 
diff --git a/t/t8004-blame-with-conflicts.sh b/t/t8004-blame-with-conflicts.sh
index 35414a5336..5e3dea35a5 100755
--- a/t/t8004-blame-with-conflicts.sh
+++ b/t/t8004-blame-with-conflicts.sh
@@ -73,4 +73,25 @@  test_expect_success 'blame does not crash with conflicted file in stages 1,3' '
 	git blame file1
 '
 
+test_expect_success 'setup second case' '
+	git merge --abort
+'
+
+test_expect_success 'blame on directory/file conflict' '
+	mkdir d &&
+	test_commit second &&
+	test_commit d/file &&
+	test_must_fail git blame d 2>expected &&
+	grep "unsupported file type d" expected &&
+
+	git reset --hard second &&
+	>d &&
+	git add d &&
+	git commit -m"a not-a-dir" &&
+	test_must_fail git merge d/file &&
+
+	test_must_fail git blame d 2>actual &&
+	test_cmp expected actual
+'
+
 test_done