| 789 | } |
| 790 | |
| 791 | static struct attr_stack *read_attr_from_index(struct index_state *istate, |
| 792 | const char *path, unsigned flags) |
| 793 | { |
| 794 | struct attr_stack *stack = NULL; |
| 795 | char *buf; |
| 796 | unsigned long size; |
| 797 | int sparse_dir_pos = -1; |
| 798 | |
| 799 | if (!istate) |
| 800 | return NULL; |
| 801 | |
| 802 | /* |
| 803 | * When handling sparse-checkouts, .gitattributes files |
| 804 | * may reside within a sparse directory. We distinguish |
| 805 | * whether a path exists directly in the index or not by |
| 806 | * evaluating if 'pos' is negative. |
| 807 | * If 'pos' is negative, the path is not directly present |
| 808 | * in the index and is likely within a sparse directory. |
| 809 | * For paths not in the index, The absolute value of 'pos' |
| 810 | * minus 1 gives us the position where the path would be |
| 811 | * inserted in lexicographic order within the index. |
| 812 | * We then subtract another 1 from this value |
| 813 | * (sparse_dir_pos = -pos - 2) to find the position of the |
| 814 | * last index entry which is lexicographically smaller than |
| 815 | * the path. This would be the sparse directory containing |
| 816 | * the path. By identifying the sparse directory containing |
| 817 | * the path, we can correctly read the attributes specified |
| 818 | * in the .gitattributes file from the tree object of the |
| 819 | * sparse directory. |
| 820 | */ |
| 821 | if (!path_in_cone_mode_sparse_checkout(path, istate)) { |
| 822 | int pos = index_name_pos_sparse(istate, path, strlen(path)); |
| 823 | |
| 824 | if (pos < 0) |
| 825 | sparse_dir_pos = -pos - 2; |
| 826 | } |
| 827 | |
| 828 | if (sparse_dir_pos >= 0 && |
| 829 | S_ISSPARSEDIR(istate->cache[sparse_dir_pos]->ce_mode) && |
| 830 | !strncmp(istate->cache[sparse_dir_pos]->name, path, ce_namelen(istate->cache[sparse_dir_pos]))) { |
| 831 | const char *relative_path = path + ce_namelen(istate->cache[sparse_dir_pos]); |
| 832 | stack = read_attr_from_blob(istate, &istate->cache[sparse_dir_pos]->oid, relative_path, flags); |
| 833 | } else { |
| 834 | buf = read_blob_data_from_index(istate, path, &size); |
| 835 | if (buf) |
| 836 | stack = read_attr_from_buf(buf, size, path, flags); |
| 837 | } |
| 838 | return stack; |
| 839 | } |
| 840 | |
| 841 | static struct attr_stack *read_attr(struct index_state *istate, |
| 842 | const struct object_id *tree_oid, |
no test coverage detected