| 2809 | } |
| 2810 | |
| 2811 | static int treat_leading_path(struct dir_struct *dir, |
| 2812 | struct index_state *istate, |
| 2813 | const char *path, int len, |
| 2814 | const struct pathspec *pathspec) |
| 2815 | { |
| 2816 | struct strbuf sb = STRBUF_INIT; |
| 2817 | struct strbuf subdir = STRBUF_INIT; |
| 2818 | int prevlen, baselen; |
| 2819 | const char *cp; |
| 2820 | struct cached_dir cdir; |
| 2821 | enum path_treatment state = path_none; |
| 2822 | |
| 2823 | /* |
| 2824 | * For each directory component of path, we are going to check whether |
| 2825 | * that path is relevant given the pathspec. For example, if path is |
| 2826 | * foo/bar/baz/ |
| 2827 | * then we will ask treat_path() whether we should go into foo, then |
| 2828 | * whether we should go into bar, then whether baz is relevant. |
| 2829 | * Checking each is important because e.g. if path is |
| 2830 | * .git/info/ |
| 2831 | * then we need to check .git to know we shouldn't traverse it. |
| 2832 | * If the return from treat_path() is: |
| 2833 | * * path_none, for any path, we return false. |
| 2834 | * * path_recurse, for all path components, we return true |
| 2835 | * * <anything else> for some intermediate component, we make sure |
| 2836 | * to add that path to the relevant list but return false |
| 2837 | * signifying that we shouldn't recurse into it. |
| 2838 | */ |
| 2839 | |
| 2840 | while (len && path[len - 1] == '/') |
| 2841 | len--; |
| 2842 | if (!len) |
| 2843 | return 1; |
| 2844 | |
| 2845 | memset(&cdir, 0, sizeof(cdir)); |
| 2846 | cdir.d_type = DT_DIR; |
| 2847 | baselen = 0; |
| 2848 | prevlen = 0; |
| 2849 | while (1) { |
| 2850 | prevlen = baselen + !!baselen; |
| 2851 | cp = path + prevlen; |
| 2852 | cp = memchr(cp, '/', path + len - cp); |
| 2853 | if (!cp) |
| 2854 | baselen = len; |
| 2855 | else |
| 2856 | baselen = cp - path; |
| 2857 | strbuf_reset(&sb); |
| 2858 | strbuf_add(&sb, path, baselen); |
| 2859 | if (!is_directory(sb.buf)) |
| 2860 | break; |
| 2861 | strbuf_reset(&sb); |
| 2862 | strbuf_add(&sb, path, prevlen); |
| 2863 | strbuf_reset(&subdir); |
| 2864 | strbuf_add(&subdir, path+prevlen, baselen-prevlen); |
| 2865 | cdir.d_name = subdir.buf; |
| 2866 | state = treat_path(dir, NULL, &cdir, istate, &sb, prevlen, pathspec); |
| 2867 | |
| 2868 | if (state != path_recurse) |
no test coverage detected