1/* 2 * This handles recursive filename detection with exclude 3 * files, index knowledge etc.. 4 * 5 * See Documentation/technical/api-directory-listing.txt 6 * 7 * Copyright (C) Linus Torvalds, 2005-2006 8 * Junio Hamano, 2005-2006 9 */ 10#include"cache.h" 11#include"dir.h" 12#include"refs.h" 13#include"wildmatch.h" 14#include"pathspec.h" 15#include"utf8.h" 16#include"varint.h" 17#include"ewah/ewok.h" 18 19struct path_simplify { 20int len; 21const char*path; 22}; 23 24/* 25 * Tells read_directory_recursive how a file or directory should be treated. 26 * Values are ordered by significance, e.g. if a directory contains both 27 * excluded and untracked files, it is listed as untracked because 28 * path_untracked > path_excluded. 29 */ 30enum path_treatment { 31 path_none =0, 32 path_recurse, 33 path_excluded, 34 path_untracked 35}; 36 37/* 38 * Support data structure for our opendir/readdir/closedir wrappers 39 */ 40struct cached_dir { 41DIR*fdir; 42struct untracked_cache_dir *untracked; 43int nr_files; 44int nr_dirs; 45 46struct dirent *de; 47const char*file; 48struct untracked_cache_dir *ucd; 49}; 50 51static enum path_treatment read_directory_recursive(struct dir_struct *dir, 52const char*path,int len,struct untracked_cache_dir *untracked, 53int check_only,const struct path_simplify *simplify); 54static intget_dtype(struct dirent *de,const char*path,int len); 55 56static struct trace_key trace_exclude =TRACE_KEY_INIT(EXCLUDE); 57 58/* helper string functions with support for the ignore_case flag */ 59intstrcmp_icase(const char*a,const char*b) 60{ 61return ignore_case ?strcasecmp(a, b) :strcmp(a, b); 62} 63 64intstrncmp_icase(const char*a,const char*b,size_t count) 65{ 66return ignore_case ?strncasecmp(a, b, count) :strncmp(a, b, count); 67} 68 69intfnmatch_icase(const char*pattern,const char*string,int flags) 70{ 71returnwildmatch(pattern, string, 72 flags | (ignore_case ? WM_CASEFOLD :0), 73 NULL); 74} 75 76intgit_fnmatch(const struct pathspec_item *item, 77const char*pattern,const char*string, 78int prefix) 79{ 80if(prefix >0) { 81if(ps_strncmp(item, pattern, string, prefix)) 82return WM_NOMATCH; 83 pattern += prefix; 84 string += prefix; 85} 86if(item->flags & PATHSPEC_ONESTAR) { 87int pattern_len =strlen(++pattern); 88int string_len =strlen(string); 89return string_len < pattern_len || 90ps_strcmp(item, pattern, 91 string + string_len - pattern_len); 92} 93if(item->magic & PATHSPEC_GLOB) 94returnwildmatch(pattern, string, 95 WM_PATHNAME | 96(item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0), 97 NULL); 98else 99/* wildmatch has not learned no FNM_PATHNAME mode yet */ 100returnwildmatch(pattern, string, 101 item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0, 102 NULL); 103} 104 105static intfnmatch_icase_mem(const char*pattern,int patternlen, 106const char*string,int stringlen, 107int flags) 108{ 109int match_status; 110struct strbuf pat_buf = STRBUF_INIT; 111struct strbuf str_buf = STRBUF_INIT; 112const char*use_pat = pattern; 113const char*use_str = string; 114 115if(pattern[patternlen]) { 116strbuf_add(&pat_buf, pattern, patternlen); 117 use_pat = pat_buf.buf; 118} 119if(string[stringlen]) { 120strbuf_add(&str_buf, string, stringlen); 121 use_str = str_buf.buf; 122} 123 124if(ignore_case) 125 flags |= WM_CASEFOLD; 126 match_status =wildmatch(use_pat, use_str, flags, NULL); 127 128strbuf_release(&pat_buf); 129strbuf_release(&str_buf); 130 131return match_status; 132} 133 134static size_tcommon_prefix_len(const struct pathspec *pathspec) 135{ 136int n; 137size_t max =0; 138 139/* 140 * ":(icase)path" is treated as a pathspec full of 141 * wildcard. In other words, only prefix is considered common 142 * prefix. If the pathspec is abc/foo abc/bar, running in 143 * subdir xyz, the common prefix is still xyz, not xuz/abc as 144 * in non-:(icase). 145 */ 146GUARD_PATHSPEC(pathspec, 147 PATHSPEC_FROMTOP | 148 PATHSPEC_MAXDEPTH | 149 PATHSPEC_LITERAL | 150 PATHSPEC_GLOB | 151 PATHSPEC_ICASE | 152 PATHSPEC_EXCLUDE); 153 154for(n =0; n < pathspec->nr; n++) { 155size_t i =0, len =0, item_len; 156if(pathspec->items[n].magic & PATHSPEC_EXCLUDE) 157continue; 158if(pathspec->items[n].magic & PATHSPEC_ICASE) 159 item_len = pathspec->items[n].prefix; 160else 161 item_len = pathspec->items[n].nowildcard_len; 162while(i < item_len && (n ==0|| i < max)) { 163char c = pathspec->items[n].match[i]; 164if(c != pathspec->items[0].match[i]) 165break; 166if(c =='/') 167 len = i +1; 168 i++; 169} 170if(n ==0|| len < max) { 171 max = len; 172if(!max) 173break; 174} 175} 176return max; 177} 178 179/* 180 * Returns a copy of the longest leading path common among all 181 * pathspecs. 182 */ 183char*common_prefix(const struct pathspec *pathspec) 184{ 185unsigned long len =common_prefix_len(pathspec); 186 187return len ?xmemdupz(pathspec->items[0].match, len) : NULL; 188} 189 190intfill_directory(struct dir_struct *dir,const struct pathspec *pathspec) 191{ 192size_t len; 193 194/* 195 * Calculate common prefix for the pathspec, and 196 * use that to optimize the directory walk 197 */ 198 len =common_prefix_len(pathspec); 199 200/* Read the directory and prune it */ 201read_directory(dir, pathspec->nr ? pathspec->_raw[0] :"", len, pathspec); 202return len; 203} 204 205intwithin_depth(const char*name,int namelen, 206int depth,int max_depth) 207{ 208const char*cp = name, *cpe = name + namelen; 209 210while(cp < cpe) { 211if(*cp++ !='/') 212continue; 213 depth++; 214if(depth > max_depth) 215return0; 216} 217return1; 218} 219 220#define DO_MATCH_EXCLUDE 1 221#define DO_MATCH_DIRECTORY 2 222 223/* 224 * Does 'match' match the given name? 225 * A match is found if 226 * 227 * (1) the 'match' string is leading directory of 'name', or 228 * (2) the 'match' string is a wildcard and matches 'name', or 229 * (3) the 'match' string is exactly the same as 'name'. 230 * 231 * and the return value tells which case it was. 232 * 233 * It returns 0 when there is no match. 234 */ 235static intmatch_pathspec_item(const struct pathspec_item *item,int prefix, 236const char*name,int namelen,unsigned flags) 237{ 238/* name/namelen has prefix cut off by caller */ 239const char*match = item->match + prefix; 240int matchlen = item->len - prefix; 241 242/* 243 * The normal call pattern is: 244 * 1. prefix = common_prefix_len(ps); 245 * 2. prune something, or fill_directory 246 * 3. match_pathspec() 247 * 248 * 'prefix' at #1 may be shorter than the command's prefix and 249 * it's ok for #2 to match extra files. Those extras will be 250 * trimmed at #3. 251 * 252 * Suppose the pathspec is 'foo' and '../bar' running from 253 * subdir 'xyz'. The common prefix at #1 will be empty, thanks 254 * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The 255 * user does not want XYZ/foo, only the "foo" part should be 256 * case-insensitive. We need to filter out XYZ/foo here. In 257 * other words, we do not trust the caller on comparing the 258 * prefix part when :(icase) is involved. We do exact 259 * comparison ourselves. 260 * 261 * Normally the caller (common_prefix_len() in fact) does 262 * _exact_ matching on name[-prefix+1..-1] and we do not need 263 * to check that part. Be defensive and check it anyway, in 264 * case common_prefix_len is changed, or a new caller is 265 * introduced that does not use common_prefix_len. 266 * 267 * If the penalty turns out too high when prefix is really 268 * long, maybe change it to 269 * strncmp(match, name, item->prefix - prefix) 270 */ 271if(item->prefix && (item->magic & PATHSPEC_ICASE) && 272strncmp(item->match, name - prefix, item->prefix)) 273return0; 274 275/* If the match was just the prefix, we matched */ 276if(!*match) 277return MATCHED_RECURSIVELY; 278 279if(matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) { 280if(matchlen == namelen) 281return MATCHED_EXACTLY; 282 283if(match[matchlen-1] =='/'|| name[matchlen] =='/') 284return MATCHED_RECURSIVELY; 285}else if((flags & DO_MATCH_DIRECTORY) && 286 match[matchlen -1] =='/'&& 287 namelen == matchlen -1&& 288!ps_strncmp(item, match, name, namelen)) 289return MATCHED_EXACTLY; 290 291if(item->nowildcard_len < item->len && 292!git_fnmatch(item, match, name, 293 item->nowildcard_len - prefix)) 294return MATCHED_FNMATCH; 295 296return0; 297} 298 299/* 300 * Given a name and a list of pathspecs, returns the nature of the 301 * closest (i.e. most specific) match of the name to any of the 302 * pathspecs. 303 * 304 * The caller typically calls this multiple times with the same 305 * pathspec and seen[] array but with different name/namelen 306 * (e.g. entries from the index) and is interested in seeing if and 307 * how each pathspec matches all the names it calls this function 308 * with. A mark is left in the seen[] array for each pathspec element 309 * indicating the closest type of match that element achieved, so if 310 * seen[n] remains zero after multiple invocations, that means the nth 311 * pathspec did not match any names, which could indicate that the 312 * user mistyped the nth pathspec. 313 */ 314static intdo_match_pathspec(const struct pathspec *ps, 315const char*name,int namelen, 316int prefix,char*seen, 317unsigned flags) 318{ 319int i, retval =0, exclude = flags & DO_MATCH_EXCLUDE; 320 321GUARD_PATHSPEC(ps, 322 PATHSPEC_FROMTOP | 323 PATHSPEC_MAXDEPTH | 324 PATHSPEC_LITERAL | 325 PATHSPEC_GLOB | 326 PATHSPEC_ICASE | 327 PATHSPEC_EXCLUDE); 328 329if(!ps->nr) { 330if(!ps->recursive || 331!(ps->magic & PATHSPEC_MAXDEPTH) || 332 ps->max_depth == -1) 333return MATCHED_RECURSIVELY; 334 335if(within_depth(name, namelen,0, ps->max_depth)) 336return MATCHED_EXACTLY; 337else 338return0; 339} 340 341 name += prefix; 342 namelen -= prefix; 343 344for(i = ps->nr -1; i >=0; i--) { 345int how; 346 347if((!exclude && ps->items[i].magic & PATHSPEC_EXCLUDE) || 348( exclude && !(ps->items[i].magic & PATHSPEC_EXCLUDE))) 349continue; 350 351if(seen && seen[i] == MATCHED_EXACTLY) 352continue; 353/* 354 * Make exclude patterns optional and never report 355 * "pathspec ':(exclude)foo' matches no files" 356 */ 357if(seen && ps->items[i].magic & PATHSPEC_EXCLUDE) 358 seen[i] = MATCHED_FNMATCH; 359 how =match_pathspec_item(ps->items+i, prefix, name, 360 namelen, flags); 361if(ps->recursive && 362(ps->magic & PATHSPEC_MAXDEPTH) && 363 ps->max_depth != -1&& 364 how && how != MATCHED_FNMATCH) { 365int len = ps->items[i].len; 366if(name[len] =='/') 367 len++; 368if(within_depth(name+len, namelen-len,0, ps->max_depth)) 369 how = MATCHED_EXACTLY; 370else 371 how =0; 372} 373if(how) { 374if(retval < how) 375 retval = how; 376if(seen && seen[i] < how) 377 seen[i] = how; 378} 379} 380return retval; 381} 382 383intmatch_pathspec(const struct pathspec *ps, 384const char*name,int namelen, 385int prefix,char*seen,int is_dir) 386{ 387int positive, negative; 388unsigned flags = is_dir ? DO_MATCH_DIRECTORY :0; 389 positive =do_match_pathspec(ps, name, namelen, 390 prefix, seen, flags); 391if(!(ps->magic & PATHSPEC_EXCLUDE) || !positive) 392return positive; 393 negative =do_match_pathspec(ps, name, namelen, 394 prefix, seen, 395 flags | DO_MATCH_EXCLUDE); 396return negative ?0: positive; 397} 398 399intreport_path_error(const char*ps_matched, 400const struct pathspec *pathspec, 401const char*prefix) 402{ 403/* 404 * Make sure all pathspec matched; otherwise it is an error. 405 */ 406int num, errors =0; 407for(num =0; num < pathspec->nr; num++) { 408int other, found_dup; 409 410if(ps_matched[num]) 411continue; 412/* 413 * The caller might have fed identical pathspec 414 * twice. Do not barf on such a mistake. 415 * FIXME: parse_pathspec should have eliminated 416 * duplicate pathspec. 417 */ 418for(found_dup = other =0; 419!found_dup && other < pathspec->nr; 420 other++) { 421if(other == num || !ps_matched[other]) 422continue; 423if(!strcmp(pathspec->items[other].original, 424 pathspec->items[num].original)) 425/* 426 * Ok, we have a match already. 427 */ 428 found_dup =1; 429} 430if(found_dup) 431continue; 432 433error("pathspec '%s' did not match any file(s) known to git.", 434 pathspec->items[num].original); 435 errors++; 436} 437return errors; 438} 439 440/* 441 * Return the length of the "simple" part of a path match limiter. 442 */ 443intsimple_length(const char*match) 444{ 445int len = -1; 446 447for(;;) { 448unsigned char c = *match++; 449 len++; 450if(c =='\0'||is_glob_special(c)) 451return len; 452} 453} 454 455intno_wildcard(const char*string) 456{ 457return string[simple_length(string)] =='\0'; 458} 459 460voidparse_exclude_pattern(const char**pattern, 461int*patternlen, 462int*flags, 463int*nowildcardlen) 464{ 465const char*p = *pattern; 466size_t i, len; 467 468*flags =0; 469if(*p =='!') { 470*flags |= EXC_FLAG_NEGATIVE; 471 p++; 472} 473 len =strlen(p); 474if(len && p[len -1] =='/') { 475 len--; 476*flags |= EXC_FLAG_MUSTBEDIR; 477} 478for(i =0; i < len; i++) { 479if(p[i] =='/') 480break; 481} 482if(i == len) 483*flags |= EXC_FLAG_NODIR; 484*nowildcardlen =simple_length(p); 485/* 486 * we should have excluded the trailing slash from 'p' too, 487 * but that's one more allocation. Instead just make sure 488 * nowildcardlen does not exceed real patternlen 489 */ 490if(*nowildcardlen > len) 491*nowildcardlen = len; 492if(*p =='*'&&no_wildcard(p +1)) 493*flags |= EXC_FLAG_ENDSWITH; 494*pattern = p; 495*patternlen = len; 496} 497 498voidadd_exclude(const char*string,const char*base, 499int baselen,struct exclude_list *el,int srcpos) 500{ 501struct exclude *x; 502int patternlen; 503int flags; 504int nowildcardlen; 505 506parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); 507if(flags & EXC_FLAG_MUSTBEDIR) { 508FLEXPTR_ALLOC_MEM(x, pattern, string, patternlen); 509}else{ 510 x =xmalloc(sizeof(*x)); 511 x->pattern = string; 512} 513 x->patternlen = patternlen; 514 x->nowildcardlen = nowildcardlen; 515 x->base = base; 516 x->baselen = baselen; 517 x->flags = flags; 518 x->srcpos = srcpos; 519string_list_init(&x->sticky_paths,1); 520ALLOC_GROW(el->excludes, el->nr +1, el->alloc); 521 el->excludes[el->nr++] = x; 522 x->el = el; 523} 524 525static void*read_skip_worktree_file_from_index(const char*path,size_t*size, 526struct sha1_stat *sha1_stat) 527{ 528int pos, len; 529unsigned long sz; 530enum object_type type; 531void*data; 532 533 len =strlen(path); 534 pos =cache_name_pos(path, len); 535if(pos <0) 536return NULL; 537if(!ce_skip_worktree(active_cache[pos])) 538return NULL; 539 data =read_sha1_file(active_cache[pos]->sha1, &type, &sz); 540if(!data || type != OBJ_BLOB) { 541free(data); 542return NULL; 543} 544*size =xsize_t(sz); 545if(sha1_stat) { 546memset(&sha1_stat->stat,0,sizeof(sha1_stat->stat)); 547hashcpy(sha1_stat->sha1, active_cache[pos]->sha1); 548} 549return data; 550} 551 552/* 553 * Frees memory within el which was allocated for exclude patterns and 554 * the file buffer. Does not free el itself. 555 */ 556voidclear_exclude_list(struct exclude_list *el) 557{ 558int i; 559 560for(i =0; i < el->nr; i++) { 561string_list_clear(&el->excludes[i]->sticky_paths,0); 562free(el->excludes[i]); 563} 564free(el->excludes); 565free(el->filebuf); 566 567memset(el,0,sizeof(*el)); 568} 569 570static voidtrim_trailing_spaces(char*buf) 571{ 572char*p, *last_space = NULL; 573 574for(p = buf; *p; p++) 575switch(*p) { 576case' ': 577if(!last_space) 578 last_space = p; 579break; 580case'\\': 581 p++; 582if(!*p) 583return; 584/* fallthrough */ 585default: 586 last_space = NULL; 587} 588 589if(last_space) 590*last_space ='\0'; 591} 592 593/* 594 * Given a subdirectory name and "dir" of the current directory, 595 * search the subdir in "dir" and return it, or create a new one if it 596 * does not exist in "dir". 597 * 598 * If "name" has the trailing slash, it'll be excluded in the search. 599 */ 600static struct untracked_cache_dir *lookup_untracked(struct untracked_cache *uc, 601struct untracked_cache_dir *dir, 602const char*name,int len) 603{ 604int first, last; 605struct untracked_cache_dir *d; 606if(!dir) 607return NULL; 608if(len && name[len -1] =='/') 609 len--; 610 first =0; 611 last = dir->dirs_nr; 612while(last > first) { 613int cmp, next = (last + first) >>1; 614 d = dir->dirs[next]; 615 cmp =strncmp(name, d->name, len); 616if(!cmp &&strlen(d->name) > len) 617 cmp = -1; 618if(!cmp) 619return d; 620if(cmp <0) { 621 last = next; 622continue; 623} 624 first = next+1; 625} 626 627 uc->dir_created++; 628FLEX_ALLOC_MEM(d, name, name, len); 629 630ALLOC_GROW(dir->dirs, dir->dirs_nr +1, dir->dirs_alloc); 631memmove(dir->dirs + first +1, dir->dirs + first, 632(dir->dirs_nr - first) *sizeof(*dir->dirs)); 633 dir->dirs_nr++; 634 dir->dirs[first] = d; 635return d; 636} 637 638static voiddo_invalidate_gitignore(struct untracked_cache_dir *dir) 639{ 640int i; 641 dir->valid =0; 642 dir->untracked_nr =0; 643for(i =0; i < dir->dirs_nr; i++) 644do_invalidate_gitignore(dir->dirs[i]); 645} 646 647static voidinvalidate_gitignore(struct untracked_cache *uc, 648struct untracked_cache_dir *dir) 649{ 650 uc->gitignore_invalidated++; 651do_invalidate_gitignore(dir); 652} 653 654static voidinvalidate_directory(struct untracked_cache *uc, 655struct untracked_cache_dir *dir) 656{ 657int i; 658 uc->dir_invalidated++; 659 dir->valid =0; 660 dir->untracked_nr =0; 661for(i =0; i < dir->dirs_nr; i++) 662 dir->dirs[i]->recurse =0; 663} 664 665/* 666 * Given a file with name "fname", read it (either from disk, or from 667 * the index if "check_index" is non-zero), parse it and store the 668 * exclude rules in "el". 669 * 670 * If "ss" is not NULL, compute SHA-1 of the exclude file and fill 671 * stat data from disk (only valid if add_excludes returns zero). If 672 * ss_valid is non-zero, "ss" must contain good value as input. 673 */ 674static intadd_excludes(const char*fname,const char*base,int baselen, 675struct exclude_list *el,int check_index, 676struct sha1_stat *sha1_stat) 677{ 678struct stat st; 679int fd, i, lineno =1; 680size_t size =0; 681char*buf, *entry; 682 683 fd =open(fname, O_RDONLY); 684if(fd <0||fstat(fd, &st) <0) { 685if(errno != ENOENT) 686warn_on_inaccessible(fname); 687if(0<= fd) 688close(fd); 689if(!check_index || 690(buf =read_skip_worktree_file_from_index(fname, &size, sha1_stat)) == NULL) 691return-1; 692if(size ==0) { 693free(buf); 694return0; 695} 696if(buf[size-1] !='\n') { 697 buf =xrealloc(buf,st_add(size,1)); 698 buf[size++] ='\n'; 699} 700}else{ 701 size =xsize_t(st.st_size); 702if(size ==0) { 703if(sha1_stat) { 704fill_stat_data(&sha1_stat->stat, &st); 705hashcpy(sha1_stat->sha1, EMPTY_BLOB_SHA1_BIN); 706 sha1_stat->valid =1; 707} 708close(fd); 709return0; 710} 711 buf =xmallocz(size); 712if(read_in_full(fd, buf, size) != size) { 713free(buf); 714close(fd); 715return-1; 716} 717 buf[size++] ='\n'; 718close(fd); 719if(sha1_stat) { 720int pos; 721if(sha1_stat->valid && 722!match_stat_data_racy(&the_index, &sha1_stat->stat, &st)) 723;/* no content change, ss->sha1 still good */ 724else if(check_index && 725(pos =cache_name_pos(fname,strlen(fname))) >=0&& 726!ce_stage(active_cache[pos]) && 727ce_uptodate(active_cache[pos]) && 728!would_convert_to_git(fname)) 729hashcpy(sha1_stat->sha1, active_cache[pos]->sha1); 730else 731hash_sha1_file(buf, size,"blob", sha1_stat->sha1); 732fill_stat_data(&sha1_stat->stat, &st); 733 sha1_stat->valid =1; 734} 735} 736 737 el->filebuf = buf; 738 739if(skip_utf8_bom(&buf, size)) 740 size -= buf - el->filebuf; 741 742 entry = buf; 743 744for(i =0; i < size; i++) { 745if(buf[i] =='\n') { 746if(entry != buf + i && entry[0] !='#') { 747 buf[i - (i && buf[i-1] =='\r')] =0; 748trim_trailing_spaces(entry); 749add_exclude(entry, base, baselen, el, lineno); 750} 751 lineno++; 752 entry = buf + i +1; 753} 754} 755return0; 756} 757 758intadd_excludes_from_file_to_list(const char*fname,const char*base, 759int baselen,struct exclude_list *el, 760int check_index) 761{ 762returnadd_excludes(fname, base, baselen, el, check_index, NULL); 763} 764 765struct exclude_list *add_exclude_list(struct dir_struct *dir, 766int group_type,const char*src) 767{ 768struct exclude_list *el; 769struct exclude_list_group *group; 770 771 group = &dir->exclude_list_group[group_type]; 772ALLOC_GROW(group->el, group->nr +1, group->alloc); 773 el = &group->el[group->nr++]; 774memset(el,0,sizeof(*el)); 775 el->src = src; 776return el; 777} 778 779/* 780 * Used to set up core.excludesfile and .git/info/exclude lists. 781 */ 782static voidadd_excludes_from_file_1(struct dir_struct *dir,const char*fname, 783struct sha1_stat *sha1_stat) 784{ 785struct exclude_list *el; 786/* 787 * catch setup_standard_excludes() that's called before 788 * dir->untracked is assigned. That function behaves 789 * differently when dir->untracked is non-NULL. 790 */ 791if(!dir->untracked) 792 dir->unmanaged_exclude_files++; 793 el =add_exclude_list(dir, EXC_FILE, fname); 794if(add_excludes(fname,"",0, el,0, sha1_stat) <0) 795die("cannot use%sas an exclude file", fname); 796} 797 798voidadd_excludes_from_file(struct dir_struct *dir,const char*fname) 799{ 800 dir->unmanaged_exclude_files++;/* see validate_untracked_cache() */ 801add_excludes_from_file_1(dir, fname, NULL); 802} 803 804intmatch_basename(const char*basename,int basenamelen, 805const char*pattern,int prefix,int patternlen, 806int flags) 807{ 808if(prefix == patternlen) { 809if(patternlen == basenamelen && 810!strncmp_icase(pattern, basename, basenamelen)) 811return1; 812}else if(flags & EXC_FLAG_ENDSWITH) { 813/* "*literal" matching against "fooliteral" */ 814if(patternlen -1<= basenamelen && 815!strncmp_icase(pattern +1, 816 basename + basenamelen - (patternlen -1), 817 patternlen -1)) 818return1; 819}else{ 820if(fnmatch_icase_mem(pattern, patternlen, 821 basename, basenamelen, 8220) ==0) 823return1; 824} 825return0; 826} 827 828intmatch_pathname(const char*pathname,int pathlen, 829const char*base,int baselen, 830const char*pattern,int prefix,int patternlen, 831int flags) 832{ 833const char*name; 834int namelen; 835 836/* 837 * match with FNM_PATHNAME; the pattern has base implicitly 838 * in front of it. 839 */ 840if(*pattern =='/') { 841 pattern++; 842 patternlen--; 843 prefix--; 844} 845 846/* 847 * baselen does not count the trailing slash. base[] may or 848 * may not end with a trailing slash though. 849 */ 850if(pathlen < baselen +1|| 851(baselen && pathname[baselen] !='/') || 852strncmp_icase(pathname, base, baselen)) 853return0; 854 855 namelen = baselen ? pathlen - baselen -1: pathlen; 856 name = pathname + pathlen - namelen; 857 858if(prefix) { 859/* 860 * if the non-wildcard part is longer than the 861 * remaining pathname, surely it cannot match. 862 */ 863if(prefix > namelen) 864return0; 865 866if(strncmp_icase(pattern, name, prefix)) 867return0; 868 pattern += prefix; 869 patternlen -= prefix; 870 name += prefix; 871 namelen -= prefix; 872 873/* 874 * If the whole pattern did not have a wildcard, 875 * then our prefix match is all we need; we 876 * do not need to call fnmatch at all. 877 */ 878if(!patternlen && (!namelen || *name =='/')) 879return1; 880} 881 882returnfnmatch_icase_mem(pattern, patternlen, 883 name, namelen, 884 WM_PATHNAME) ==0; 885} 886 887static voidadd_sticky(struct exclude *exc,const char*pathname,int pathlen) 888{ 889struct strbuf sb = STRBUF_INIT; 890int i; 891 892for(i = exc->sticky_paths.nr -1; i >=0; i--) { 893const char*sticky = exc->sticky_paths.items[i].string; 894int len =strlen(sticky); 895 896if(pathlen < len && sticky[pathlen] =='/'&& 897!strncmp(pathname, sticky, pathlen)) 898return; 899} 900 901strbuf_add(&sb, pathname, pathlen); 902string_list_append_nodup(&exc->sticky_paths,strbuf_detach(&sb, NULL)); 903} 904 905static intmatch_sticky(struct exclude *exc,const char*pathname,int pathlen,int dtype) 906{ 907int i; 908 909for(i = exc->sticky_paths.nr -1; i >=0; i--) { 910const char*sticky = exc->sticky_paths.items[i].string; 911int len =strlen(sticky); 912 913if(pathlen == len && dtype == DT_DIR && 914!strncmp(pathname, sticky, len)) 915return1; 916 917if(pathlen > len && pathname[len] =='/'&& 918!strncmp(pathname, sticky, len)) 919return1; 920} 921 922return0; 923} 924 925staticinlineintdifferent_decisions(const struct exclude *a, 926const struct exclude *b) 927{ 928return(a->flags & EXC_FLAG_NEGATIVE) != (b->flags & EXC_FLAG_NEGATIVE); 929} 930 931/* 932 * Return non-zero if pathname is a directory and an ancestor of the 933 * literal path in a pattern. 934 */ 935static intmatch_directory_part(const char*pathname,int pathlen, 936int*dtype,struct exclude *x) 937{ 938const char*base = x->base; 939int baselen = x->baselen ? x->baselen -1:0; 940const char*pattern = x->pattern; 941int prefix = x->nowildcardlen; 942int patternlen = x->patternlen; 943 944if(*dtype == DT_UNKNOWN) 945*dtype =get_dtype(NULL, pathname, pathlen); 946if(*dtype != DT_DIR) 947return0; 948 949if(*pattern =='/') { 950 pattern++; 951 patternlen--; 952 prefix--; 953} 954 955if(baselen) { 956if(((pathlen < baselen && base[pathlen] =='/') || 957 pathlen == baselen) && 958!strncmp_icase(pathname, base, pathlen)) 959return1; 960 pathname += baselen +1; 961 pathlen -= baselen +1; 962} 963 964 965if(prefix && 966(((pathlen < prefix && pattern[pathlen] =='/') || 967 pathlen == prefix) && 968!strncmp_icase(pathname, pattern, pathlen))) 969return1; 970 971return0; 972} 973 974static struct exclude *should_descend(const char*pathname,int pathlen, 975int*dtype,struct exclude_list *el, 976struct exclude *exc) 977{ 978int i; 979 980for(i = el->nr -1;0<= i; i--) { 981struct exclude *x = el->excludes[i]; 982 983if(x == exc) 984break; 985 986if(!(x->flags & EXC_FLAG_NODIR) && 987different_decisions(x, exc) && 988match_directory_part(pathname, pathlen, dtype, x)) 989return x; 990} 991return NULL; 992} 993 994/* 995 * Scan the given exclude list in reverse to see whether pathname 996 * should be ignored. The first match (i.e. the last on the list), if 997 * any, determines the fate. Returns the exclude_list element which 998 * matched, or NULL for undecided. 999 */1000static struct exclude *last_exclude_matching_from_list(const char*pathname,1001int pathlen,1002const char*basename,1003int*dtype,1004struct exclude_list *el)1005{1006struct exclude *exc = NULL;/* undecided */1007int i, maybe_descend =0;10081009if(!el->nr)1010return NULL;/* undefined */10111012trace_printf_key(&trace_exclude,"exclude: from%s\n", el->src);10131014for(i = el->nr -1;0<= i; i--) {1015struct exclude *x = el->excludes[i];1016const char*exclude = x->pattern;1017int prefix = x->nowildcardlen;10181019if(!maybe_descend && i < el->nr -1&&1020different_decisions(x, el->excludes[i+1]))1021 maybe_descend =1;10221023if(x->sticky_paths.nr) {1024if(*dtype == DT_UNKNOWN)1025*dtype =get_dtype(NULL, pathname, pathlen);1026if(match_sticky(x, pathname, pathlen, *dtype)) {1027 exc = x;1028break;1029}1030continue;1031}10321033if(x->flags & EXC_FLAG_MUSTBEDIR) {1034if(*dtype == DT_UNKNOWN)1035*dtype =get_dtype(NULL, pathname, pathlen);1036if(*dtype != DT_DIR)1037continue;1038}10391040if(x->flags & EXC_FLAG_NODIR) {1041if(match_basename(basename,1042 pathlen - (basename - pathname),1043 exclude, prefix, x->patternlen,1044 x->flags)) {1045 exc = x;1046break;1047}1048continue;1049}10501051assert(x->baselen ==0|| x->base[x->baselen -1] =='/');1052if(match_pathname(pathname, pathlen,1053 x->base, x->baselen ? x->baselen -1:0,1054 exclude, prefix, x->patternlen, x->flags)) {1055 exc = x;1056break;1057}1058}10591060if(!exc) {1061trace_printf_key(&trace_exclude,"exclude: %.*s => n/a\n",1062 pathlen, pathname);1063return NULL;1064}10651066/*1067 * We have found a matching pattern "exc" that may exclude whole1068 * directory. We also found that there may be a pattern that matches1069 * something inside the directory and reincludes stuff.1070 *1071 * Go through the patterns again, find that pattern and double check.1072 * If it's true, return "undecided" and keep descending in. "exc" is1073 * marked sticky so that it continues to match inside the directory.1074 */1075if(!(exc->flags & EXC_FLAG_NEGATIVE) && maybe_descend) {1076struct exclude *x;10771078if(*dtype == DT_UNKNOWN)1079*dtype =get_dtype(NULL, pathname, pathlen);10801081if(*dtype == DT_DIR &&1082(x =should_descend(pathname, pathlen, dtype, el, exc))) {1083add_sticky(exc, pathname, pathlen);1084trace_printf_key(&trace_exclude,1085"exclude: %.*s vs%sat line%d=>%s,"1086" forced open by%sat line%d=> n/a\n",1087 pathlen, pathname, exc->pattern, exc->srcpos,1088 exc->flags & EXC_FLAG_NEGATIVE ?"no":"yes",1089 x->pattern, x->srcpos);1090return NULL;1091}1092}10931094trace_printf_key(&trace_exclude,"exclude: %.*s vs%sat line%d=>%s%s\n",1095 pathlen, pathname, exc->pattern, exc->srcpos,1096 exc->flags & EXC_FLAG_NEGATIVE ?"no":"yes",1097 exc->sticky_paths.nr ?" (stuck)":"");1098return exc;1099}11001101/*1102 * Scan the list and let the last match determine the fate.1103 * Return 1 for exclude, 0 for include and -1 for undecided.1104 */1105intis_excluded_from_list(const char*pathname,1106int pathlen,const char*basename,int*dtype,1107struct exclude_list *el)1108{1109struct exclude *exclude;1110 exclude =last_exclude_matching_from_list(pathname, pathlen, basename, dtype, el);1111if(exclude)1112return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1113return-1;/* undecided */1114}11151116static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,1117const char*pathname,int pathlen,const char*basename,1118int*dtype_p)1119{1120int i, j;1121struct exclude_list_group *group;1122struct exclude *exclude;1123for(i = EXC_CMDL; i <= EXC_FILE; i++) {1124 group = &dir->exclude_list_group[i];1125for(j = group->nr -1; j >=0; j--) {1126 exclude =last_exclude_matching_from_list(1127 pathname, pathlen, basename, dtype_p,1128&group->el[j]);1129if(exclude)1130return exclude;1131}1132}1133return NULL;1134}11351136/*1137 * Loads the per-directory exclude list for the substring of base1138 * which has a char length of baselen.1139 */1140static voidprep_exclude(struct dir_struct *dir,const char*base,int baselen)1141{1142struct exclude_list_group *group;1143struct exclude_list *el;1144struct exclude_stack *stk = NULL;1145struct untracked_cache_dir *untracked;1146int current;11471148 group = &dir->exclude_list_group[EXC_DIRS];11491150/*1151 * Pop the exclude lists from the EXCL_DIRS exclude_list_group1152 * which originate from directories not in the prefix of the1153 * path being checked.1154 */1155while((stk = dir->exclude_stack) != NULL) {1156if(stk->baselen <= baselen &&1157!strncmp(dir->basebuf.buf, base, stk->baselen))1158break;1159 el = &group->el[dir->exclude_stack->exclude_ix];1160 dir->exclude_stack = stk->prev;1161 dir->exclude = NULL;1162free((char*)el->src);/* see strbuf_detach() below */1163clear_exclude_list(el);1164free(stk);1165 group->nr--;1166}11671168/* Skip traversing into sub directories if the parent is excluded */1169if(dir->exclude)1170return;11711172/*1173 * Lazy initialization. All call sites currently just1174 * memset(dir, 0, sizeof(*dir)) before use. Changing all of1175 * them seems lots of work for little benefit.1176 */1177if(!dir->basebuf.buf)1178strbuf_init(&dir->basebuf, PATH_MAX);11791180/* Read from the parent directories and push them down. */1181 current = stk ? stk->baselen : -1;1182strbuf_setlen(&dir->basebuf, current <0?0: current);1183if(dir->untracked)1184 untracked = stk ? stk->ucd : dir->untracked->root;1185else1186 untracked = NULL;11871188while(current < baselen) {1189const char*cp;1190struct sha1_stat sha1_stat;11911192 stk =xcalloc(1,sizeof(*stk));1193if(current <0) {1194 cp = base;1195 current =0;1196}else{1197 cp =strchr(base + current +1,'/');1198if(!cp)1199die("oops in prep_exclude");1200 cp++;1201 untracked =1202lookup_untracked(dir->untracked, untracked,1203 base + current,1204 cp - base - current);1205}1206 stk->prev = dir->exclude_stack;1207 stk->baselen = cp - base;1208 stk->exclude_ix = group->nr;1209 stk->ucd = untracked;1210 el =add_exclude_list(dir, EXC_DIRS, NULL);1211strbuf_add(&dir->basebuf, base + current, stk->baselen - current);1212assert(stk->baselen == dir->basebuf.len);12131214/* Abort if the directory is excluded */1215if(stk->baselen) {1216int dt = DT_DIR;1217 dir->basebuf.buf[stk->baselen -1] =0;1218 dir->exclude =last_exclude_matching_from_lists(dir,1219 dir->basebuf.buf, stk->baselen -1,1220 dir->basebuf.buf + current, &dt);1221 dir->basebuf.buf[stk->baselen -1] ='/';1222if(dir->exclude &&1223 dir->exclude->flags & EXC_FLAG_NEGATIVE)1224 dir->exclude = NULL;1225if(dir->exclude) {1226 dir->exclude_stack = stk;1227return;1228}1229}12301231/* Try to read per-directory file */1232hashclr(sha1_stat.sha1);1233 sha1_stat.valid =0;1234if(dir->exclude_per_dir &&1235/*1236 * If we know that no files have been added in1237 * this directory (i.e. valid_cached_dir() has1238 * been executed and set untracked->valid) ..1239 */1240(!untracked || !untracked->valid ||1241/*1242 * .. and .gitignore does not exist before1243 * (i.e. null exclude_sha1). Then we can skip1244 * loading .gitignore, which would result in1245 * ENOENT anyway.1246 */1247!is_null_sha1(untracked->exclude_sha1))) {1248/*1249 * dir->basebuf gets reused by the traversal, but we1250 * need fname to remain unchanged to ensure the src1251 * member of each struct exclude correctly1252 * back-references its source file. Other invocations1253 * of add_exclude_list provide stable strings, so we1254 * strbuf_detach() and free() here in the caller.1255 */1256struct strbuf sb = STRBUF_INIT;1257strbuf_addbuf(&sb, &dir->basebuf);1258strbuf_addstr(&sb, dir->exclude_per_dir);1259 el->src =strbuf_detach(&sb, NULL);1260add_excludes(el->src, el->src, stk->baselen, el,1,1261 untracked ? &sha1_stat : NULL);1262}1263/*1264 * NEEDSWORK: when untracked cache is enabled, prep_exclude()1265 * will first be called in valid_cached_dir() then maybe many1266 * times more in last_exclude_matching(). When the cache is1267 * used, last_exclude_matching() will not be called and1268 * reading .gitignore content will be a waste.1269 *1270 * So when it's called by valid_cached_dir() and we can get1271 * .gitignore SHA-1 from the index (i.e. .gitignore is not1272 * modified on work tree), we could delay reading the1273 * .gitignore content until we absolutely need it in1274 * last_exclude_matching(). Be careful about ignore rule1275 * order, though, if you do that.1276 */1277if(untracked &&1278hashcmp(sha1_stat.sha1, untracked->exclude_sha1)) {1279invalidate_gitignore(dir->untracked, untracked);1280hashcpy(untracked->exclude_sha1, sha1_stat.sha1);1281}1282 dir->exclude_stack = stk;1283 current = stk->baselen;1284}1285strbuf_setlen(&dir->basebuf, baselen);1286}12871288/*1289 * Loads the exclude lists for the directory containing pathname, then1290 * scans all exclude lists to determine whether pathname is excluded.1291 * Returns the exclude_list element which matched, or NULL for1292 * undecided.1293 */1294struct exclude *last_exclude_matching(struct dir_struct *dir,1295const char*pathname,1296int*dtype_p)1297{1298int pathlen =strlen(pathname);1299const char*basename =strrchr(pathname,'/');1300 basename = (basename) ? basename+1: pathname;13011302prep_exclude(dir, pathname, basename-pathname);13031304if(dir->exclude)1305return dir->exclude;13061307returnlast_exclude_matching_from_lists(dir, pathname, pathlen,1308 basename, dtype_p);1309}13101311/*1312 * Loads the exclude lists for the directory containing pathname, then1313 * scans all exclude lists to determine whether pathname is excluded.1314 * Returns 1 if true, otherwise 0.1315 */1316intis_excluded(struct dir_struct *dir,const char*pathname,int*dtype_p)1317{1318struct exclude *exclude =1319last_exclude_matching(dir, pathname, dtype_p);1320if(exclude)1321return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1322return0;1323}13241325static struct dir_entry *dir_entry_new(const char*pathname,int len)1326{1327struct dir_entry *ent;13281329FLEX_ALLOC_MEM(ent, name, pathname, len);1330 ent->len = len;1331return ent;1332}13331334static struct dir_entry *dir_add_name(struct dir_struct *dir,const char*pathname,int len)1335{1336if(cache_file_exists(pathname, len, ignore_case))1337return NULL;13381339ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);1340return dir->entries[dir->nr++] =dir_entry_new(pathname, len);1341}13421343struct dir_entry *dir_add_ignored(struct dir_struct *dir,const char*pathname,int len)1344{1345if(!cache_name_is_other(pathname, len))1346return NULL;13471348ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);1349return dir->ignored[dir->ignored_nr++] =dir_entry_new(pathname, len);1350}13511352enum exist_status {1353 index_nonexistent =0,1354 index_directory,1355 index_gitdir1356};13571358/*1359 * Do not use the alphabetically sorted index to look up1360 * the directory name; instead, use the case insensitive1361 * directory hash.1362 */1363static enum exist_status directory_exists_in_index_icase(const char*dirname,int len)1364{1365struct cache_entry *ce;13661367if(cache_dir_exists(dirname, len))1368return index_directory;13691370 ce =cache_file_exists(dirname, len, ignore_case);1371if(ce &&S_ISGITLINK(ce->ce_mode))1372return index_gitdir;13731374return index_nonexistent;1375}13761377/*1378 * The index sorts alphabetically by entry name, which1379 * means that a gitlink sorts as '\0' at the end, while1380 * a directory (which is defined not as an entry, but as1381 * the files it contains) will sort with the '/' at the1382 * end.1383 */1384static enum exist_status directory_exists_in_index(const char*dirname,int len)1385{1386int pos;13871388if(ignore_case)1389returndirectory_exists_in_index_icase(dirname, len);13901391 pos =cache_name_pos(dirname, len);1392if(pos <0)1393 pos = -pos-1;1394while(pos < active_nr) {1395const struct cache_entry *ce = active_cache[pos++];1396unsigned char endchar;13971398if(strncmp(ce->name, dirname, len))1399break;1400 endchar = ce->name[len];1401if(endchar >'/')1402break;1403if(endchar =='/')1404return index_directory;1405if(!endchar &&S_ISGITLINK(ce->ce_mode))1406return index_gitdir;1407}1408return index_nonexistent;1409}14101411/*1412 * When we find a directory when traversing the filesystem, we1413 * have three distinct cases:1414 *1415 * - ignore it1416 * - see it as a directory1417 * - recurse into it1418 *1419 * and which one we choose depends on a combination of existing1420 * git index contents and the flags passed into the directory1421 * traversal routine.1422 *1423 * Case 1: If we *already* have entries in the index under that1424 * directory name, we always recurse into the directory to see1425 * all the files.1426 *1427 * Case 2: If we *already* have that directory name as a gitlink,1428 * we always continue to see it as a gitlink, regardless of whether1429 * there is an actual git directory there or not (it might not1430 * be checked out as a subproject!)1431 *1432 * Case 3: if we didn't have it in the index previously, we1433 * have a few sub-cases:1434 *1435 * (a) if "show_other_directories" is true, we show it as1436 * just a directory, unless "hide_empty_directories" is1437 * also true, in which case we need to check if it contains any1438 * untracked and / or ignored files.1439 * (b) if it looks like a git directory, and we don't have1440 * 'no_gitlinks' set we treat it as a gitlink, and show it1441 * as a directory.1442 * (c) otherwise, we recurse into it.1443 */1444static enum path_treatment treat_directory(struct dir_struct *dir,1445struct untracked_cache_dir *untracked,1446const char*dirname,int len,int baselen,int exclude,1447const struct path_simplify *simplify)1448{1449/* The "len-1" is to strip the final '/' */1450switch(directory_exists_in_index(dirname, len-1)) {1451case index_directory:1452return path_recurse;14531454case index_gitdir:1455return path_none;14561457case index_nonexistent:1458if(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)1459break;1460if(!(dir->flags & DIR_NO_GITLINKS)) {1461unsigned char sha1[20];1462if(resolve_gitlink_ref(dirname,"HEAD", sha1) ==0)1463return path_untracked;1464}1465return path_recurse;1466}14671468/* This is the "show_other_directories" case */14691470if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1471return exclude ? path_excluded : path_untracked;14721473 untracked =lookup_untracked(dir->untracked, untracked,1474 dirname + baselen, len - baselen);1475returnread_directory_recursive(dir, dirname, len,1476 untracked,1, simplify);1477}14781479/*1480 * This is an inexact early pruning of any recursive directory1481 * reading - if the path cannot possibly be in the pathspec,1482 * return true, and we'll skip it early.1483 */1484static intsimplify_away(const char*path,int pathlen,const struct path_simplify *simplify)1485{1486if(simplify) {1487for(;;) {1488const char*match = simplify->path;1489int len = simplify->len;14901491if(!match)1492break;1493if(len > pathlen)1494 len = pathlen;1495if(!memcmp(path, match, len))1496return0;1497 simplify++;1498}1499return1;1500}1501return0;1502}15031504/*1505 * This function tells us whether an excluded path matches a1506 * list of "interesting" pathspecs. That is, whether a path matched1507 * by any of the pathspecs could possibly be ignored by excluding1508 * the specified path. This can happen if:1509 *1510 * 1. the path is mentioned explicitly in the pathspec1511 *1512 * 2. the path is a directory prefix of some element in the1513 * pathspec1514 */1515static intexclude_matches_pathspec(const char*path,int len,1516const struct path_simplify *simplify)1517{1518if(simplify) {1519for(; simplify->path; simplify++) {1520if(len == simplify->len1521&& !memcmp(path, simplify->path, len))1522return1;1523if(len < simplify->len1524&& simplify->path[len] =='/'1525&& !memcmp(path, simplify->path, len))1526return1;1527}1528}1529return0;1530}15311532static intget_index_dtype(const char*path,int len)1533{1534int pos;1535const struct cache_entry *ce;15361537 ce =cache_file_exists(path, len,0);1538if(ce) {1539if(!ce_uptodate(ce))1540return DT_UNKNOWN;1541if(S_ISGITLINK(ce->ce_mode))1542return DT_DIR;1543/*1544 * Nobody actually cares about the1545 * difference between DT_LNK and DT_REG1546 */1547return DT_REG;1548}15491550/* Try to look it up as a directory */1551 pos =cache_name_pos(path, len);1552if(pos >=0)1553return DT_UNKNOWN;1554 pos = -pos-1;1555while(pos < active_nr) {1556 ce = active_cache[pos++];1557if(strncmp(ce->name, path, len))1558break;1559if(ce->name[len] >'/')1560break;1561if(ce->name[len] <'/')1562continue;1563if(!ce_uptodate(ce))1564break;/* continue? */1565return DT_DIR;1566}1567return DT_UNKNOWN;1568}15691570static intget_dtype(struct dirent *de,const char*path,int len)1571{1572int dtype = de ?DTYPE(de) : DT_UNKNOWN;1573struct stat st;15741575if(dtype != DT_UNKNOWN)1576return dtype;1577 dtype =get_index_dtype(path, len);1578if(dtype != DT_UNKNOWN)1579return dtype;1580if(lstat(path, &st))1581return dtype;1582if(S_ISREG(st.st_mode))1583return DT_REG;1584if(S_ISDIR(st.st_mode))1585return DT_DIR;1586if(S_ISLNK(st.st_mode))1587return DT_LNK;1588return dtype;1589}15901591static enum path_treatment treat_one_path(struct dir_struct *dir,1592struct untracked_cache_dir *untracked,1593struct strbuf *path,1594int baselen,1595const struct path_simplify *simplify,1596int dtype,struct dirent *de)1597{1598int exclude;1599int has_path_in_index = !!cache_file_exists(path->buf, path->len, ignore_case);16001601if(dtype == DT_UNKNOWN)1602 dtype =get_dtype(de, path->buf, path->len);16031604/* Always exclude indexed files */1605if(dtype != DT_DIR && has_path_in_index)1606return path_none;16071608/*1609 * When we are looking at a directory P in the working tree,1610 * there are three cases:1611 *1612 * (1) P exists in the index. Everything inside the directory P in1613 * the working tree needs to go when P is checked out from the1614 * index.1615 *1616 * (2) P does not exist in the index, but there is P/Q in the index.1617 * We know P will stay a directory when we check out the contents1618 * of the index, but we do not know yet if there is a directory1619 * P/Q in the working tree to be killed, so we need to recurse.1620 *1621 * (3) P does not exist in the index, and there is no P/Q in the index1622 * to require P to be a directory, either. Only in this case, we1623 * know that everything inside P will not be killed without1624 * recursing.1625 */1626if((dir->flags & DIR_COLLECT_KILLED_ONLY) &&1627(dtype == DT_DIR) &&1628!has_path_in_index &&1629(directory_exists_in_index(path->buf, path->len) == index_nonexistent))1630return path_none;16311632 exclude =is_excluded(dir, path->buf, &dtype);16331634/*1635 * Excluded? If we don't explicitly want to show1636 * ignored files, ignore it1637 */1638if(exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO)))1639return path_excluded;16401641switch(dtype) {1642default:1643return path_none;1644case DT_DIR:1645strbuf_addch(path,'/');1646returntreat_directory(dir, untracked, path->buf, path->len,1647 baselen, exclude, simplify);1648case DT_REG:1649case DT_LNK:1650return exclude ? path_excluded : path_untracked;1651}1652}16531654static enum path_treatment treat_path_fast(struct dir_struct *dir,1655struct untracked_cache_dir *untracked,1656struct cached_dir *cdir,1657struct strbuf *path,1658int baselen,1659const struct path_simplify *simplify)1660{1661strbuf_setlen(path, baselen);1662if(!cdir->ucd) {1663strbuf_addstr(path, cdir->file);1664return path_untracked;1665}1666strbuf_addstr(path, cdir->ucd->name);1667/* treat_one_path() does this before it calls treat_directory() */1668strbuf_complete(path,'/');1669if(cdir->ucd->check_only)1670/*1671 * check_only is set as a result of treat_directory() getting1672 * to its bottom. Verify again the same set of directories1673 * with check_only set.1674 */1675returnread_directory_recursive(dir, path->buf, path->len,1676 cdir->ucd,1, simplify);1677/*1678 * We get path_recurse in the first run when1679 * directory_exists_in_index() returns index_nonexistent. We1680 * are sure that new changes in the index does not impact the1681 * outcome. Return now.1682 */1683return path_recurse;1684}16851686static enum path_treatment treat_path(struct dir_struct *dir,1687struct untracked_cache_dir *untracked,1688struct cached_dir *cdir,1689struct strbuf *path,1690int baselen,1691const struct path_simplify *simplify)1692{1693int dtype;1694struct dirent *de = cdir->de;16951696if(!de)1697returntreat_path_fast(dir, untracked, cdir, path,1698 baselen, simplify);1699if(is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name,".git"))1700return path_none;1701strbuf_setlen(path, baselen);1702strbuf_addstr(path, de->d_name);1703if(simplify_away(path->buf, path->len, simplify))1704return path_none;17051706 dtype =DTYPE(de);1707returntreat_one_path(dir, untracked, path, baselen, simplify, dtype, de);1708}17091710static voidadd_untracked(struct untracked_cache_dir *dir,const char*name)1711{1712if(!dir)1713return;1714ALLOC_GROW(dir->untracked, dir->untracked_nr +1,1715 dir->untracked_alloc);1716 dir->untracked[dir->untracked_nr++] =xstrdup(name);1717}17181719static intvalid_cached_dir(struct dir_struct *dir,1720struct untracked_cache_dir *untracked,1721struct strbuf *path,1722int check_only)1723{1724struct stat st;17251726if(!untracked)1727return0;17281729if(stat(path->len ? path->buf :".", &st)) {1730invalidate_directory(dir->untracked, untracked);1731memset(&untracked->stat_data,0,sizeof(untracked->stat_data));1732return0;1733}1734if(!untracked->valid ||1735match_stat_data_racy(&the_index, &untracked->stat_data, &st)) {1736if(untracked->valid)1737invalidate_directory(dir->untracked, untracked);1738fill_stat_data(&untracked->stat_data, &st);1739return0;1740}17411742if(untracked->check_only != !!check_only) {1743invalidate_directory(dir->untracked, untracked);1744return0;1745}17461747/*1748 * prep_exclude will be called eventually on this directory,1749 * but it's called much later in last_exclude_matching(). We1750 * need it now to determine the validity of the cache for this1751 * path. The next calls will be nearly no-op, the way1752 * prep_exclude() is designed.1753 */1754if(path->len && path->buf[path->len -1] !='/') {1755strbuf_addch(path,'/');1756prep_exclude(dir, path->buf, path->len);1757strbuf_setlen(path, path->len -1);1758}else1759prep_exclude(dir, path->buf, path->len);17601761/* hopefully prep_exclude() haven't invalidated this entry... */1762return untracked->valid;1763}17641765static intopen_cached_dir(struct cached_dir *cdir,1766struct dir_struct *dir,1767struct untracked_cache_dir *untracked,1768struct strbuf *path,1769int check_only)1770{1771memset(cdir,0,sizeof(*cdir));1772 cdir->untracked = untracked;1773if(valid_cached_dir(dir, untracked, path, check_only))1774return0;1775 cdir->fdir =opendir(path->len ? path->buf :".");1776if(dir->untracked)1777 dir->untracked->dir_opened++;1778if(!cdir->fdir)1779return-1;1780return0;1781}17821783static intread_cached_dir(struct cached_dir *cdir)1784{1785if(cdir->fdir) {1786 cdir->de =readdir(cdir->fdir);1787if(!cdir->de)1788return-1;1789return0;1790}1791while(cdir->nr_dirs < cdir->untracked->dirs_nr) {1792struct untracked_cache_dir *d = cdir->untracked->dirs[cdir->nr_dirs];1793if(!d->recurse) {1794 cdir->nr_dirs++;1795continue;1796}1797 cdir->ucd = d;1798 cdir->nr_dirs++;1799return0;1800}1801 cdir->ucd = NULL;1802if(cdir->nr_files < cdir->untracked->untracked_nr) {1803struct untracked_cache_dir *d = cdir->untracked;1804 cdir->file = d->untracked[cdir->nr_files++];1805return0;1806}1807return-1;1808}18091810static voidclose_cached_dir(struct cached_dir *cdir)1811{1812if(cdir->fdir)1813closedir(cdir->fdir);1814/*1815 * We have gone through this directory and found no untracked1816 * entries. Mark it valid.1817 */1818if(cdir->untracked) {1819 cdir->untracked->valid =1;1820 cdir->untracked->recurse =1;1821}1822}18231824/*1825 * Read a directory tree. We currently ignore anything but1826 * directories, regular files and symlinks. That's because git1827 * doesn't handle them at all yet. Maybe that will change some1828 * day.1829 *1830 * Also, we ignore the name ".git" (even if it is not a directory).1831 * That likely will not change.1832 *1833 * Returns the most significant path_treatment value encountered in the scan.1834 */1835static enum path_treatment read_directory_recursive(struct dir_struct *dir,1836const char*base,int baselen,1837struct untracked_cache_dir *untracked,int check_only,1838const struct path_simplify *simplify)1839{1840struct cached_dir cdir;1841enum path_treatment state, subdir_state, dir_state = path_none;1842struct strbuf path = STRBUF_INIT;1843static int level =0;18441845strbuf_add(&path, base, baselen);18461847trace_printf_key(&trace_exclude,"exclude: [%d] enter '%.*s'\n",1848 level++, baselen, base);18491850if(open_cached_dir(&cdir, dir, untracked, &path, check_only))1851goto out;18521853if(untracked)1854 untracked->check_only = !!check_only;18551856while(!read_cached_dir(&cdir)) {1857/* check how the file or directory should be treated */1858 state =treat_path(dir, untracked, &cdir, &path, baselen, simplify);18591860if(state > dir_state)1861 dir_state = state;18621863/* recurse into subdir if instructed by treat_path */1864if(state == path_recurse) {1865struct untracked_cache_dir *ud;1866 ud =lookup_untracked(dir->untracked, untracked,1867 path.buf + baselen,1868 path.len - baselen);1869 subdir_state =1870read_directory_recursive(dir, path.buf, path.len,1871 ud, check_only, simplify);1872if(subdir_state > dir_state)1873 dir_state = subdir_state;1874}18751876if(check_only) {1877/* abort early if maximum state has been reached */1878if(dir_state == path_untracked) {1879if(cdir.fdir)1880add_untracked(untracked, path.buf + baselen);1881break;1882}1883/* skip the dir_add_* part */1884continue;1885}18861887/* add the path to the appropriate result list */1888switch(state) {1889case path_excluded:1890if(dir->flags & DIR_SHOW_IGNORED)1891dir_add_name(dir, path.buf, path.len);1892else if((dir->flags & DIR_SHOW_IGNORED_TOO) ||1893((dir->flags & DIR_COLLECT_IGNORED) &&1894exclude_matches_pathspec(path.buf, path.len,1895 simplify)))1896dir_add_ignored(dir, path.buf, path.len);1897break;18981899case path_untracked:1900if(dir->flags & DIR_SHOW_IGNORED)1901break;1902dir_add_name(dir, path.buf, path.len);1903if(cdir.fdir)1904add_untracked(untracked, path.buf + baselen);1905break;19061907default:1908break;1909}1910}1911close_cached_dir(&cdir);1912 out:1913trace_printf_key(&trace_exclude,"exclude: [%d] leave '%.*s'\n",1914--level, baselen, base);1915strbuf_release(&path);19161917return dir_state;1918}19191920static intcmp_name(const void*p1,const void*p2)1921{1922const struct dir_entry *e1 = *(const struct dir_entry **)p1;1923const struct dir_entry *e2 = *(const struct dir_entry **)p2;19241925returnname_compare(e1->name, e1->len, e2->name, e2->len);1926}19271928static struct path_simplify *create_simplify(const char**pathspec)1929{1930int nr, alloc =0;1931struct path_simplify *simplify = NULL;19321933if(!pathspec)1934return NULL;19351936for(nr =0; ; nr++) {1937const char*match;1938ALLOC_GROW(simplify, nr +1, alloc);1939 match = *pathspec++;1940if(!match)1941break;1942 simplify[nr].path = match;1943 simplify[nr].len =simple_length(match);1944}1945 simplify[nr].path = NULL;1946 simplify[nr].len =0;1947return simplify;1948}19491950static voidfree_simplify(struct path_simplify *simplify)1951{1952free(simplify);1953}19541955static inttreat_leading_path(struct dir_struct *dir,1956const char*path,int len,1957const struct path_simplify *simplify)1958{1959struct strbuf sb = STRBUF_INIT;1960int baselen, rc =0;1961const char*cp;1962int old_flags = dir->flags;19631964while(len && path[len -1] =='/')1965 len--;1966if(!len)1967return1;1968 baselen =0;1969 dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES;1970while(1) {1971 cp = path + baselen + !!baselen;1972 cp =memchr(cp,'/', path + len - cp);1973if(!cp)1974 baselen = len;1975else1976 baselen = cp - path;1977strbuf_setlen(&sb,0);1978strbuf_add(&sb, path, baselen);1979if(!is_directory(sb.buf))1980break;1981if(simplify_away(sb.buf, sb.len, simplify))1982break;1983if(treat_one_path(dir, NULL, &sb, baselen, simplify,1984 DT_DIR, NULL) == path_none)1985break;/* do not recurse into it */1986if(len <= baselen) {1987 rc =1;1988break;/* finished checking */1989}1990}1991strbuf_release(&sb);1992 dir->flags = old_flags;1993return rc;1994}19951996static const char*get_ident_string(void)1997{1998static struct strbuf sb = STRBUF_INIT;1999struct utsname uts;20002001if(sb.len)2002return sb.buf;2003if(uname(&uts) <0)2004die_errno(_("failed to get kernel name and information"));2005strbuf_addf(&sb,"Location%s, system%s",get_git_work_tree(),2006 uts.sysname);2007return sb.buf;2008}20092010static intident_in_untracked(const struct untracked_cache *uc)2011{2012/*2013 * Previous git versions may have saved many NUL separated2014 * strings in the "ident" field, but it is insane to manage2015 * many locations, so just take care of the first one.2016 */20172018return!strcmp(uc->ident.buf,get_ident_string());2019}20202021static voidset_untracked_ident(struct untracked_cache *uc)2022{2023strbuf_reset(&uc->ident);2024strbuf_addstr(&uc->ident,get_ident_string());20252026/*2027 * This strbuf used to contain a list of NUL separated2028 * strings, so save NUL too for backward compatibility.2029 */2030strbuf_addch(&uc->ident,0);2031}20322033static voidnew_untracked_cache(struct index_state *istate)2034{2035struct untracked_cache *uc =xcalloc(1,sizeof(*uc));2036strbuf_init(&uc->ident,100);2037 uc->exclude_per_dir =".gitignore";2038/* should be the same flags used by git-status */2039 uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;2040set_untracked_ident(uc);2041 istate->untracked = uc;2042 istate->cache_changed |= UNTRACKED_CHANGED;2043}20442045voidadd_untracked_cache(struct index_state *istate)2046{2047if(!istate->untracked) {2048new_untracked_cache(istate);2049}else{2050if(!ident_in_untracked(istate->untracked)) {2051free_untracked_cache(istate->untracked);2052new_untracked_cache(istate);2053}2054}2055}20562057voidremove_untracked_cache(struct index_state *istate)2058{2059if(istate->untracked) {2060free_untracked_cache(istate->untracked);2061 istate->untracked = NULL;2062 istate->cache_changed |= UNTRACKED_CHANGED;2063}2064}20652066static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,2067int base_len,2068const struct pathspec *pathspec)2069{2070struct untracked_cache_dir *root;20712072if(!dir->untracked ||getenv("GIT_DISABLE_UNTRACKED_CACHE"))2073return NULL;20742075/*2076 * We only support $GIT_DIR/info/exclude and core.excludesfile2077 * as the global ignore rule files. Any other additions2078 * (e.g. from command line) invalidate the cache. This2079 * condition also catches running setup_standard_excludes()2080 * before setting dir->untracked!2081 */2082if(dir->unmanaged_exclude_files)2083return NULL;20842085/*2086 * Optimize for the main use case only: whole-tree git2087 * status. More work involved in treat_leading_path() if we2088 * use cache on just a subset of the worktree. pathspec2089 * support could make the matter even worse.2090 */2091if(base_len || (pathspec && pathspec->nr))2092return NULL;20932094/* Different set of flags may produce different results */2095if(dir->flags != dir->untracked->dir_flags ||2096/*2097 * See treat_directory(), case index_nonexistent. Without2098 * this flag, we may need to also cache .git file content2099 * for the resolve_gitlink_ref() call, which we don't.2100 */2101!(dir->flags & DIR_SHOW_OTHER_DIRECTORIES) ||2102/* We don't support collecting ignore files */2103(dir->flags & (DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO |2104 DIR_COLLECT_IGNORED)))2105return NULL;21062107/*2108 * If we use .gitignore in the cache and now you change it to2109 * .gitexclude, everything will go wrong.2110 */2111if(dir->exclude_per_dir != dir->untracked->exclude_per_dir &&2112strcmp(dir->exclude_per_dir, dir->untracked->exclude_per_dir))2113return NULL;21142115/*2116 * EXC_CMDL is not considered in the cache. If people set it,2117 * skip the cache.2118 */2119if(dir->exclude_list_group[EXC_CMDL].nr)2120return NULL;21212122if(!ident_in_untracked(dir->untracked)) {2123warning(_("Untracked cache is disabled on this system or location."));2124return NULL;2125}21262127if(!dir->untracked->root) {2128const int len =sizeof(*dir->untracked->root);2129 dir->untracked->root =xmalloc(len);2130memset(dir->untracked->root,0, len);2131}21322133/* Validate $GIT_DIR/info/exclude and core.excludesfile */2134 root = dir->untracked->root;2135if(hashcmp(dir->ss_info_exclude.sha1,2136 dir->untracked->ss_info_exclude.sha1)) {2137invalidate_gitignore(dir->untracked, root);2138 dir->untracked->ss_info_exclude = dir->ss_info_exclude;2139}2140if(hashcmp(dir->ss_excludes_file.sha1,2141 dir->untracked->ss_excludes_file.sha1)) {2142invalidate_gitignore(dir->untracked, root);2143 dir->untracked->ss_excludes_file = dir->ss_excludes_file;2144}21452146/* Make sure this directory is not dropped out at saving phase */2147 root->recurse =1;2148return root;2149}21502151static voidclear_sticky(struct dir_struct *dir)2152{2153struct exclude_list_group *g;2154struct exclude_list *el;2155struct exclude *x;2156int i, j, k;21572158for(i = EXC_CMDL; i <= EXC_FILE; i++) {2159 g = &dir->exclude_list_group[i];2160for(j = g->nr -1; j >=0; j--) {2161 el = &g->el[j];2162for(k = el->nr -1;0<= k; k--) {2163 x = el->excludes[k];2164string_list_clear(&x->sticky_paths,0);2165}2166}2167}2168}21692170intread_directory(struct dir_struct *dir,const char*path,int len,const struct pathspec *pathspec)2171{2172struct path_simplify *simplify;2173struct untracked_cache_dir *untracked;21742175/*2176 * Check out create_simplify()2177 */2178if(pathspec)2179GUARD_PATHSPEC(pathspec,2180 PATHSPEC_FROMTOP |2181 PATHSPEC_MAXDEPTH |2182 PATHSPEC_LITERAL |2183 PATHSPEC_GLOB |2184 PATHSPEC_ICASE |2185 PATHSPEC_EXCLUDE);21862187if(has_symlink_leading_path(path, len))2188return dir->nr;21892190/*2191 * Stay on the safe side. if read_directory() has run once on2192 * "dir", some sticky flag may have been left. Clear them all.2193 */2194clear_sticky(dir);21952196/*2197 * exclude patterns are treated like positive ones in2198 * create_simplify. Usually exclude patterns should be a2199 * subset of positive ones, which has no impacts on2200 * create_simplify().2201 */2202 simplify =create_simplify(pathspec ? pathspec->_raw : NULL);2203 untracked =validate_untracked_cache(dir, len, pathspec);2204if(!untracked)2205/*2206 * make sure untracked cache code path is disabled,2207 * e.g. prep_exclude()2208 */2209 dir->untracked = NULL;2210if(!len ||treat_leading_path(dir, path, len, simplify))2211read_directory_recursive(dir, path, len, untracked,0, simplify);2212free_simplify(simplify);2213qsort(dir->entries, dir->nr,sizeof(struct dir_entry *), cmp_name);2214qsort(dir->ignored, dir->ignored_nr,sizeof(struct dir_entry *), cmp_name);2215if(dir->untracked) {2216static struct trace_key trace_untracked_stats =TRACE_KEY_INIT(UNTRACKED_STATS);2217trace_printf_key(&trace_untracked_stats,2218"node creation:%u\n"2219"gitignore invalidation:%u\n"2220"directory invalidation:%u\n"2221"opendir:%u\n",2222 dir->untracked->dir_created,2223 dir->untracked->gitignore_invalidated,2224 dir->untracked->dir_invalidated,2225 dir->untracked->dir_opened);2226if(dir->untracked == the_index.untracked &&2227(dir->untracked->dir_opened ||2228 dir->untracked->gitignore_invalidated ||2229 dir->untracked->dir_invalidated))2230 the_index.cache_changed |= UNTRACKED_CHANGED;2231if(dir->untracked != the_index.untracked) {2232free(dir->untracked);2233 dir->untracked = NULL;2234}2235}2236return dir->nr;2237}22382239intfile_exists(const char*f)2240{2241struct stat sb;2242returnlstat(f, &sb) ==0;2243}22442245static intcmp_icase(char a,char b)2246{2247if(a == b)2248return0;2249if(ignore_case)2250returntoupper(a) -toupper(b);2251return a - b;2252}22532254/*2255 * Given two normalized paths (a trailing slash is ok), if subdir is2256 * outside dir, return -1. Otherwise return the offset in subdir that2257 * can be used as relative path to dir.2258 */2259intdir_inside_of(const char*subdir,const char*dir)2260{2261int offset =0;22622263assert(dir && subdir && *dir && *subdir);22642265while(*dir && *subdir && !cmp_icase(*dir, *subdir)) {2266 dir++;2267 subdir++;2268 offset++;2269}22702271/* hel[p]/me vs hel[l]/yeah */2272if(*dir && *subdir)2273return-1;22742275if(!*subdir)2276return!*dir ? offset : -1;/* same dir */22772278/* foo/[b]ar vs foo/[] */2279if(is_dir_sep(dir[-1]))2280returnis_dir_sep(subdir[-1]) ? offset : -1;22812282/* foo[/]bar vs foo[] */2283returnis_dir_sep(*subdir) ? offset +1: -1;2284}22852286intis_inside_dir(const char*dir)2287{2288char*cwd;2289int rc;22902291if(!dir)2292return0;22932294 cwd =xgetcwd();2295 rc = (dir_inside_of(cwd, dir) >=0);2296free(cwd);2297return rc;2298}22992300intis_empty_dir(const char*path)2301{2302DIR*dir =opendir(path);2303struct dirent *e;2304int ret =1;23052306if(!dir)2307return0;23082309while((e =readdir(dir)) != NULL)2310if(!is_dot_or_dotdot(e->d_name)) {2311 ret =0;2312break;2313}23142315closedir(dir);2316return ret;2317}23182319static intremove_dir_recurse(struct strbuf *path,int flag,int*kept_up)2320{2321DIR*dir;2322struct dirent *e;2323int ret =0, original_len = path->len, len, kept_down =0;2324int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);2325int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);2326unsigned char submodule_head[20];23272328if((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&2329!resolve_gitlink_ref(path->buf,"HEAD", submodule_head)) {2330/* Do not descend and nuke a nested git work tree. */2331if(kept_up)2332*kept_up =1;2333return0;2334}23352336 flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;2337 dir =opendir(path->buf);2338if(!dir) {2339if(errno == ENOENT)2340return keep_toplevel ? -1:0;2341else if(errno == EACCES && !keep_toplevel)2342/*2343 * An empty dir could be removable even if it2344 * is unreadable:2345 */2346returnrmdir(path->buf);2347else2348return-1;2349}2350strbuf_complete(path,'/');23512352 len = path->len;2353while((e =readdir(dir)) != NULL) {2354struct stat st;2355if(is_dot_or_dotdot(e->d_name))2356continue;23572358strbuf_setlen(path, len);2359strbuf_addstr(path, e->d_name);2360if(lstat(path->buf, &st)) {2361if(errno == ENOENT)2362/*2363 * file disappeared, which is what we2364 * wanted anyway2365 */2366continue;2367/* fall thru */2368}else if(S_ISDIR(st.st_mode)) {2369if(!remove_dir_recurse(path, flag, &kept_down))2370continue;/* happy */2371}else if(!only_empty &&2372(!unlink(path->buf) || errno == ENOENT)) {2373continue;/* happy, too */2374}23752376/* path too long, stat fails, or non-directory still exists */2377 ret = -1;2378break;2379}2380closedir(dir);23812382strbuf_setlen(path, original_len);2383if(!ret && !keep_toplevel && !kept_down)2384 ret = (!rmdir(path->buf) || errno == ENOENT) ?0: -1;2385else if(kept_up)2386/*2387 * report the uplevel that it is not an error that we2388 * did not rmdir() our directory.2389 */2390*kept_up = !ret;2391return ret;2392}23932394intremove_dir_recursively(struct strbuf *path,int flag)2395{2396returnremove_dir_recurse(path, flag, NULL);2397}23982399staticGIT_PATH_FUNC(git_path_info_exclude,"info/exclude")24002401voidsetup_standard_excludes(struct dir_struct *dir)2402{2403const char*path;24042405 dir->exclude_per_dir =".gitignore";24062407/* core.excludefile defaulting to $XDG_HOME/git/ignore */2408if(!excludes_file)2409 excludes_file =xdg_config_home("ignore");2410if(excludes_file && !access_or_warn(excludes_file, R_OK,0))2411add_excludes_from_file_1(dir, excludes_file,2412 dir->untracked ? &dir->ss_excludes_file : NULL);24132414/* per repository user preference */2415 path =git_path_info_exclude();2416if(!access_or_warn(path, R_OK,0))2417add_excludes_from_file_1(dir, path,2418 dir->untracked ? &dir->ss_info_exclude : NULL);2419}24202421intremove_path(const char*name)2422{2423char*slash;24242425if(unlink(name) && errno != ENOENT && errno != ENOTDIR)2426return-1;24272428 slash =strrchr(name,'/');2429if(slash) {2430char*dirs =xstrdup(name);2431 slash = dirs + (slash - name);2432do{2433*slash ='\0';2434}while(rmdir(dirs) ==0&& (slash =strrchr(dirs,'/')));2435free(dirs);2436}2437return0;2438}24392440/*2441 * Frees memory within dir which was allocated for exclude lists and2442 * the exclude_stack. Does not free dir itself.2443 */2444voidclear_directory(struct dir_struct *dir)2445{2446int i, j;2447struct exclude_list_group *group;2448struct exclude_list *el;2449struct exclude_stack *stk;24502451for(i = EXC_CMDL; i <= EXC_FILE; i++) {2452 group = &dir->exclude_list_group[i];2453for(j =0; j < group->nr; j++) {2454 el = &group->el[j];2455if(i == EXC_DIRS)2456free((char*)el->src);2457clear_exclude_list(el);2458}2459free(group->el);2460}24612462 stk = dir->exclude_stack;2463while(stk) {2464struct exclude_stack *prev = stk->prev;2465free(stk);2466 stk = prev;2467}2468strbuf_release(&dir->basebuf);2469}24702471struct ondisk_untracked_cache {2472struct stat_data info_exclude_stat;2473struct stat_data excludes_file_stat;2474uint32_t dir_flags;2475unsigned char info_exclude_sha1[20];2476unsigned char excludes_file_sha1[20];2477char exclude_per_dir[FLEX_ARRAY];2478};24792480#define ouc_size(len) (offsetof(struct ondisk_untracked_cache, exclude_per_dir) + len + 1)24812482struct write_data {2483int index;/* number of written untracked_cache_dir */2484struct ewah_bitmap *check_only;/* from untracked_cache_dir */2485struct ewah_bitmap *valid;/* from untracked_cache_dir */2486struct ewah_bitmap *sha1_valid;/* set if exclude_sha1 is not null */2487struct strbuf out;2488struct strbuf sb_stat;2489struct strbuf sb_sha1;2490};24912492static voidstat_data_to_disk(struct stat_data *to,const struct stat_data *from)2493{2494 to->sd_ctime.sec =htonl(from->sd_ctime.sec);2495 to->sd_ctime.nsec =htonl(from->sd_ctime.nsec);2496 to->sd_mtime.sec =htonl(from->sd_mtime.sec);2497 to->sd_mtime.nsec =htonl(from->sd_mtime.nsec);2498 to->sd_dev =htonl(from->sd_dev);2499 to->sd_ino =htonl(from->sd_ino);2500 to->sd_uid =htonl(from->sd_uid);2501 to->sd_gid =htonl(from->sd_gid);2502 to->sd_size =htonl(from->sd_size);2503}25042505static voidwrite_one_dir(struct untracked_cache_dir *untracked,2506struct write_data *wd)2507{2508struct stat_data stat_data;2509struct strbuf *out = &wd->out;2510unsigned char intbuf[16];2511unsigned int intlen, value;2512int i = wd->index++;25132514/*2515 * untracked_nr should be reset whenever valid is clear, but2516 * for safety..2517 */2518if(!untracked->valid) {2519 untracked->untracked_nr =0;2520 untracked->check_only =0;2521}25222523if(untracked->check_only)2524ewah_set(wd->check_only, i);2525if(untracked->valid) {2526ewah_set(wd->valid, i);2527stat_data_to_disk(&stat_data, &untracked->stat_data);2528strbuf_add(&wd->sb_stat, &stat_data,sizeof(stat_data));2529}2530if(!is_null_sha1(untracked->exclude_sha1)) {2531ewah_set(wd->sha1_valid, i);2532strbuf_add(&wd->sb_sha1, untracked->exclude_sha1,20);2533}25342535 intlen =encode_varint(untracked->untracked_nr, intbuf);2536strbuf_add(out, intbuf, intlen);25372538/* skip non-recurse directories */2539for(i =0, value =0; i < untracked->dirs_nr; i++)2540if(untracked->dirs[i]->recurse)2541 value++;2542 intlen =encode_varint(value, intbuf);2543strbuf_add(out, intbuf, intlen);25442545strbuf_add(out, untracked->name,strlen(untracked->name) +1);25462547for(i =0; i < untracked->untracked_nr; i++)2548strbuf_add(out, untracked->untracked[i],2549strlen(untracked->untracked[i]) +1);25502551for(i =0; i < untracked->dirs_nr; i++)2552if(untracked->dirs[i]->recurse)2553write_one_dir(untracked->dirs[i], wd);2554}25552556voidwrite_untracked_extension(struct strbuf *out,struct untracked_cache *untracked)2557{2558struct ondisk_untracked_cache *ouc;2559struct write_data wd;2560unsigned char varbuf[16];2561int varint_len;2562size_t len =strlen(untracked->exclude_per_dir);25632564FLEX_ALLOC_MEM(ouc, exclude_per_dir, untracked->exclude_per_dir, len);2565stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat);2566stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat);2567hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.sha1);2568hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.sha1);2569 ouc->dir_flags =htonl(untracked->dir_flags);25702571 varint_len =encode_varint(untracked->ident.len, varbuf);2572strbuf_add(out, varbuf, varint_len);2573strbuf_add(out, untracked->ident.buf, untracked->ident.len);25742575strbuf_add(out, ouc,ouc_size(len));2576free(ouc);2577 ouc = NULL;25782579if(!untracked->root) {2580 varint_len =encode_varint(0, varbuf);2581strbuf_add(out, varbuf, varint_len);2582return;2583}25842585 wd.index =0;2586 wd.check_only =ewah_new();2587 wd.valid =ewah_new();2588 wd.sha1_valid =ewah_new();2589strbuf_init(&wd.out,1024);2590strbuf_init(&wd.sb_stat,1024);2591strbuf_init(&wd.sb_sha1,1024);2592write_one_dir(untracked->root, &wd);25932594 varint_len =encode_varint(wd.index, varbuf);2595strbuf_add(out, varbuf, varint_len);2596strbuf_addbuf(out, &wd.out);2597ewah_serialize_strbuf(wd.valid, out);2598ewah_serialize_strbuf(wd.check_only, out);2599ewah_serialize_strbuf(wd.sha1_valid, out);2600strbuf_addbuf(out, &wd.sb_stat);2601strbuf_addbuf(out, &wd.sb_sha1);2602strbuf_addch(out,'\0');/* safe guard for string lists */26032604ewah_free(wd.valid);2605ewah_free(wd.check_only);2606ewah_free(wd.sha1_valid);2607strbuf_release(&wd.out);2608strbuf_release(&wd.sb_stat);2609strbuf_release(&wd.sb_sha1);2610}26112612static voidfree_untracked(struct untracked_cache_dir *ucd)2613{2614int i;2615if(!ucd)2616return;2617for(i =0; i < ucd->dirs_nr; i++)2618free_untracked(ucd->dirs[i]);2619for(i =0; i < ucd->untracked_nr; i++)2620free(ucd->untracked[i]);2621free(ucd->untracked);2622free(ucd->dirs);2623free(ucd);2624}26252626voidfree_untracked_cache(struct untracked_cache *uc)2627{2628if(uc)2629free_untracked(uc->root);2630free(uc);2631}26322633struct read_data {2634int index;2635struct untracked_cache_dir **ucd;2636struct ewah_bitmap *check_only;2637struct ewah_bitmap *valid;2638struct ewah_bitmap *sha1_valid;2639const unsigned char*data;2640const unsigned char*end;2641};26422643static voidstat_data_from_disk(struct stat_data *to,const struct stat_data *from)2644{2645 to->sd_ctime.sec =get_be32(&from->sd_ctime.sec);2646 to->sd_ctime.nsec =get_be32(&from->sd_ctime.nsec);2647 to->sd_mtime.sec =get_be32(&from->sd_mtime.sec);2648 to->sd_mtime.nsec =get_be32(&from->sd_mtime.nsec);2649 to->sd_dev =get_be32(&from->sd_dev);2650 to->sd_ino =get_be32(&from->sd_ino);2651 to->sd_uid =get_be32(&from->sd_uid);2652 to->sd_gid =get_be32(&from->sd_gid);2653 to->sd_size =get_be32(&from->sd_size);2654}26552656static intread_one_dir(struct untracked_cache_dir **untracked_,2657struct read_data *rd)2658{2659struct untracked_cache_dir ud, *untracked;2660const unsigned char*next, *data = rd->data, *end = rd->end;2661unsigned int value;2662int i, len;26632664memset(&ud,0,sizeof(ud));26652666 next = data;2667 value =decode_varint(&next);2668if(next > end)2669return-1;2670 ud.recurse =1;2671 ud.untracked_alloc = value;2672 ud.untracked_nr = value;2673if(ud.untracked_nr)2674ALLOC_ARRAY(ud.untracked, ud.untracked_nr);2675 data = next;26762677 next = data;2678 ud.dirs_alloc = ud.dirs_nr =decode_varint(&next);2679if(next > end)2680return-1;2681ALLOC_ARRAY(ud.dirs, ud.dirs_nr);2682 data = next;26832684 len =strlen((const char*)data);2685 next = data + len +1;2686if(next > rd->end)2687return-1;2688*untracked_ = untracked =xmalloc(st_add(sizeof(*untracked), len));2689memcpy(untracked, &ud,sizeof(ud));2690memcpy(untracked->name, data, len +1);2691 data = next;26922693for(i =0; i < untracked->untracked_nr; i++) {2694 len =strlen((const char*)data);2695 next = data + len +1;2696if(next > rd->end)2697return-1;2698 untracked->untracked[i] =xstrdup((const char*)data);2699 data = next;2700}27012702 rd->ucd[rd->index++] = untracked;2703 rd->data = data;27042705for(i =0; i < untracked->dirs_nr; i++) {2706 len =read_one_dir(untracked->dirs + i, rd);2707if(len <0)2708return-1;2709}2710return0;2711}27122713static voidset_check_only(size_t pos,void*cb)2714{2715struct read_data *rd = cb;2716struct untracked_cache_dir *ud = rd->ucd[pos];2717 ud->check_only =1;2718}27192720static voidread_stat(size_t pos,void*cb)2721{2722struct read_data *rd = cb;2723struct untracked_cache_dir *ud = rd->ucd[pos];2724if(rd->data +sizeof(struct stat_data) > rd->end) {2725 rd->data = rd->end +1;2726return;2727}2728stat_data_from_disk(&ud->stat_data, (struct stat_data *)rd->data);2729 rd->data +=sizeof(struct stat_data);2730 ud->valid =1;2731}27322733static voidread_sha1(size_t pos,void*cb)2734{2735struct read_data *rd = cb;2736struct untracked_cache_dir *ud = rd->ucd[pos];2737if(rd->data +20> rd->end) {2738 rd->data = rd->end +1;2739return;2740}2741hashcpy(ud->exclude_sha1, rd->data);2742 rd->data +=20;2743}27442745static voidload_sha1_stat(struct sha1_stat *sha1_stat,2746const struct stat_data *stat,2747const unsigned char*sha1)2748{2749stat_data_from_disk(&sha1_stat->stat, stat);2750hashcpy(sha1_stat->sha1, sha1);2751 sha1_stat->valid =1;2752}27532754struct untracked_cache *read_untracked_extension(const void*data,unsigned long sz)2755{2756const struct ondisk_untracked_cache *ouc;2757struct untracked_cache *uc;2758struct read_data rd;2759const unsigned char*next = data, *end = (const unsigned char*)data + sz;2760const char*ident;2761int ident_len, len;27622763if(sz <=1|| end[-1] !='\0')2764return NULL;2765 end--;27662767 ident_len =decode_varint(&next);2768if(next + ident_len > end)2769return NULL;2770 ident = (const char*)next;2771 next += ident_len;27722773 ouc = (const struct ondisk_untracked_cache *)next;2774if(next +ouc_size(0) > end)2775return NULL;27762777 uc =xcalloc(1,sizeof(*uc));2778strbuf_init(&uc->ident, ident_len);2779strbuf_add(&uc->ident, ident, ident_len);2780load_sha1_stat(&uc->ss_info_exclude, &ouc->info_exclude_stat,2781 ouc->info_exclude_sha1);2782load_sha1_stat(&uc->ss_excludes_file, &ouc->excludes_file_stat,2783 ouc->excludes_file_sha1);2784 uc->dir_flags =get_be32(&ouc->dir_flags);2785 uc->exclude_per_dir =xstrdup(ouc->exclude_per_dir);2786/* NUL after exclude_per_dir is covered by sizeof(*ouc) */2787 next +=ouc_size(strlen(ouc->exclude_per_dir));2788if(next >= end)2789goto done2;27902791 len =decode_varint(&next);2792if(next > end || len ==0)2793goto done2;27942795 rd.valid =ewah_new();2796 rd.check_only =ewah_new();2797 rd.sha1_valid =ewah_new();2798 rd.data = next;2799 rd.end = end;2800 rd.index =0;2801ALLOC_ARRAY(rd.ucd, len);28022803if(read_one_dir(&uc->root, &rd) || rd.index != len)2804goto done;28052806 next = rd.data;2807 len =ewah_read_mmap(rd.valid, next, end - next);2808if(len <0)2809goto done;28102811 next += len;2812 len =ewah_read_mmap(rd.check_only, next, end - next);2813if(len <0)2814goto done;28152816 next += len;2817 len =ewah_read_mmap(rd.sha1_valid, next, end - next);2818if(len <0)2819goto done;28202821ewah_each_bit(rd.check_only, set_check_only, &rd);2822 rd.data = next + len;2823ewah_each_bit(rd.valid, read_stat, &rd);2824ewah_each_bit(rd.sha1_valid, read_sha1, &rd);2825 next = rd.data;28262827done:2828free(rd.ucd);2829ewah_free(rd.valid);2830ewah_free(rd.check_only);2831ewah_free(rd.sha1_valid);2832done2:2833if(next != end) {2834free_untracked_cache(uc);2835 uc = NULL;2836}2837return uc;2838}28392840static voidinvalidate_one_directory(struct untracked_cache *uc,2841struct untracked_cache_dir *ucd)2842{2843 uc->dir_invalidated++;2844 ucd->valid =0;2845 ucd->untracked_nr =0;2846}28472848/*2849 * Normally when an entry is added or removed from a directory,2850 * invalidating that directory is enough. No need to touch its2851 * ancestors. When a directory is shown as "foo/bar/" in git-status2852 * however, deleting or adding an entry may have cascading effect.2853 *2854 * Say the "foo/bar/file" has become untracked, we need to tell the2855 * untracked_cache_dir of "foo" that "bar/" is not an untracked2856 * directory any more (because "bar" is managed by foo as an untracked2857 * "file").2858 *2859 * Similarly, if "foo/bar/file" moves from untracked to tracked and it2860 * was the last untracked entry in the entire "foo", we should show2861 * "foo/" instead. Which means we have to invalidate past "bar" up to2862 * "foo".2863 *2864 * This function traverses all directories from root to leaf. If there2865 * is a chance of one of the above cases happening, we invalidate back2866 * to root. Otherwise we just invalidate the leaf. There may be a more2867 * sophisticated way than checking for SHOW_OTHER_DIRECTORIES to2868 * detect these cases and avoid unnecessary invalidation, for example,2869 * checking for the untracked entry named "bar/" in "foo", but for now2870 * stick to something safe and simple.2871 */2872static intinvalidate_one_component(struct untracked_cache *uc,2873struct untracked_cache_dir *dir,2874const char*path,int len)2875{2876const char*rest =strchr(path,'/');28772878if(rest) {2879int component_len = rest - path;2880struct untracked_cache_dir *d =2881lookup_untracked(uc, dir, path, component_len);2882int ret =2883invalidate_one_component(uc, d, rest +1,2884 len - (component_len +1));2885if(ret)2886invalidate_one_directory(uc, dir);2887return ret;2888}28892890invalidate_one_directory(uc, dir);2891return uc->dir_flags & DIR_SHOW_OTHER_DIRECTORIES;2892}28932894voiduntracked_cache_invalidate_path(struct index_state *istate,2895const char*path)2896{2897if(!istate->untracked || !istate->untracked->root)2898return;2899invalidate_one_component(istate->untracked, istate->untracked->root,2900 path,strlen(path));2901}29022903voiduntracked_cache_remove_from_index(struct index_state *istate,2904const char*path)2905{2906untracked_cache_invalidate_path(istate, path);2907}29082909voiduntracked_cache_add_to_index(struct index_state *istate,2910const char*path)2911{2912untracked_cache_invalidate_path(istate, path);2913}