92
const char *elt)
93
{
94
unsigned magic = 0, short_magic = 0;
95
- const char *copyfrom = elt;
95
+ const char *copyfrom = elt, *long_magic_end = NULL;
96
char *match;
97
- int i;
97
+ int i, pathspec_prefix = -1;
98
99
if (elt[0] != ':') {
100
; /* nothing to do */
112
nextat = copyfrom + len;
113
if (!len)
114
continue;
115
- for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++)
115
+ for (i = 0; i < ARRAY_SIZE(pathspec_magic); i++) {
116
if (strlen(pathspec_magic[i].name) == len &&
117
!strncmp(pathspec_magic[i].name, copyfrom, len)) {
118
magic |= pathspec_magic[i].bit;
119
break;
120
}
121
+ if (!prefixcmp(copyfrom, "prefix:")) {
122
+ char *endptr;
123
+ pathspec_prefix = strtol(copyfrom + 7,
124
+ &endptr, 10);
125
+ if (endptr - copyfrom != len)
126
+ die(_("invalid parameter for pathspec magic 'prefix'"));
127
+ /* "i" would be wrong, but it does not matter */
128
+ break;
129
+ }
130
+ }
131
if (ARRAY_SIZE(pathspec_magic) <= i)
132
die(_("Invalid pathspec magic '%.*s' in '%s'"),
133
(int) len, copyfrom, elt);
134
}
135
if (*copyfrom != ')')
136
die(_("Missing ')' at the end of pathspec magic in '%s'"), elt);
137
+ long_magic_end = copyfrom;
138
copyfrom++;
139
} else {
140
/* shorthand */
161
magic |= short_magic;
162
*p_short_magic = short_magic;
163
153
- if (magic & PATHSPEC_FROMTOP) {
164
+ if (pathspec_prefix >= 0 &&
165
+ (prefixlen || (prefix && *prefix)))
166
+ die("BUG: 'prefix' magic is supposed to be used at worktree's root");
167
+
168
+ if (pathspec_prefix >= 0) {
169
+ match = xstrdup(copyfrom);
170
+ prefixlen = pathspec_prefix;
171
+ } else if (magic & PATHSPEC_FROMTOP) {
172
match = xstrdup(copyfrom);
173
prefixlen = 0;
174
} else {
183
*/
184
if (flags & PATHSPEC_PREFIX_ORIGIN) {
185
struct strbuf sb = STRBUF_INIT;
168
- strbuf_add(&sb, elt, copyfrom - elt);
186
+ const char *start = elt;
187
+ if (prefixlen && !limit_pathspec_to_literal()) {
188
+ /* Preserve the actual prefix length of each pattern */
189
+ if (long_magic_end) {
190
+ strbuf_add(&sb, start, long_magic_end - start);
191
+ strbuf_addf(&sb, ",prefix:%d", prefixlen);
192
+ start = long_magic_end;
193
+ } else {
194
+ if (*start == ':')
195
+ start++;
196
+ strbuf_addf(&sb, ":(prefix:%d)", prefixlen);
197
+ }
198
+ }
199
+ strbuf_add(&sb, start, copyfrom - start);
200
strbuf_addstr(&sb, match);
201
item->original = strbuf_detach(&sb, NULL);
202
} else