* A simpler implementation of relative_path * * Get relative path by removing "prefix" from "in". This function * first appears in v1.5.6-1-g044bbbc, and makes git_dir shorter * to increase performance when traversing the path to work_tree. */
| 1044 | * to increase performance when traversing the path to work_tree. |
| 1045 | */ |
| 1046 | const char *remove_leading_path(const char *in, const char *prefix) |
| 1047 | { |
| 1048 | static struct strbuf buf = STRBUF_INIT; |
| 1049 | int i = 0, j = 0; |
| 1050 | |
| 1051 | if (!prefix || !prefix[0]) |
| 1052 | return in; |
| 1053 | while (prefix[i]) { |
| 1054 | if (is_dir_sep(prefix[i])) { |
| 1055 | if (!is_dir_sep(in[j])) |
| 1056 | return in; |
| 1057 | while (is_dir_sep(prefix[i])) |
| 1058 | i++; |
| 1059 | while (is_dir_sep(in[j])) |
| 1060 | j++; |
| 1061 | continue; |
| 1062 | } else if (in[j] != prefix[i]) { |
| 1063 | return in; |
| 1064 | } |
| 1065 | i++; |
| 1066 | j++; |
| 1067 | } |
| 1068 | if ( |
| 1069 | /* "/foo" is a prefix of "/foo" */ |
| 1070 | in[j] && |
| 1071 | /* "/foo" is not a prefix of "/foobar" */ |
| 1072 | !is_dir_sep(prefix[i-1]) && !is_dir_sep(in[j]) |
| 1073 | ) |
| 1074 | return in; |
| 1075 | while (is_dir_sep(in[j])) |
| 1076 | j++; |
| 1077 | |
| 1078 | strbuf_reset(&buf); |
| 1079 | if (!in[j]) |
| 1080 | strbuf_addstr(&buf, "."); |
| 1081 | else |
| 1082 | strbuf_addstr(&buf, in + j); |
| 1083 | return buf.buf; |
| 1084 | } |
| 1085 | |
| 1086 | /* |
| 1087 | * It is okay if dst == src, but they should not overlap otherwise. |
no test coverage detected