1#include"cache.h" 2#include"dir.h" 3#include"pathspec.h" 4 5/* 6 * Finds which of the given pathspecs match items in the index. 7 * 8 * For each pathspec, sets the corresponding entry in the seen[] array 9 * (which should be specs items long, i.e. the same size as pathspec) 10 * to the nature of the "closest" (i.e. most specific) match found for 11 * that pathspec in the index, if it was a closer type of match than 12 * the existing entry. As an optimization, matching is skipped 13 * altogether if seen[] already only contains non-zero entries. 14 * 15 * If seen[] has not already been written to, it may make sense 16 * to use find_pathspecs_matching_against_index() instead. 17 */ 18voidadd_pathspec_matches_against_index(const char**pathspec, 19char*seen,int specs) 20{ 21int num_unmatched =0, i; 22 23/* 24 * Since we are walking the index as if we were walking the directory, 25 * we have to mark the matched pathspec as seen; otherwise we will 26 * mistakenly think that the user gave a pathspec that did not match 27 * anything. 28 */ 29for(i =0; i < specs; i++) 30if(!seen[i]) 31 num_unmatched++; 32if(!num_unmatched) 33return; 34for(i =0; i < active_nr; i++) { 35struct cache_entry *ce = active_cache[i]; 36match_pathspec(pathspec, ce->name,ce_namelen(ce),0, seen); 37} 38} 39 40/* 41 * Finds which of the given pathspecs match items in the index. 42 * 43 * This is a one-shot wrapper around add_pathspec_matches_against_index() 44 * which allocates, populates, and returns a seen[] array indicating the 45 * nature of the "closest" (i.e. most specific) matches which each of the 46 * given pathspecs achieves against all items in the index. 47 */ 48char*find_pathspecs_matching_against_index(const char**pathspec) 49{ 50char*seen; 51int i; 52 53for(i =0; pathspec[i]; i++) 54;/* just counting */ 55 seen =xcalloc(i,1); 56add_pathspec_matches_against_index(pathspec, seen, i); 57return seen; 58} 59 60/* 61 * Check the index to see whether path refers to a submodule, or 62 * something inside a submodule. If the former, returns the path with 63 * any trailing slash stripped. If the latter, dies with an error 64 * message. 65 */ 66const char*check_path_for_gitlink(const char*path) 67{ 68int i, path_len =strlen(path); 69for(i =0; i < active_nr; i++) { 70struct cache_entry *ce = active_cache[i]; 71if(S_ISGITLINK(ce->ce_mode)) { 72int ce_len =ce_namelen(ce); 73if(path_len <= ce_len || path[ce_len] !='/'|| 74memcmp(ce->name, path, ce_len)) 75/* path does not refer to this 76 * submodule or anything inside it */ 77continue; 78if(path_len == ce_len +1) { 79/* path refers to submodule; 80 * strip trailing slash */ 81returnxstrndup(ce->name, ce_len); 82}else{ 83die(_("Path '%s' is in submodule '%.*s'"), 84 path, ce_len, ce->name); 85} 86} 87} 88return path; 89} 90 91/* 92 * Dies if the given path refers to a file inside a symlinked 93 * directory in the index. 94 */ 95voiddie_if_path_beyond_symlink(const char*path,const char*prefix) 96{ 97if(has_symlink_leading_path(path,strlen(path))) { 98int len = prefix ?strlen(prefix) :0; 99die(_("'%s' is beyond a symbolic link"), path + len); 100} 101} 102 103/* 104 * Magic pathspec 105 * 106 * Possible future magic semantics include stuff like: 107 * 108 * { PATHSPEC_NOGLOB, '!', "noglob" }, 109 * { PATHSPEC_ICASE, '\0', "icase" }, 110 * { PATHSPEC_RECURSIVE, '*', "recursive" }, 111 * { PATHSPEC_REGEXP, '\0', "regexp" }, 112 * 113 */ 114 115static struct pathspec_magic { 116unsigned bit; 117char mnemonic;/* this cannot be ':'! */ 118const char*name; 119} pathspec_magic[] = { 120{ PATHSPEC_FROMTOP,'/',"top"}, 121}; 122 123/* 124 * Take an element of a pathspec and check for magic signatures. 125 * Append the result to the prefix. Return the magic bitmap. 126 * 127 * For now, we only parse the syntax and throw out anything other than 128 * "top" magic. 129 * 130 * NEEDSWORK: This needs to be rewritten when we start migrating 131 * get_pathspec() users to use the "struct pathspec" interface. For 132 * example, a pathspec element may be marked as case-insensitive, but 133 * the prefix part must always match literally, and a single stupid 134 * string cannot express such a case. 135 */ 136static unsignedprefix_pathspec(struct pathspec_item *item, 137unsigned*p_short_magic, 138const char**raw,unsigned flags, 139const char*prefix,int prefixlen, 140const char*elt) 141{ 142unsigned magic =0, short_magic =0; 143const char*copyfrom = elt; 144char*match; 145int i; 146 147if(elt[0] !=':') { 148;/* nothing to do */ 149}else if(elt[1] =='(') { 150/* longhand */ 151const char*nextat; 152for(copyfrom = elt +2; 153*copyfrom && *copyfrom !=')'; 154 copyfrom = nextat) { 155size_t len =strcspn(copyfrom,",)"); 156if(copyfrom[len] ==',') 157 nextat = copyfrom + len +1; 158else 159/* handle ')' and '\0' */ 160 nextat = copyfrom + len; 161if(!len) 162continue; 163for(i =0; i <ARRAY_SIZE(pathspec_magic); i++) 164if(strlen(pathspec_magic[i].name) == len && 165!strncmp(pathspec_magic[i].name, copyfrom, len)) { 166 magic |= pathspec_magic[i].bit; 167break; 168} 169if(ARRAY_SIZE(pathspec_magic) <= i) 170die(_("Invalid pathspec magic '%.*s' in '%s'"), 171(int) len, copyfrom, elt); 172} 173if(*copyfrom !=')') 174die(_("Missing ')' at the end of pathspec magic in '%s'"), elt); 175 copyfrom++; 176}else{ 177/* shorthand */ 178for(copyfrom = elt +1; 179*copyfrom && *copyfrom !=':'; 180 copyfrom++) { 181char ch = *copyfrom; 182 183if(!is_pathspec_magic(ch)) 184break; 185for(i =0; i <ARRAY_SIZE(pathspec_magic); i++) 186if(pathspec_magic[i].mnemonic == ch) { 187 short_magic |= pathspec_magic[i].bit; 188break; 189} 190if(ARRAY_SIZE(pathspec_magic) <= i) 191die(_("Unimplemented pathspec magic '%c' in '%s'"), 192 ch, elt); 193} 194if(*copyfrom ==':') 195 copyfrom++; 196} 197 198 magic |= short_magic; 199*p_short_magic = short_magic; 200 201if(magic & PATHSPEC_FROMTOP) 202 match =xstrdup(copyfrom); 203else 204 match =prefix_path(prefix, prefixlen, copyfrom); 205*raw = item->match = match; 206/* 207 * Prefix the pathspec (keep all magic) and assign to 208 * original. Useful for passing to another command. 209 */ 210if(flags & PATHSPEC_PREFIX_ORIGIN) { 211struct strbuf sb = STRBUF_INIT; 212strbuf_add(&sb, elt, copyfrom - elt); 213strbuf_addstr(&sb, match); 214 item->original =strbuf_detach(&sb, NULL); 215}else 216 item->original = elt; 217 item->len =strlen(item->match); 218 219if((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) && 220(item->len >=1&& item->match[item->len -1] =='/') && 221(i =cache_name_pos(item->match, item->len -1)) >=0&& 222S_ISGITLINK(active_cache[i]->ce_mode)) { 223 item->len--; 224 match[item->len] ='\0'; 225} 226 227if(flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE) 228for(i =0; i < active_nr; i++) { 229struct cache_entry *ce = active_cache[i]; 230int ce_len =ce_namelen(ce); 231 232if(!S_ISGITLINK(ce->ce_mode)) 233continue; 234 235if(item->len <= ce_len || match[ce_len] !='/'|| 236memcmp(ce->name, match, ce_len)) 237continue; 238if(item->len == ce_len +1) { 239/* strip trailing slash */ 240 item->len--; 241 match[item->len] ='\0'; 242}else 243die(_("Pathspec '%s' is in submodule '%.*s'"), 244 elt, ce_len, ce->name); 245} 246 247if(limit_pathspec_to_literal()) 248 item->nowildcard_len = item->len; 249else 250 item->nowildcard_len =simple_length(item->match); 251 item->flags =0; 252if(item->nowildcard_len < item->len && 253 item->match[item->nowildcard_len] =='*'&& 254no_wildcard(item->match + item->nowildcard_len +1)) 255 item->flags |= PATHSPEC_ONESTAR; 256return magic; 257} 258 259static intpathspec_item_cmp(const void*a_,const void*b_) 260{ 261struct pathspec_item *a, *b; 262 263 a = (struct pathspec_item *)a_; 264 b = (struct pathspec_item *)b_; 265returnstrcmp(a->match, b->match); 266} 267 268static void NORETURN unsupported_magic(const char*pattern, 269unsigned magic, 270unsigned short_magic) 271{ 272struct strbuf sb = STRBUF_INIT; 273int i, n; 274for(n = i =0; i <ARRAY_SIZE(pathspec_magic); i++) { 275const struct pathspec_magic *m = pathspec_magic + i; 276if(!(magic & m->bit)) 277continue; 278if(sb.len) 279strbuf_addstr(&sb," "); 280if(short_magic & m->bit) 281strbuf_addf(&sb,"'%c'", m->mnemonic); 282else 283strbuf_addf(&sb,"'%s'", m->name); 284 n++; 285} 286/* 287 * We may want to substitute "this command" with a command 288 * name. E.g. when add--interactive dies when running 289 * "checkout -p" 290 */ 291die(_("%s: pathspec magic not supported by this command:%s"), 292 pattern, sb.buf); 293} 294 295/* 296 * Given command line arguments and a prefix, convert the input to 297 * pathspec. die() if any magic in magic_mask is used. 298 */ 299voidparse_pathspec(struct pathspec *pathspec, 300unsigned magic_mask,unsigned flags, 301const char*prefix,const char**argv) 302{ 303struct pathspec_item *item; 304const char*entry = argv ? *argv : NULL; 305int i, n, prefixlen; 306 307memset(pathspec,0,sizeof(*pathspec)); 308 309if(flags & PATHSPEC_MAXDEPTH_VALID) 310 pathspec->magic |= PATHSPEC_MAXDEPTH; 311 312/* No arguments, no prefix -> no pathspec */ 313if(!entry && !prefix) 314return; 315 316if((flags & PATHSPEC_PREFER_CWD) && 317(flags & PATHSPEC_PREFER_FULL)) 318die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible"); 319 320/* No arguments with prefix -> prefix pathspec */ 321if(!entry) { 322static const char*raw[2]; 323 324if(flags & PATHSPEC_PREFER_FULL) 325return; 326 327if(!(flags & PATHSPEC_PREFER_CWD)) 328die("BUG: PATHSPEC_PREFER_CWD requires arguments"); 329 330 pathspec->items = item =xmalloc(sizeof(*item)); 331memset(item,0,sizeof(*item)); 332 item->match = prefix; 333 item->original = prefix; 334 item->nowildcard_len = item->len =strlen(prefix); 335 raw[0] = prefix; 336 raw[1] = NULL; 337 pathspec->nr =1; 338 pathspec->raw = raw; 339return; 340} 341 342 n =0; 343while(argv[n]) 344 n++; 345 346 pathspec->nr = n; 347 pathspec->items = item =xmalloc(sizeof(*item) * n); 348 pathspec->raw = argv; 349 prefixlen = prefix ?strlen(prefix) :0; 350 351for(i =0; i < n; i++) { 352unsigned short_magic; 353 entry = argv[i]; 354 355 item[i].magic =prefix_pathspec(item + i, &short_magic, 356 argv + i, flags, 357 prefix, prefixlen, entry); 358if(item[i].magic & magic_mask) 359unsupported_magic(entry, 360 item[i].magic & magic_mask, 361 short_magic); 362 363if((flags & PATHSPEC_SYMLINK_LEADING_PATH) && 364has_symlink_leading_path(item[i].match, item[i].len)) { 365die(_("pathspec '%s' is beyond a symbolic link"), entry); 366} 367 368if(item[i].nowildcard_len < item[i].len) 369 pathspec->has_wildcard =1; 370 pathspec->magic |= item[i].magic; 371} 372 373if(pathspec->magic & PATHSPEC_MAXDEPTH) 374qsort(pathspec->items, pathspec->nr, 375sizeof(struct pathspec_item), pathspec_item_cmp); 376} 377 378/* 379 * N.B. get_pathspec() is deprecated in favor of the "struct pathspec" 380 * based interface - see pathspec.c:parse_pathspec(). 381 * 382 * Arguments: 383 * - prefix - a path relative to the root of the working tree 384 * - pathspec - a list of paths underneath the prefix path 385 * 386 * Iterates over pathspec, prepending each path with prefix, 387 * and return the resulting list. 388 * 389 * If pathspec is empty, return a singleton list containing prefix. 390 * 391 * If pathspec and prefix are both empty, return an empty list. 392 * 393 * This is typically used by built-in commands such as add.c, in order 394 * to normalize argv arguments provided to the built-in into a list of 395 * paths to process, all relative to the root of the working tree. 396 */ 397const char**get_pathspec(const char*prefix,const char**pathspec) 398{ 399struct pathspec ps; 400parse_pathspec(&ps, 401 PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, 402 PATHSPEC_PREFER_CWD, 403 prefix, pathspec); 404return ps.raw; 405} 406 407voidcopy_pathspec(struct pathspec *dst,const struct pathspec *src) 408{ 409*dst = *src; 410 dst->items =xmalloc(sizeof(struct pathspec_item) * dst->nr); 411memcpy(dst->items, src->items, 412sizeof(struct pathspec_item) * dst->nr); 413}