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 item->original = elt; 207 item->len =strlen(item->match); 208 209if((flags & PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) && 210(item->len >=1&& item->match[item->len -1] =='/') && 211(i =cache_name_pos(item->match, item->len -1)) >=0&& 212S_ISGITLINK(active_cache[i]->ce_mode)) { 213 item->len--; 214 match[item->len] ='\0'; 215} 216 217if(flags & PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE) 218for(i =0; i < active_nr; i++) { 219struct cache_entry *ce = active_cache[i]; 220int ce_len =ce_namelen(ce); 221 222if(!S_ISGITLINK(ce->ce_mode)) 223continue; 224 225if(item->len <= ce_len || match[ce_len] !='/'|| 226memcmp(ce->name, match, ce_len)) 227continue; 228if(item->len == ce_len +1) { 229/* strip trailing slash */ 230 item->len--; 231 match[item->len] ='\0'; 232}else 233die(_("Pathspec '%s' is in submodule '%.*s'"), 234 elt, ce_len, ce->name); 235} 236 237if(limit_pathspec_to_literal()) 238 item->nowildcard_len = item->len; 239else 240 item->nowildcard_len =simple_length(item->match); 241 item->flags =0; 242if(item->nowildcard_len < item->len && 243 item->match[item->nowildcard_len] =='*'&& 244no_wildcard(item->match + item->nowildcard_len +1)) 245 item->flags |= PATHSPEC_ONESTAR; 246return magic; 247} 248 249static intpathspec_item_cmp(const void*a_,const void*b_) 250{ 251struct pathspec_item *a, *b; 252 253 a = (struct pathspec_item *)a_; 254 b = (struct pathspec_item *)b_; 255returnstrcmp(a->match, b->match); 256} 257 258static void NORETURN unsupported_magic(const char*pattern, 259unsigned magic, 260unsigned short_magic) 261{ 262struct strbuf sb = STRBUF_INIT; 263int i, n; 264for(n = i =0; i <ARRAY_SIZE(pathspec_magic); i++) { 265const struct pathspec_magic *m = pathspec_magic + i; 266if(!(magic & m->bit)) 267continue; 268if(sb.len) 269strbuf_addstr(&sb," "); 270if(short_magic & m->bit) 271strbuf_addf(&sb,"'%c'", m->mnemonic); 272else 273strbuf_addf(&sb,"'%s'", m->name); 274 n++; 275} 276/* 277 * We may want to substitute "this command" with a command 278 * name. E.g. when add--interactive dies when running 279 * "checkout -p" 280 */ 281die(_("%s: pathspec magic not supported by this command:%s"), 282 pattern, sb.buf); 283} 284 285/* 286 * Given command line arguments and a prefix, convert the input to 287 * pathspec. die() if any magic in magic_mask is used. 288 */ 289voidparse_pathspec(struct pathspec *pathspec, 290unsigned magic_mask,unsigned flags, 291const char*prefix,const char**argv) 292{ 293struct pathspec_item *item; 294const char*entry = argv ? *argv : NULL; 295int i, n, prefixlen; 296 297memset(pathspec,0,sizeof(*pathspec)); 298 299if(flags & PATHSPEC_MAXDEPTH_VALID) 300 pathspec->magic |= PATHSPEC_MAXDEPTH; 301 302/* No arguments, no prefix -> no pathspec */ 303if(!entry && !prefix) 304return; 305 306if((flags & PATHSPEC_PREFER_CWD) && 307(flags & PATHSPEC_PREFER_FULL)) 308die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible"); 309 310/* No arguments with prefix -> prefix pathspec */ 311if(!entry) { 312static const char*raw[2]; 313 314if(flags & PATHSPEC_PREFER_FULL) 315return; 316 317if(!(flags & PATHSPEC_PREFER_CWD)) 318die("BUG: PATHSPEC_PREFER_CWD requires arguments"); 319 320 pathspec->items = item =xmalloc(sizeof(*item)); 321memset(item,0,sizeof(*item)); 322 item->match = prefix; 323 item->original = prefix; 324 item->nowildcard_len = item->len =strlen(prefix); 325 raw[0] = prefix; 326 raw[1] = NULL; 327 pathspec->nr =1; 328 pathspec->raw = raw; 329return; 330} 331 332 n =0; 333while(argv[n]) 334 n++; 335 336 pathspec->nr = n; 337 pathspec->items = item =xmalloc(sizeof(*item) * n); 338 pathspec->raw = argv; 339 prefixlen = prefix ?strlen(prefix) :0; 340 341for(i =0; i < n; i++) { 342unsigned short_magic; 343 entry = argv[i]; 344 345 item[i].magic =prefix_pathspec(item + i, &short_magic, 346 argv + i, flags, 347 prefix, prefixlen, entry); 348if(item[i].magic & magic_mask) 349unsupported_magic(entry, 350 item[i].magic & magic_mask, 351 short_magic); 352 353if((flags & PATHSPEC_SYMLINK_LEADING_PATH) && 354has_symlink_leading_path(item[i].match, item[i].len)) { 355die(_("pathspec '%s' is beyond a symbolic link"), entry); 356} 357 358if(item[i].nowildcard_len < item[i].len) 359 pathspec->has_wildcard =1; 360 pathspec->magic |= item[i].magic; 361} 362 363if(pathspec->magic & PATHSPEC_MAXDEPTH) 364qsort(pathspec->items, pathspec->nr, 365sizeof(struct pathspec_item), pathspec_item_cmp); 366} 367 368/* 369 * N.B. get_pathspec() is deprecated in favor of the "struct pathspec" 370 * based interface - see pathspec.c:parse_pathspec(). 371 * 372 * Arguments: 373 * - prefix - a path relative to the root of the working tree 374 * - pathspec - a list of paths underneath the prefix path 375 * 376 * Iterates over pathspec, prepending each path with prefix, 377 * and return the resulting list. 378 * 379 * If pathspec is empty, return a singleton list containing prefix. 380 * 381 * If pathspec and prefix are both empty, return an empty list. 382 * 383 * This is typically used by built-in commands such as add.c, in order 384 * to normalize argv arguments provided to the built-in into a list of 385 * paths to process, all relative to the root of the working tree. 386 */ 387const char**get_pathspec(const char*prefix,const char**pathspec) 388{ 389struct pathspec ps; 390parse_pathspec(&ps, 391 PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP, 392 PATHSPEC_PREFER_CWD, 393 prefix, pathspec); 394return ps.raw; 395} 396 397voidcopy_pathspec(struct pathspec *dst,const struct pathspec *src) 398{ 399*dst = *src; 400 dst->items =xmalloc(sizeof(struct pathspec_item) * dst->nr); 401memcpy(dst->items, src->items, 402sizeof(struct pathspec_item) * dst->nr); 403}