diff --git a/dir.c b/dir.c
index 3acac7beb1..6116022ae6 100644
--- a/dir.c
+++ b/dir.c
@@ -337,12 +337,11 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,
  * [2] Only if DO_MATCH_LEADING_PATHSPEC is passed; otherwise, not a match.
  */
 static int match_pathspec_item(struct index_state *istate,
-			       const struct pathspec_item *item, int prefix,
+			       const struct pathspec_item *item,
 			       const char *name, int namelen, unsigned flags)
 {
-	/* name/namelen has prefix cut off by caller */
-	const char *match = item->match + prefix;
-	int matchlen = item->len - prefix;
+	const char *match = item->match;
+	int matchlen = item->len;
 
 	/*
 	 * The normal call pattern is:
@@ -362,19 +361,9 @@ static int match_pathspec_item(struct index_state *istate,
 	 * other words, we do not trust the caller on comparing the
 	 * prefix part when :(icase) is involved. We do exact
 	 * comparison ourselves.
-	 *
-	 * Normally the caller (common_prefix_len() in fact) does
-	 * _exact_ matching on name[-prefix+1..-1] and we do not need
-	 * to check that part. Be defensive and check it anyway, in
-	 * case common_prefix_len is changed, or a new caller is
-	 * introduced that does not use common_prefix_len.
-	 *
-	 * If the penalty turns out too high when prefix is really
-	 * long, maybe change it to
-	 * strncmp(match, name, item->prefix - prefix)
 	 */
 	if (item->prefix && (item->magic & PATHSPEC_ICASE) &&
-	    strncmp(item->match, name - prefix, item->prefix))
+	    strncmp(item->match, name, item->prefix))
 		return 0;
 
 	if (item->attr_match_nr &&
@@ -399,7 +388,7 @@ static int match_pathspec_item(struct index_state *istate,
 
 	if (item->nowildcard_len < item->len &&
 	    !git_fnmatch(item, match, name,
-			 item->nowildcard_len - prefix))
+			 item->nowildcard_len))
 		return MATCHED_FNMATCH;
 
 	/* Perform checks to see if "name" is a leading string of the pathspec */
@@ -414,8 +403,7 @@ static int match_pathspec_item(struct index_state *istate,
 
 		/* name doesn't match up to the first wild character */
 		if (item->nowildcard_len < item->len &&
-		    ps_strncmp(item, match, name,
-			       item->nowildcard_len - prefix))
+		    ps_strncmp(item, match, name, item->nowildcard_len))
 			return 0;
 
 		/*
@@ -488,9 +476,6 @@ static int do_match_pathspec(struct index_state *istate,
 			return 0;
 	}
 
-	name += prefix;
-	namelen -= prefix;
-
 	for (i = ps->nr - 1; i >= 0; i--) {
 		int how;
 
@@ -506,8 +491,8 @@ static int do_match_pathspec(struct index_state *istate,
 		 */
 		if (seen && ps->items[i].magic & PATHSPEC_EXCLUDE)
 			seen[i] = MATCHED_FNMATCH;
-		how = match_pathspec_item(istate, ps->items+i, prefix, name,
-					  namelen, flags);
+		how = match_pathspec_item(istate, ps->items+i,
+					  name, namelen, flags);
 		if (ps->recursive &&
 		    (ps->magic & PATHSPEC_MAXDEPTH) &&
 		    ps->max_depth != -1 &&
diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh
index f63774094f..f70c395e75 100755
--- a/t/t6135-pathspec-with-attrs.sh
+++ b/t/t6135-pathspec-with-attrs.sh
@@ -65,7 +65,8 @@ test_expect_success 'setup .gitattributes' '
 	fileValue label=foo
 	fileWrongLabel label☺
 	EOF
-	git add .gitattributes &&
+	echo fileSetLabel label1 >sub/.gitattributes &&
+	git add .gitattributes sub/.gitattributes &&
 	git commit -m "add attributes"
 '
 
@@ -157,6 +158,7 @@ test_expect_success 'check unspecified attr' '
 	fileC
 	fileNoLabel
 	fileWrongLabel
+	sub/.gitattributes
 	sub/fileA
 	sub/fileAB
 	sub/fileAC
@@ -181,6 +183,7 @@ test_expect_success 'check unspecified attr (2)' '
 	HEAD:fileC
 	HEAD:fileNoLabel
 	HEAD:fileWrongLabel
+	HEAD:sub/.gitattributes
 	HEAD:sub/fileA
 	HEAD:sub/fileAB
 	HEAD:sub/fileAC
@@ -200,6 +203,7 @@ test_expect_success 'check multiple unspecified attr' '
 	fileC
 	fileNoLabel
 	fileWrongLabel
+	sub/.gitattributes
 	sub/fileC
 	sub/fileNoLabel
 	sub/fileWrongLabel
@@ -273,4 +277,22 @@ test_expect_success 'backslash cannot be used as a value' '
 	test_i18ngrep "for value matching" actual
 '
 
+test_expect_success 'reading from .gitattributes in a subdirectory (1)' '
+	git ls-files ":(attr:label1)" >actual &&
+	test_write_lines "sub/fileSetLabel" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'reading from .gitattributes in a subdirectory (2)' '
+	git ls-files ":(attr:label1)sub" >actual &&
+	test_write_lines "sub/fileSetLabel" >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'reading from .gitattributes in a subdirectory (3)' '
+	git ls-files ":(attr:label1)sub/" >actual &&
+	test_write_lines "sub/fileSetLabel" >expect &&
+	test_cmp expect actual
+'
+
 test_done
