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#define NO_THE_INDEX_COMPATIBILITY_MACROS 11#include"cache.h" 12#include"config.h" 13#include"dir.h" 14#include"object-store.h" 15#include"attr.h" 16#include"refs.h" 17#include"wildmatch.h" 18#include"pathspec.h" 19#include"utf8.h" 20#include"varint.h" 21#include"ewah/ewok.h" 22#include"fsmonitor.h" 23#include"submodule-config.h" 24 25/* 26 * Tells read_directory_recursive how a file or directory should be treated. 27 * Values are ordered by significance, e.g. if a directory contains both 28 * excluded and untracked files, it is listed as untracked because 29 * path_untracked > path_excluded. 30 */ 31enum path_treatment { 32 path_none =0, 33 path_recurse, 34 path_excluded, 35 path_untracked 36}; 37 38/* 39 * Support data structure for our opendir/readdir/closedir wrappers 40 */ 41struct cached_dir { 42DIR*fdir; 43struct untracked_cache_dir *untracked; 44int nr_files; 45int nr_dirs; 46 47struct dirent *de; 48const char*file; 49struct untracked_cache_dir *ucd; 50}; 51 52static enum path_treatment read_directory_recursive(struct dir_struct *dir, 53struct index_state *istate,const char*path,int len, 54struct untracked_cache_dir *untracked, 55int check_only,int stop_at_first_file,const struct pathspec *pathspec); 56static intget_dtype(struct dirent *de,struct index_state *istate, 57const char*path,int len); 58 59intcount_slashes(const char*s) 60{ 61int cnt =0; 62while(*s) 63if(*s++ =='/') 64 cnt++; 65return cnt; 66} 67 68intfspathcmp(const char*a,const char*b) 69{ 70return ignore_case ?strcasecmp(a, b) :strcmp(a, b); 71} 72 73intfspathncmp(const char*a,const char*b,size_t count) 74{ 75return ignore_case ?strncasecmp(a, b, count) :strncmp(a, b, count); 76} 77 78intgit_fnmatch(const struct pathspec_item *item, 79const char*pattern,const char*string, 80int prefix) 81{ 82if(prefix >0) { 83if(ps_strncmp(item, pattern, string, prefix)) 84return WM_NOMATCH; 85 pattern += prefix; 86 string += prefix; 87} 88if(item->flags & PATHSPEC_ONESTAR) { 89int pattern_len =strlen(++pattern); 90int string_len =strlen(string); 91return string_len < pattern_len || 92ps_strcmp(item, pattern, 93 string + string_len - pattern_len); 94} 95if(item->magic & PATHSPEC_GLOB) 96returnwildmatch(pattern, string, 97 WM_PATHNAME | 98(item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0)); 99else 100/* wildmatch has not learned no FNM_PATHNAME mode yet */ 101returnwildmatch(pattern, string, 102 item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0); 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); 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 PATHSPEC_ATTR); 154 155for(n =0; n < pathspec->nr; n++) { 156size_t i =0, len =0, item_len; 157if(pathspec->items[n].magic & PATHSPEC_EXCLUDE) 158continue; 159if(pathspec->items[n].magic & PATHSPEC_ICASE) 160 item_len = pathspec->items[n].prefix; 161else 162 item_len = pathspec->items[n].nowildcard_len; 163while(i < item_len && (n ==0|| i < max)) { 164char c = pathspec->items[n].match[i]; 165if(c != pathspec->items[0].match[i]) 166break; 167if(c =='/') 168 len = i +1; 169 i++; 170} 171if(n ==0|| len < max) { 172 max = len; 173if(!max) 174break; 175} 176} 177return max; 178} 179 180/* 181 * Returns a copy of the longest leading path common among all 182 * pathspecs. 183 */ 184char*common_prefix(const struct pathspec *pathspec) 185{ 186unsigned long len =common_prefix_len(pathspec); 187 188return len ?xmemdupz(pathspec->items[0].match, len) : NULL; 189} 190 191intfill_directory(struct dir_struct *dir, 192struct index_state *istate, 193const struct pathspec *pathspec) 194{ 195const char*prefix; 196size_t prefix_len; 197 198/* 199 * Calculate common prefix for the pathspec, and 200 * use that to optimize the directory walk 201 */ 202 prefix_len =common_prefix_len(pathspec); 203 prefix = prefix_len ? pathspec->items[0].match :""; 204 205/* Read the directory and prune it */ 206read_directory(dir, istate, prefix, prefix_len, pathspec); 207 208return prefix_len; 209} 210 211intwithin_depth(const char*name,int namelen, 212int depth,int max_depth) 213{ 214const char*cp = name, *cpe = name + namelen; 215 216while(cp < cpe) { 217if(*cp++ !='/') 218continue; 219 depth++; 220if(depth > max_depth) 221return0; 222} 223return1; 224} 225 226/* 227 * Read the contents of the blob with the given OID into a buffer. 228 * Append a trailing LF to the end if the last line doesn't have one. 229 * 230 * Returns: 231 * -1 when the OID is invalid or unknown or does not refer to a blob. 232 * 0 when the blob is empty. 233 * 1 along with { data, size } of the (possibly augmented) buffer 234 * when successful. 235 * 236 * Optionally updates the given oid_stat with the given OID (when valid). 237 */ 238static intdo_read_blob(const struct object_id *oid,struct oid_stat *oid_stat, 239size_t*size_out,char**data_out) 240{ 241enum object_type type; 242unsigned long sz; 243char*data; 244 245*size_out =0; 246*data_out = NULL; 247 248 data =read_object_file(oid, &type, &sz); 249if(!data || type != OBJ_BLOB) { 250free(data); 251return-1; 252} 253 254if(oid_stat) { 255memset(&oid_stat->stat,0,sizeof(oid_stat->stat)); 256oidcpy(&oid_stat->oid, oid); 257} 258 259if(sz ==0) { 260free(data); 261return0; 262} 263 264if(data[sz -1] !='\n') { 265 data =xrealloc(data,st_add(sz,1)); 266 data[sz++] ='\n'; 267} 268 269*size_out =xsize_t(sz); 270*data_out = data; 271 272return1; 273} 274 275#define DO_MATCH_EXCLUDE (1<<0) 276#define DO_MATCH_DIRECTORY (1<<1) 277#define DO_MATCH_SUBMODULE (1<<2) 278 279static intmatch_attrs(const struct index_state *istate, 280const char*name,int namelen, 281const struct pathspec_item *item) 282{ 283int i; 284 285git_check_attr(istate, name, item->attr_check); 286for(i =0; i < item->attr_match_nr; i++) { 287const char*value; 288int matched; 289enum attr_match_mode match_mode; 290 291 value = item->attr_check->items[i].value; 292 match_mode = item->attr_match[i].match_mode; 293 294if(ATTR_TRUE(value)) 295 matched = (match_mode == MATCH_SET); 296else if(ATTR_FALSE(value)) 297 matched = (match_mode == MATCH_UNSET); 298else if(ATTR_UNSET(value)) 299 matched = (match_mode == MATCH_UNSPECIFIED); 300else 301 matched = (match_mode == MATCH_VALUE && 302!strcmp(item->attr_match[i].value, value)); 303if(!matched) 304return0; 305} 306 307return1; 308} 309 310/* 311 * Does 'match' match the given name? 312 * A match is found if 313 * 314 * (1) the 'match' string is leading directory of 'name', or 315 * (2) the 'match' string is a wildcard and matches 'name', or 316 * (3) the 'match' string is exactly the same as 'name'. 317 * 318 * and the return value tells which case it was. 319 * 320 * It returns 0 when there is no match. 321 */ 322static intmatch_pathspec_item(const struct index_state *istate, 323const struct pathspec_item *item,int prefix, 324const char*name,int namelen,unsigned flags) 325{ 326/* name/namelen has prefix cut off by caller */ 327const char*match = item->match + prefix; 328int matchlen = item->len - prefix; 329 330/* 331 * The normal call pattern is: 332 * 1. prefix = common_prefix_len(ps); 333 * 2. prune something, or fill_directory 334 * 3. match_pathspec() 335 * 336 * 'prefix' at #1 may be shorter than the command's prefix and 337 * it's ok for #2 to match extra files. Those extras will be 338 * trimmed at #3. 339 * 340 * Suppose the pathspec is 'foo' and '../bar' running from 341 * subdir 'xyz'. The common prefix at #1 will be empty, thanks 342 * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The 343 * user does not want XYZ/foo, only the "foo" part should be 344 * case-insensitive. We need to filter out XYZ/foo here. In 345 * other words, we do not trust the caller on comparing the 346 * prefix part when :(icase) is involved. We do exact 347 * comparison ourselves. 348 * 349 * Normally the caller (common_prefix_len() in fact) does 350 * _exact_ matching on name[-prefix+1..-1] and we do not need 351 * to check that part. Be defensive and check it anyway, in 352 * case common_prefix_len is changed, or a new caller is 353 * introduced that does not use common_prefix_len. 354 * 355 * If the penalty turns out too high when prefix is really 356 * long, maybe change it to 357 * strncmp(match, name, item->prefix - prefix) 358 */ 359if(item->prefix && (item->magic & PATHSPEC_ICASE) && 360strncmp(item->match, name - prefix, item->prefix)) 361return0; 362 363if(item->attr_match_nr && !match_attrs(istate, name, namelen, item)) 364return0; 365 366/* If the match was just the prefix, we matched */ 367if(!*match) 368return MATCHED_RECURSIVELY; 369 370if(matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) { 371if(matchlen == namelen) 372return MATCHED_EXACTLY; 373 374if(match[matchlen-1] =='/'|| name[matchlen] =='/') 375return MATCHED_RECURSIVELY; 376}else if((flags & DO_MATCH_DIRECTORY) && 377 match[matchlen -1] =='/'&& 378 namelen == matchlen -1&& 379!ps_strncmp(item, match, name, namelen)) 380return MATCHED_EXACTLY; 381 382if(item->nowildcard_len < item->len && 383!git_fnmatch(item, match, name, 384 item->nowildcard_len - prefix)) 385return MATCHED_FNMATCH; 386 387/* Perform checks to see if "name" is a super set of the pathspec */ 388if(flags & DO_MATCH_SUBMODULE) { 389/* name is a literal prefix of the pathspec */ 390if((namelen < matchlen) && 391(match[namelen] =='/') && 392!ps_strncmp(item, match, name, namelen)) 393return MATCHED_RECURSIVELY; 394 395/* name" doesn't match up to the first wild character */ 396if(item->nowildcard_len < item->len && 397ps_strncmp(item, match, name, 398 item->nowildcard_len - prefix)) 399return0; 400 401/* 402 * Here is where we would perform a wildmatch to check if 403 * "name" can be matched as a directory (or a prefix) against 404 * the pathspec. Since wildmatch doesn't have this capability 405 * at the present we have to punt and say that it is a match, 406 * potentially returning a false positive 407 * The submodules themselves will be able to perform more 408 * accurate matching to determine if the pathspec matches. 409 */ 410return MATCHED_RECURSIVELY; 411} 412 413return0; 414} 415 416/* 417 * Given a name and a list of pathspecs, returns the nature of the 418 * closest (i.e. most specific) match of the name to any of the 419 * pathspecs. 420 * 421 * The caller typically calls this multiple times with the same 422 * pathspec and seen[] array but with different name/namelen 423 * (e.g. entries from the index) and is interested in seeing if and 424 * how each pathspec matches all the names it calls this function 425 * with. A mark is left in the seen[] array for each pathspec element 426 * indicating the closest type of match that element achieved, so if 427 * seen[n] remains zero after multiple invocations, that means the nth 428 * pathspec did not match any names, which could indicate that the 429 * user mistyped the nth pathspec. 430 */ 431static intdo_match_pathspec(const struct index_state *istate, 432const struct pathspec *ps, 433const char*name,int namelen, 434int prefix,char*seen, 435unsigned flags) 436{ 437int i, retval =0, exclude = flags & DO_MATCH_EXCLUDE; 438 439GUARD_PATHSPEC(ps, 440 PATHSPEC_FROMTOP | 441 PATHSPEC_MAXDEPTH | 442 PATHSPEC_LITERAL | 443 PATHSPEC_GLOB | 444 PATHSPEC_ICASE | 445 PATHSPEC_EXCLUDE | 446 PATHSPEC_ATTR); 447 448if(!ps->nr) { 449if(!ps->recursive || 450!(ps->magic & PATHSPEC_MAXDEPTH) || 451 ps->max_depth == -1) 452return MATCHED_RECURSIVELY; 453 454if(within_depth(name, namelen,0, ps->max_depth)) 455return MATCHED_EXACTLY; 456else 457return0; 458} 459 460 name += prefix; 461 namelen -= prefix; 462 463for(i = ps->nr -1; i >=0; i--) { 464int how; 465 466if((!exclude && ps->items[i].magic & PATHSPEC_EXCLUDE) || 467( exclude && !(ps->items[i].magic & PATHSPEC_EXCLUDE))) 468continue; 469 470if(seen && seen[i] == MATCHED_EXACTLY) 471continue; 472/* 473 * Make exclude patterns optional and never report 474 * "pathspec ':(exclude)foo' matches no files" 475 */ 476if(seen && ps->items[i].magic & PATHSPEC_EXCLUDE) 477 seen[i] = MATCHED_FNMATCH; 478 how =match_pathspec_item(istate, ps->items+i, prefix, name, 479 namelen, flags); 480if(ps->recursive && 481(ps->magic & PATHSPEC_MAXDEPTH) && 482 ps->max_depth != -1&& 483 how && how != MATCHED_FNMATCH) { 484int len = ps->items[i].len; 485if(name[len] =='/') 486 len++; 487if(within_depth(name+len, namelen-len,0, ps->max_depth)) 488 how = MATCHED_EXACTLY; 489else 490 how =0; 491} 492if(how) { 493if(retval < how) 494 retval = how; 495if(seen && seen[i] < how) 496 seen[i] = how; 497} 498} 499return retval; 500} 501 502intmatch_pathspec(const struct index_state *istate, 503const struct pathspec *ps, 504const char*name,int namelen, 505int prefix,char*seen,int is_dir) 506{ 507int positive, negative; 508unsigned flags = is_dir ? DO_MATCH_DIRECTORY :0; 509 positive =do_match_pathspec(istate, ps, name, namelen, 510 prefix, seen, flags); 511if(!(ps->magic & PATHSPEC_EXCLUDE) || !positive) 512return positive; 513 negative =do_match_pathspec(istate, ps, name, namelen, 514 prefix, seen, 515 flags | DO_MATCH_EXCLUDE); 516return negative ?0: positive; 517} 518 519/** 520 * Check if a submodule is a superset of the pathspec 521 */ 522intsubmodule_path_match(const struct index_state *istate, 523const struct pathspec *ps, 524const char*submodule_name, 525char*seen) 526{ 527int matched =do_match_pathspec(istate, ps, submodule_name, 528strlen(submodule_name), 5290, seen, 530 DO_MATCH_DIRECTORY | 531 DO_MATCH_SUBMODULE); 532return matched; 533} 534 535intreport_path_error(const char*ps_matched, 536const struct pathspec *pathspec, 537const char*prefix) 538{ 539/* 540 * Make sure all pathspec matched; otherwise it is an error. 541 */ 542int num, errors =0; 543for(num =0; num < pathspec->nr; num++) { 544int other, found_dup; 545 546if(ps_matched[num]) 547continue; 548/* 549 * The caller might have fed identical pathspec 550 * twice. Do not barf on such a mistake. 551 * FIXME: parse_pathspec should have eliminated 552 * duplicate pathspec. 553 */ 554for(found_dup = other =0; 555!found_dup && other < pathspec->nr; 556 other++) { 557if(other == num || !ps_matched[other]) 558continue; 559if(!strcmp(pathspec->items[other].original, 560 pathspec->items[num].original)) 561/* 562 * Ok, we have a match already. 563 */ 564 found_dup =1; 565} 566if(found_dup) 567continue; 568 569error(_("pathspec '%s' did not match any file(s) known to git"), 570 pathspec->items[num].original); 571 errors++; 572} 573return errors; 574} 575 576/* 577 * Return the length of the "simple" part of a path match limiter. 578 */ 579intsimple_length(const char*match) 580{ 581int len = -1; 582 583for(;;) { 584unsigned char c = *match++; 585 len++; 586if(c =='\0'||is_glob_special(c)) 587return len; 588} 589} 590 591intno_wildcard(const char*string) 592{ 593return string[simple_length(string)] =='\0'; 594} 595 596voidparse_exclude_pattern(const char**pattern, 597int*patternlen, 598unsigned*flags, 599int*nowildcardlen) 600{ 601const char*p = *pattern; 602size_t i, len; 603 604*flags =0; 605if(*p =='!') { 606*flags |= EXC_FLAG_NEGATIVE; 607 p++; 608} 609 len =strlen(p); 610if(len && p[len -1] =='/') { 611 len--; 612*flags |= EXC_FLAG_MUSTBEDIR; 613} 614for(i =0; i < len; i++) { 615if(p[i] =='/') 616break; 617} 618if(i == len) 619*flags |= EXC_FLAG_NODIR; 620*nowildcardlen =simple_length(p); 621/* 622 * we should have excluded the trailing slash from 'p' too, 623 * but that's one more allocation. Instead just make sure 624 * nowildcardlen does not exceed real patternlen 625 */ 626if(*nowildcardlen > len) 627*nowildcardlen = len; 628if(*p =='*'&&no_wildcard(p +1)) 629*flags |= EXC_FLAG_ENDSWITH; 630*pattern = p; 631*patternlen = len; 632} 633 634voidadd_exclude(const char*string,const char*base, 635int baselen,struct exclude_list *el,int srcpos) 636{ 637struct exclude *x; 638int patternlen; 639unsigned flags; 640int nowildcardlen; 641 642parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); 643if(flags & EXC_FLAG_MUSTBEDIR) { 644FLEXPTR_ALLOC_MEM(x, pattern, string, patternlen); 645}else{ 646 x =xmalloc(sizeof(*x)); 647 x->pattern = string; 648} 649 x->patternlen = patternlen; 650 x->nowildcardlen = nowildcardlen; 651 x->base = base; 652 x->baselen = baselen; 653 x->flags = flags; 654 x->srcpos = srcpos; 655ALLOC_GROW(el->excludes, el->nr +1, el->alloc); 656 el->excludes[el->nr++] = x; 657 x->el = el; 658} 659 660static intread_skip_worktree_file_from_index(const struct index_state *istate, 661const char*path, 662size_t*size_out,char**data_out, 663struct oid_stat *oid_stat) 664{ 665int pos, len; 666 667 len =strlen(path); 668 pos =index_name_pos(istate, path, len); 669if(pos <0) 670return-1; 671if(!ce_skip_worktree(istate->cache[pos])) 672return-1; 673 674returndo_read_blob(&istate->cache[pos]->oid, oid_stat, size_out, data_out); 675} 676 677/* 678 * Frees memory within el which was allocated for exclude patterns and 679 * the file buffer. Does not free el itself. 680 */ 681voidclear_exclude_list(struct exclude_list *el) 682{ 683int i; 684 685for(i =0; i < el->nr; i++) 686free(el->excludes[i]); 687free(el->excludes); 688free(el->filebuf); 689 690memset(el,0,sizeof(*el)); 691} 692 693static voidtrim_trailing_spaces(char*buf) 694{ 695char*p, *last_space = NULL; 696 697for(p = buf; *p; p++) 698switch(*p) { 699case' ': 700if(!last_space) 701 last_space = p; 702break; 703case'\\': 704 p++; 705if(!*p) 706return; 707/* fallthrough */ 708default: 709 last_space = NULL; 710} 711 712if(last_space) 713*last_space ='\0'; 714} 715 716/* 717 * Given a subdirectory name and "dir" of the current directory, 718 * search the subdir in "dir" and return it, or create a new one if it 719 * does not exist in "dir". 720 * 721 * If "name" has the trailing slash, it'll be excluded in the search. 722 */ 723static struct untracked_cache_dir *lookup_untracked(struct untracked_cache *uc, 724struct untracked_cache_dir *dir, 725const char*name,int len) 726{ 727int first, last; 728struct untracked_cache_dir *d; 729if(!dir) 730return NULL; 731if(len && name[len -1] =='/') 732 len--; 733 first =0; 734 last = dir->dirs_nr; 735while(last > first) { 736int cmp, next = (last + first) >>1; 737 d = dir->dirs[next]; 738 cmp =strncmp(name, d->name, len); 739if(!cmp &&strlen(d->name) > len) 740 cmp = -1; 741if(!cmp) 742return d; 743if(cmp <0) { 744 last = next; 745continue; 746} 747 first = next+1; 748} 749 750 uc->dir_created++; 751FLEX_ALLOC_MEM(d, name, name, len); 752 753ALLOC_GROW(dir->dirs, dir->dirs_nr +1, dir->dirs_alloc); 754MOVE_ARRAY(dir->dirs + first +1, dir->dirs + first, 755 dir->dirs_nr - first); 756 dir->dirs_nr++; 757 dir->dirs[first] = d; 758return d; 759} 760 761static voiddo_invalidate_gitignore(struct untracked_cache_dir *dir) 762{ 763int i; 764 dir->valid =0; 765 dir->untracked_nr =0; 766for(i =0; i < dir->dirs_nr; i++) 767do_invalidate_gitignore(dir->dirs[i]); 768} 769 770static voidinvalidate_gitignore(struct untracked_cache *uc, 771struct untracked_cache_dir *dir) 772{ 773 uc->gitignore_invalidated++; 774do_invalidate_gitignore(dir); 775} 776 777static voidinvalidate_directory(struct untracked_cache *uc, 778struct untracked_cache_dir *dir) 779{ 780int i; 781 782/* 783 * Invalidation increment here is just roughly correct. If 784 * untracked_nr or any of dirs[].recurse is non-zero, we 785 * should increment dir_invalidated too. But that's more 786 * expensive to do. 787 */ 788if(dir->valid) 789 uc->dir_invalidated++; 790 791 dir->valid =0; 792 dir->untracked_nr =0; 793for(i =0; i < dir->dirs_nr; i++) 794 dir->dirs[i]->recurse =0; 795} 796 797static intadd_excludes_from_buffer(char*buf,size_t size, 798const char*base,int baselen, 799struct exclude_list *el); 800 801/* 802 * Given a file with name "fname", read it (either from disk, or from 803 * an index if 'istate' is non-null), parse it and store the 804 * exclude rules in "el". 805 * 806 * If "ss" is not NULL, compute SHA-1 of the exclude file and fill 807 * stat data from disk (only valid if add_excludes returns zero). If 808 * ss_valid is non-zero, "ss" must contain good value as input. 809 */ 810static intadd_excludes(const char*fname,const char*base,int baselen, 811struct exclude_list *el,struct index_state *istate, 812struct oid_stat *oid_stat) 813{ 814struct stat st; 815int r; 816int fd; 817size_t size =0; 818char*buf; 819 820 fd =open(fname, O_RDONLY); 821if(fd <0||fstat(fd, &st) <0) { 822if(fd <0) 823warn_on_fopen_errors(fname); 824else 825close(fd); 826if(!istate) 827return-1; 828 r =read_skip_worktree_file_from_index(istate, fname, 829&size, &buf, 830 oid_stat); 831if(r !=1) 832return r; 833}else{ 834 size =xsize_t(st.st_size); 835if(size ==0) { 836if(oid_stat) { 837fill_stat_data(&oid_stat->stat, &st); 838oidcpy(&oid_stat->oid, the_hash_algo->empty_blob); 839 oid_stat->valid =1; 840} 841close(fd); 842return0; 843} 844 buf =xmallocz(size); 845if(read_in_full(fd, buf, size) != size) { 846free(buf); 847close(fd); 848return-1; 849} 850 buf[size++] ='\n'; 851close(fd); 852if(oid_stat) { 853int pos; 854if(oid_stat->valid && 855!match_stat_data_racy(istate, &oid_stat->stat, &st)) 856;/* no content change, ss->sha1 still good */ 857else if(istate && 858(pos =index_name_pos(istate, fname,strlen(fname))) >=0&& 859!ce_stage(istate->cache[pos]) && 860ce_uptodate(istate->cache[pos]) && 861!would_convert_to_git(istate, fname)) 862oidcpy(&oid_stat->oid, 863&istate->cache[pos]->oid); 864else 865hash_object_file(buf, size,"blob", 866&oid_stat->oid); 867fill_stat_data(&oid_stat->stat, &st); 868 oid_stat->valid =1; 869} 870} 871 872add_excludes_from_buffer(buf, size, base, baselen, el); 873return0; 874} 875 876static intadd_excludes_from_buffer(char*buf,size_t size, 877const char*base,int baselen, 878struct exclude_list *el) 879{ 880int i, lineno =1; 881char*entry; 882 883 el->filebuf = buf; 884 885if(skip_utf8_bom(&buf, size)) 886 size -= buf - el->filebuf; 887 888 entry = buf; 889 890for(i =0; i < size; i++) { 891if(buf[i] =='\n') { 892if(entry != buf + i && entry[0] !='#') { 893 buf[i - (i && buf[i-1] =='\r')] =0; 894trim_trailing_spaces(entry); 895add_exclude(entry, base, baselen, el, lineno); 896} 897 lineno++; 898 entry = buf + i +1; 899} 900} 901return0; 902} 903 904intadd_excludes_from_file_to_list(const char*fname,const char*base, 905int baselen,struct exclude_list *el, 906struct index_state *istate) 907{ 908returnadd_excludes(fname, base, baselen, el, istate, NULL); 909} 910 911intadd_excludes_from_blob_to_list( 912struct object_id *oid, 913const char*base,int baselen, 914struct exclude_list *el) 915{ 916char*buf; 917size_t size; 918int r; 919 920 r =do_read_blob(oid, NULL, &size, &buf); 921if(r !=1) 922return r; 923 924add_excludes_from_buffer(buf, size, base, baselen, el); 925return0; 926} 927 928struct exclude_list *add_exclude_list(struct dir_struct *dir, 929int group_type,const char*src) 930{ 931struct exclude_list *el; 932struct exclude_list_group *group; 933 934 group = &dir->exclude_list_group[group_type]; 935ALLOC_GROW(group->el, group->nr +1, group->alloc); 936 el = &group->el[group->nr++]; 937memset(el,0,sizeof(*el)); 938 el->src = src; 939return el; 940} 941 942/* 943 * Used to set up core.excludesfile and .git/info/exclude lists. 944 */ 945static voidadd_excludes_from_file_1(struct dir_struct *dir,const char*fname, 946struct oid_stat *oid_stat) 947{ 948struct exclude_list *el; 949/* 950 * catch setup_standard_excludes() that's called before 951 * dir->untracked is assigned. That function behaves 952 * differently when dir->untracked is non-NULL. 953 */ 954if(!dir->untracked) 955 dir->unmanaged_exclude_files++; 956 el =add_exclude_list(dir, EXC_FILE, fname); 957if(add_excludes(fname,"",0, el, NULL, oid_stat) <0) 958die(_("cannot use%sas an exclude file"), fname); 959} 960 961voidadd_excludes_from_file(struct dir_struct *dir,const char*fname) 962{ 963 dir->unmanaged_exclude_files++;/* see validate_untracked_cache() */ 964add_excludes_from_file_1(dir, fname, NULL); 965} 966 967intmatch_basename(const char*basename,int basenamelen, 968const char*pattern,int prefix,int patternlen, 969unsigned flags) 970{ 971if(prefix == patternlen) { 972if(patternlen == basenamelen && 973!fspathncmp(pattern, basename, basenamelen)) 974return1; 975}else if(flags & EXC_FLAG_ENDSWITH) { 976/* "*literal" matching against "fooliteral" */ 977if(patternlen -1<= basenamelen && 978!fspathncmp(pattern +1, 979 basename + basenamelen - (patternlen -1), 980 patternlen -1)) 981return1; 982}else{ 983if(fnmatch_icase_mem(pattern, patternlen, 984 basename, basenamelen, 9850) ==0) 986return1; 987} 988return0; 989} 990 991intmatch_pathname(const char*pathname,int pathlen, 992const char*base,int baselen, 993const char*pattern,int prefix,int patternlen, 994unsigned flags) 995{ 996const char*name; 997int namelen; 998 999/*1000 * match with FNM_PATHNAME; the pattern has base implicitly1001 * in front of it.1002 */1003if(*pattern =='/') {1004 pattern++;1005 patternlen--;1006 prefix--;1007}10081009/*1010 * baselen does not count the trailing slash. base[] may or1011 * may not end with a trailing slash though.1012 */1013if(pathlen < baselen +1||1014(baselen && pathname[baselen] !='/') ||1015fspathncmp(pathname, base, baselen))1016return0;10171018 namelen = baselen ? pathlen - baselen -1: pathlen;1019 name = pathname + pathlen - namelen;10201021if(prefix) {1022/*1023 * if the non-wildcard part is longer than the1024 * remaining pathname, surely it cannot match.1025 */1026if(prefix > namelen)1027return0;10281029if(fspathncmp(pattern, name, prefix))1030return0;1031 pattern += prefix;1032 patternlen -= prefix;1033 name += prefix;1034 namelen -= prefix;10351036/*1037 * If the whole pattern did not have a wildcard,1038 * then our prefix match is all we need; we1039 * do not need to call fnmatch at all.1040 */1041if(!patternlen && !namelen)1042return1;1043}10441045returnfnmatch_icase_mem(pattern, patternlen,1046 name, namelen,1047 WM_PATHNAME) ==0;1048}10491050/*1051 * Scan the given exclude list in reverse to see whether pathname1052 * should be ignored. The first match (i.e. the last on the list), if1053 * any, determines the fate. Returns the exclude_list element which1054 * matched, or NULL for undecided.1055 */1056static struct exclude *last_exclude_matching_from_list(const char*pathname,1057int pathlen,1058const char*basename,1059int*dtype,1060struct exclude_list *el,1061struct index_state *istate)1062{1063struct exclude *exc = NULL;/* undecided */1064int i;10651066if(!el->nr)1067return NULL;/* undefined */10681069for(i = el->nr -1;0<= i; i--) {1070struct exclude *x = el->excludes[i];1071const char*exclude = x->pattern;1072int prefix = x->nowildcardlen;10731074if(x->flags & EXC_FLAG_MUSTBEDIR) {1075if(*dtype == DT_UNKNOWN)1076*dtype =get_dtype(NULL, istate, pathname, pathlen);1077if(*dtype != DT_DIR)1078continue;1079}10801081if(x->flags & EXC_FLAG_NODIR) {1082if(match_basename(basename,1083 pathlen - (basename - pathname),1084 exclude, prefix, x->patternlen,1085 x->flags)) {1086 exc = x;1087break;1088}1089continue;1090}10911092assert(x->baselen ==0|| x->base[x->baselen -1] =='/');1093if(match_pathname(pathname, pathlen,1094 x->base, x->baselen ? x->baselen -1:0,1095 exclude, prefix, x->patternlen, x->flags)) {1096 exc = x;1097break;1098}1099}1100return exc;1101}11021103/*1104 * Scan the list and let the last match determine the fate.1105 * Return 1 for exclude, 0 for include and -1 for undecided.1106 */1107intis_excluded_from_list(const char*pathname,1108int pathlen,const char*basename,int*dtype,1109struct exclude_list *el,struct index_state *istate)1110{1111struct exclude *exclude;1112 exclude =last_exclude_matching_from_list(pathname, pathlen, basename,1113 dtype, el, istate);1114if(exclude)1115return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1116return-1;/* undecided */1117}11181119static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,1120struct index_state *istate,1121const char*pathname,int pathlen,const char*basename,1122int*dtype_p)1123{1124int i, j;1125struct exclude_list_group *group;1126struct exclude *exclude;1127for(i = EXC_CMDL; i <= EXC_FILE; i++) {1128 group = &dir->exclude_list_group[i];1129for(j = group->nr -1; j >=0; j--) {1130 exclude =last_exclude_matching_from_list(1131 pathname, pathlen, basename, dtype_p,1132&group->el[j], istate);1133if(exclude)1134return exclude;1135}1136}1137return NULL;1138}11391140/*1141 * Loads the per-directory exclude list for the substring of base1142 * which has a char length of baselen.1143 */1144static voidprep_exclude(struct dir_struct *dir,1145struct index_state *istate,1146const char*base,int baselen)1147{1148struct exclude_list_group *group;1149struct exclude_list *el;1150struct exclude_stack *stk = NULL;1151struct untracked_cache_dir *untracked;1152int current;11531154 group = &dir->exclude_list_group[EXC_DIRS];11551156/*1157 * Pop the exclude lists from the EXCL_DIRS exclude_list_group1158 * which originate from directories not in the prefix of the1159 * path being checked.1160 */1161while((stk = dir->exclude_stack) != NULL) {1162if(stk->baselen <= baselen &&1163!strncmp(dir->basebuf.buf, base, stk->baselen))1164break;1165 el = &group->el[dir->exclude_stack->exclude_ix];1166 dir->exclude_stack = stk->prev;1167 dir->exclude = NULL;1168free((char*)el->src);/* see strbuf_detach() below */1169clear_exclude_list(el);1170free(stk);1171 group->nr--;1172}11731174/* Skip traversing into sub directories if the parent is excluded */1175if(dir->exclude)1176return;11771178/*1179 * Lazy initialization. All call sites currently just1180 * memset(dir, 0, sizeof(*dir)) before use. Changing all of1181 * them seems lots of work for little benefit.1182 */1183if(!dir->basebuf.buf)1184strbuf_init(&dir->basebuf, PATH_MAX);11851186/* Read from the parent directories and push them down. */1187 current = stk ? stk->baselen : -1;1188strbuf_setlen(&dir->basebuf, current <0?0: current);1189if(dir->untracked)1190 untracked = stk ? stk->ucd : dir->untracked->root;1191else1192 untracked = NULL;11931194while(current < baselen) {1195const char*cp;1196struct oid_stat oid_stat;11971198 stk =xcalloc(1,sizeof(*stk));1199if(current <0) {1200 cp = base;1201 current =0;1202}else{1203 cp =strchr(base + current +1,'/');1204if(!cp)1205die("oops in prep_exclude");1206 cp++;1207 untracked =1208lookup_untracked(dir->untracked, untracked,1209 base + current,1210 cp - base - current);1211}1212 stk->prev = dir->exclude_stack;1213 stk->baselen = cp - base;1214 stk->exclude_ix = group->nr;1215 stk->ucd = untracked;1216 el =add_exclude_list(dir, EXC_DIRS, NULL);1217strbuf_add(&dir->basebuf, base + current, stk->baselen - current);1218assert(stk->baselen == dir->basebuf.len);12191220/* Abort if the directory is excluded */1221if(stk->baselen) {1222int dt = DT_DIR;1223 dir->basebuf.buf[stk->baselen -1] =0;1224 dir->exclude =last_exclude_matching_from_lists(dir,1225 istate,1226 dir->basebuf.buf, stk->baselen -1,1227 dir->basebuf.buf + current, &dt);1228 dir->basebuf.buf[stk->baselen -1] ='/';1229if(dir->exclude &&1230 dir->exclude->flags & EXC_FLAG_NEGATIVE)1231 dir->exclude = NULL;1232if(dir->exclude) {1233 dir->exclude_stack = stk;1234return;1235}1236}12371238/* Try to read per-directory file */1239oidclr(&oid_stat.oid);1240 oid_stat.valid =0;1241if(dir->exclude_per_dir &&1242/*1243 * If we know that no files have been added in1244 * this directory (i.e. valid_cached_dir() has1245 * been executed and set untracked->valid) ..1246 */1247(!untracked || !untracked->valid ||1248/*1249 * .. and .gitignore does not exist before1250 * (i.e. null exclude_oid). Then we can skip1251 * loading .gitignore, which would result in1252 * ENOENT anyway.1253 */1254!is_null_oid(&untracked->exclude_oid))) {1255/*1256 * dir->basebuf gets reused by the traversal, but we1257 * need fname to remain unchanged to ensure the src1258 * member of each struct exclude correctly1259 * back-references its source file. Other invocations1260 * of add_exclude_list provide stable strings, so we1261 * strbuf_detach() and free() here in the caller.1262 */1263struct strbuf sb = STRBUF_INIT;1264strbuf_addbuf(&sb, &dir->basebuf);1265strbuf_addstr(&sb, dir->exclude_per_dir);1266 el->src =strbuf_detach(&sb, NULL);1267add_excludes(el->src, el->src, stk->baselen, el, istate,1268 untracked ? &oid_stat : NULL);1269}1270/*1271 * NEEDSWORK: when untracked cache is enabled, prep_exclude()1272 * will first be called in valid_cached_dir() then maybe many1273 * times more in last_exclude_matching(). When the cache is1274 * used, last_exclude_matching() will not be called and1275 * reading .gitignore content will be a waste.1276 *1277 * So when it's called by valid_cached_dir() and we can get1278 * .gitignore SHA-1 from the index (i.e. .gitignore is not1279 * modified on work tree), we could delay reading the1280 * .gitignore content until we absolutely need it in1281 * last_exclude_matching(). Be careful about ignore rule1282 * order, though, if you do that.1283 */1284if(untracked &&1285oidcmp(&oid_stat.oid, &untracked->exclude_oid)) {1286invalidate_gitignore(dir->untracked, untracked);1287oidcpy(&untracked->exclude_oid, &oid_stat.oid);1288}1289 dir->exclude_stack = stk;1290 current = stk->baselen;1291}1292strbuf_setlen(&dir->basebuf, baselen);1293}12941295/*1296 * Loads the exclude lists for the directory containing pathname, then1297 * scans all exclude lists to determine whether pathname is excluded.1298 * Returns the exclude_list element which matched, or NULL for1299 * undecided.1300 */1301struct exclude *last_exclude_matching(struct dir_struct *dir,1302struct index_state *istate,1303const char*pathname,1304int*dtype_p)1305{1306int pathlen =strlen(pathname);1307const char*basename =strrchr(pathname,'/');1308 basename = (basename) ? basename+1: pathname;13091310prep_exclude(dir, istate, pathname, basename-pathname);13111312if(dir->exclude)1313return dir->exclude;13141315returnlast_exclude_matching_from_lists(dir, istate, pathname, pathlen,1316 basename, dtype_p);1317}13181319/*1320 * Loads the exclude lists for the directory containing pathname, then1321 * scans all exclude lists to determine whether pathname is excluded.1322 * Returns 1 if true, otherwise 0.1323 */1324intis_excluded(struct dir_struct *dir,struct index_state *istate,1325const char*pathname,int*dtype_p)1326{1327struct exclude *exclude =1328last_exclude_matching(dir, istate, pathname, dtype_p);1329if(exclude)1330return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1331return0;1332}13331334static struct dir_entry *dir_entry_new(const char*pathname,int len)1335{1336struct dir_entry *ent;13371338FLEX_ALLOC_MEM(ent, name, pathname, len);1339 ent->len = len;1340return ent;1341}13421343static struct dir_entry *dir_add_name(struct dir_struct *dir,1344struct index_state *istate,1345const char*pathname,int len)1346{1347if(index_file_exists(istate, pathname, len, ignore_case))1348return NULL;13491350ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);1351return dir->entries[dir->nr++] =dir_entry_new(pathname, len);1352}13531354struct dir_entry *dir_add_ignored(struct dir_struct *dir,1355struct index_state *istate,1356const char*pathname,int len)1357{1358if(!index_name_is_other(istate, pathname, len))1359return NULL;13601361ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);1362return dir->ignored[dir->ignored_nr++] =dir_entry_new(pathname, len);1363}13641365enum exist_status {1366 index_nonexistent =0,1367 index_directory,1368 index_gitdir1369};13701371/*1372 * Do not use the alphabetically sorted index to look up1373 * the directory name; instead, use the case insensitive1374 * directory hash.1375 */1376static enum exist_status directory_exists_in_index_icase(struct index_state *istate,1377const char*dirname,int len)1378{1379struct cache_entry *ce;13801381if(index_dir_exists(istate, dirname, len))1382return index_directory;13831384 ce =index_file_exists(istate, dirname, len, ignore_case);1385if(ce &&S_ISGITLINK(ce->ce_mode))1386return index_gitdir;13871388return index_nonexistent;1389}13901391/*1392 * The index sorts alphabetically by entry name, which1393 * means that a gitlink sorts as '\0' at the end, while1394 * a directory (which is defined not as an entry, but as1395 * the files it contains) will sort with the '/' at the1396 * end.1397 */1398static enum exist_status directory_exists_in_index(struct index_state *istate,1399const char*dirname,int len)1400{1401int pos;14021403if(ignore_case)1404returndirectory_exists_in_index_icase(istate, dirname, len);14051406 pos =index_name_pos(istate, dirname, len);1407if(pos <0)1408 pos = -pos-1;1409while(pos < istate->cache_nr) {1410const struct cache_entry *ce = istate->cache[pos++];1411unsigned char endchar;14121413if(strncmp(ce->name, dirname, len))1414break;1415 endchar = ce->name[len];1416if(endchar >'/')1417break;1418if(endchar =='/')1419return index_directory;1420if(!endchar &&S_ISGITLINK(ce->ce_mode))1421return index_gitdir;1422}1423return index_nonexistent;1424}14251426/*1427 * When we find a directory when traversing the filesystem, we1428 * have three distinct cases:1429 *1430 * - ignore it1431 * - see it as a directory1432 * - recurse into it1433 *1434 * and which one we choose depends on a combination of existing1435 * git index contents and the flags passed into the directory1436 * traversal routine.1437 *1438 * Case 1: If we *already* have entries in the index under that1439 * directory name, we always recurse into the directory to see1440 * all the files.1441 *1442 * Case 2: If we *already* have that directory name as a gitlink,1443 * we always continue to see it as a gitlink, regardless of whether1444 * there is an actual git directory there or not (it might not1445 * be checked out as a subproject!)1446 *1447 * Case 3: if we didn't have it in the index previously, we1448 * have a few sub-cases:1449 *1450 * (a) if "show_other_directories" is true, we show it as1451 * just a directory, unless "hide_empty_directories" is1452 * also true, in which case we need to check if it contains any1453 * untracked and / or ignored files.1454 * (b) if it looks like a git directory, and we don't have1455 * 'no_gitlinks' set we treat it as a gitlink, and show it1456 * as a directory.1457 * (c) otherwise, we recurse into it.1458 */1459static enum path_treatment treat_directory(struct dir_struct *dir,1460struct index_state *istate,1461struct untracked_cache_dir *untracked,1462const char*dirname,int len,int baselen,int exclude,1463const struct pathspec *pathspec)1464{1465/* The "len-1" is to strip the final '/' */1466switch(directory_exists_in_index(istate, dirname, len-1)) {1467case index_directory:1468return path_recurse;14691470case index_gitdir:1471return path_none;14721473case index_nonexistent:1474if(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)1475break;1476if(exclude &&1477(dir->flags & DIR_SHOW_IGNORED_TOO) &&1478(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING)) {14791480/*1481 * This is an excluded directory and we are1482 * showing ignored paths that match an exclude1483 * pattern. (e.g. show directory as ignored1484 * only if it matches an exclude pattern).1485 * This path will either be 'path_excluded`1486 * (if we are showing empty directories or if1487 * the directory is not empty), or will be1488 * 'path_none' (empty directory, and we are1489 * not showing empty directories).1490 */1491if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1492return path_excluded;14931494if(read_directory_recursive(dir, istate, dirname, len,1495 untracked,1,1, pathspec) == path_excluded)1496return path_excluded;14971498return path_none;1499}1500if(!(dir->flags & DIR_NO_GITLINKS)) {1501struct object_id oid;1502if(resolve_gitlink_ref(dirname,"HEAD", &oid) ==0)1503return exclude ? path_excluded : path_untracked;1504}1505return path_recurse;1506}15071508/* This is the "show_other_directories" case */15091510if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1511return exclude ? path_excluded : path_untracked;15121513 untracked =lookup_untracked(dir->untracked, untracked,1514 dirname + baselen, len - baselen);15151516/*1517 * If this is an excluded directory, then we only need to check if1518 * the directory contains any files.1519 */1520returnread_directory_recursive(dir, istate, dirname, len,1521 untracked,1, exclude, pathspec);1522}15231524/*1525 * This is an inexact early pruning of any recursive directory1526 * reading - if the path cannot possibly be in the pathspec,1527 * return true, and we'll skip it early.1528 */1529static intsimplify_away(const char*path,int pathlen,1530const struct pathspec *pathspec)1531{1532int i;15331534if(!pathspec || !pathspec->nr)1535return0;15361537GUARD_PATHSPEC(pathspec,1538 PATHSPEC_FROMTOP |1539 PATHSPEC_MAXDEPTH |1540 PATHSPEC_LITERAL |1541 PATHSPEC_GLOB |1542 PATHSPEC_ICASE |1543 PATHSPEC_EXCLUDE |1544 PATHSPEC_ATTR);15451546for(i =0; i < pathspec->nr; i++) {1547const struct pathspec_item *item = &pathspec->items[i];1548int len = item->nowildcard_len;15491550if(len > pathlen)1551 len = pathlen;1552if(!ps_strncmp(item, item->match, path, len))1553return0;1554}15551556return1;1557}15581559/*1560 * This function tells us whether an excluded path matches a1561 * list of "interesting" pathspecs. That is, whether a path matched1562 * by any of the pathspecs could possibly be ignored by excluding1563 * the specified path. This can happen if:1564 *1565 * 1. the path is mentioned explicitly in the pathspec1566 *1567 * 2. the path is a directory prefix of some element in the1568 * pathspec1569 */1570static intexclude_matches_pathspec(const char*path,int pathlen,1571const struct pathspec *pathspec)1572{1573int i;15741575if(!pathspec || !pathspec->nr)1576return0;15771578GUARD_PATHSPEC(pathspec,1579 PATHSPEC_FROMTOP |1580 PATHSPEC_MAXDEPTH |1581 PATHSPEC_LITERAL |1582 PATHSPEC_GLOB |1583 PATHSPEC_ICASE |1584 PATHSPEC_EXCLUDE);15851586for(i =0; i < pathspec->nr; i++) {1587const struct pathspec_item *item = &pathspec->items[i];1588int len = item->nowildcard_len;15891590if(len == pathlen &&1591!ps_strncmp(item, item->match, path, pathlen))1592return1;1593if(len > pathlen &&1594 item->match[pathlen] =='/'&&1595!ps_strncmp(item, item->match, path, pathlen))1596return1;1597}1598return0;1599}16001601static intget_index_dtype(struct index_state *istate,1602const char*path,int len)1603{1604int pos;1605const struct cache_entry *ce;16061607 ce =index_file_exists(istate, path, len,0);1608if(ce) {1609if(!ce_uptodate(ce))1610return DT_UNKNOWN;1611if(S_ISGITLINK(ce->ce_mode))1612return DT_DIR;1613/*1614 * Nobody actually cares about the1615 * difference between DT_LNK and DT_REG1616 */1617return DT_REG;1618}16191620/* Try to look it up as a directory */1621 pos =index_name_pos(istate, path, len);1622if(pos >=0)1623return DT_UNKNOWN;1624 pos = -pos-1;1625while(pos < istate->cache_nr) {1626 ce = istate->cache[pos++];1627if(strncmp(ce->name, path, len))1628break;1629if(ce->name[len] >'/')1630break;1631if(ce->name[len] <'/')1632continue;1633if(!ce_uptodate(ce))1634break;/* continue? */1635return DT_DIR;1636}1637return DT_UNKNOWN;1638}16391640static intget_dtype(struct dirent *de,struct index_state *istate,1641const char*path,int len)1642{1643int dtype = de ?DTYPE(de) : DT_UNKNOWN;1644struct stat st;16451646if(dtype != DT_UNKNOWN)1647return dtype;1648 dtype =get_index_dtype(istate, path, len);1649if(dtype != DT_UNKNOWN)1650return dtype;1651if(lstat(path, &st))1652return dtype;1653if(S_ISREG(st.st_mode))1654return DT_REG;1655if(S_ISDIR(st.st_mode))1656return DT_DIR;1657if(S_ISLNK(st.st_mode))1658return DT_LNK;1659return dtype;1660}16611662static enum path_treatment treat_one_path(struct dir_struct *dir,1663struct untracked_cache_dir *untracked,1664struct index_state *istate,1665struct strbuf *path,1666int baselen,1667const struct pathspec *pathspec,1668int dtype,struct dirent *de)1669{1670int exclude;1671int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);1672enum path_treatment path_treatment;16731674if(dtype == DT_UNKNOWN)1675 dtype =get_dtype(de, istate, path->buf, path->len);16761677/* Always exclude indexed files */1678if(dtype != DT_DIR && has_path_in_index)1679return path_none;16801681/*1682 * When we are looking at a directory P in the working tree,1683 * there are three cases:1684 *1685 * (1) P exists in the index. Everything inside the directory P in1686 * the working tree needs to go when P is checked out from the1687 * index.1688 *1689 * (2) P does not exist in the index, but there is P/Q in the index.1690 * We know P will stay a directory when we check out the contents1691 * of the index, but we do not know yet if there is a directory1692 * P/Q in the working tree to be killed, so we need to recurse.1693 *1694 * (3) P does not exist in the index, and there is no P/Q in the index1695 * to require P to be a directory, either. Only in this case, we1696 * know that everything inside P will not be killed without1697 * recursing.1698 */1699if((dir->flags & DIR_COLLECT_KILLED_ONLY) &&1700(dtype == DT_DIR) &&1701!has_path_in_index &&1702(directory_exists_in_index(istate, path->buf, path->len) == index_nonexistent))1703return path_none;17041705 exclude =is_excluded(dir, istate, path->buf, &dtype);17061707/*1708 * Excluded? If we don't explicitly want to show1709 * ignored files, ignore it1710 */1711if(exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO)))1712return path_excluded;17131714switch(dtype) {1715default:1716return path_none;1717case DT_DIR:1718strbuf_addch(path,'/');1719 path_treatment =treat_directory(dir, istate, untracked,1720 path->buf, path->len,1721 baselen, exclude, pathspec);1722/*1723 * If 1) we only want to return directories that1724 * match an exclude pattern and 2) this directory does1725 * not match an exclude pattern but all of its1726 * contents are excluded, then indicate that we should1727 * recurse into this directory (instead of marking the1728 * directory itself as an ignored path).1729 */1730if(!exclude &&1731 path_treatment == path_excluded &&1732(dir->flags & DIR_SHOW_IGNORED_TOO) &&1733(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING))1734return path_recurse;1735return path_treatment;1736case DT_REG:1737case DT_LNK:1738return exclude ? path_excluded : path_untracked;1739}1740}17411742static enum path_treatment treat_path_fast(struct dir_struct *dir,1743struct untracked_cache_dir *untracked,1744struct cached_dir *cdir,1745struct index_state *istate,1746struct strbuf *path,1747int baselen,1748const struct pathspec *pathspec)1749{1750strbuf_setlen(path, baselen);1751if(!cdir->ucd) {1752strbuf_addstr(path, cdir->file);1753return path_untracked;1754}1755strbuf_addstr(path, cdir->ucd->name);1756/* treat_one_path() does this before it calls treat_directory() */1757strbuf_complete(path,'/');1758if(cdir->ucd->check_only)1759/*1760 * check_only is set as a result of treat_directory() getting1761 * to its bottom. Verify again the same set of directories1762 * with check_only set.1763 */1764returnread_directory_recursive(dir, istate, path->buf, path->len,1765 cdir->ucd,1,0, pathspec);1766/*1767 * We get path_recurse in the first run when1768 * directory_exists_in_index() returns index_nonexistent. We1769 * are sure that new changes in the index does not impact the1770 * outcome. Return now.1771 */1772return path_recurse;1773}17741775static enum path_treatment treat_path(struct dir_struct *dir,1776struct untracked_cache_dir *untracked,1777struct cached_dir *cdir,1778struct index_state *istate,1779struct strbuf *path,1780int baselen,1781const struct pathspec *pathspec)1782{1783int dtype;1784struct dirent *de = cdir->de;17851786if(!de)1787returntreat_path_fast(dir, untracked, cdir, istate, path,1788 baselen, pathspec);1789if(is_dot_or_dotdot(de->d_name) || !fspathcmp(de->d_name,".git"))1790return path_none;1791strbuf_setlen(path, baselen);1792strbuf_addstr(path, de->d_name);1793if(simplify_away(path->buf, path->len, pathspec))1794return path_none;17951796 dtype =DTYPE(de);1797returntreat_one_path(dir, untracked, istate, path, baselen, pathspec, dtype, de);1798}17991800static voidadd_untracked(struct untracked_cache_dir *dir,const char*name)1801{1802if(!dir)1803return;1804ALLOC_GROW(dir->untracked, dir->untracked_nr +1,1805 dir->untracked_alloc);1806 dir->untracked[dir->untracked_nr++] =xstrdup(name);1807}18081809static intvalid_cached_dir(struct dir_struct *dir,1810struct untracked_cache_dir *untracked,1811struct index_state *istate,1812struct strbuf *path,1813int check_only)1814{1815struct stat st;18161817if(!untracked)1818return0;18191820/*1821 * With fsmonitor, we can trust the untracked cache's valid field.1822 */1823refresh_fsmonitor(istate);1824if(!(dir->untracked->use_fsmonitor && untracked->valid)) {1825if(lstat(path->len ? path->buf :".", &st)) {1826memset(&untracked->stat_data,0,sizeof(untracked->stat_data));1827return0;1828}1829if(!untracked->valid ||1830match_stat_data_racy(istate, &untracked->stat_data, &st)) {1831fill_stat_data(&untracked->stat_data, &st);1832return0;1833}1834}18351836if(untracked->check_only != !!check_only)1837return0;18381839/*1840 * prep_exclude will be called eventually on this directory,1841 * but it's called much later in last_exclude_matching(). We1842 * need it now to determine the validity of the cache for this1843 * path. The next calls will be nearly no-op, the way1844 * prep_exclude() is designed.1845 */1846if(path->len && path->buf[path->len -1] !='/') {1847strbuf_addch(path,'/');1848prep_exclude(dir, istate, path->buf, path->len);1849strbuf_setlen(path, path->len -1);1850}else1851prep_exclude(dir, istate, path->buf, path->len);18521853/* hopefully prep_exclude() haven't invalidated this entry... */1854return untracked->valid;1855}18561857static intopen_cached_dir(struct cached_dir *cdir,1858struct dir_struct *dir,1859struct untracked_cache_dir *untracked,1860struct index_state *istate,1861struct strbuf *path,1862int check_only)1863{1864const char*c_path;18651866memset(cdir,0,sizeof(*cdir));1867 cdir->untracked = untracked;1868if(valid_cached_dir(dir, untracked, istate, path, check_only))1869return0;1870 c_path = path->len ? path->buf :".";1871 cdir->fdir =opendir(c_path);1872if(!cdir->fdir)1873warning_errno(_("could not open directory '%s'"), c_path);1874if(dir->untracked) {1875invalidate_directory(dir->untracked, untracked);1876 dir->untracked->dir_opened++;1877}1878if(!cdir->fdir)1879return-1;1880return0;1881}18821883static intread_cached_dir(struct cached_dir *cdir)1884{1885if(cdir->fdir) {1886 cdir->de =readdir(cdir->fdir);1887if(!cdir->de)1888return-1;1889return0;1890}1891while(cdir->nr_dirs < cdir->untracked->dirs_nr) {1892struct untracked_cache_dir *d = cdir->untracked->dirs[cdir->nr_dirs];1893if(!d->recurse) {1894 cdir->nr_dirs++;1895continue;1896}1897 cdir->ucd = d;1898 cdir->nr_dirs++;1899return0;1900}1901 cdir->ucd = NULL;1902if(cdir->nr_files < cdir->untracked->untracked_nr) {1903struct untracked_cache_dir *d = cdir->untracked;1904 cdir->file = d->untracked[cdir->nr_files++];1905return0;1906}1907return-1;1908}19091910static voidclose_cached_dir(struct cached_dir *cdir)1911{1912if(cdir->fdir)1913closedir(cdir->fdir);1914/*1915 * We have gone through this directory and found no untracked1916 * entries. Mark it valid.1917 */1918if(cdir->untracked) {1919 cdir->untracked->valid =1;1920 cdir->untracked->recurse =1;1921}1922}19231924/*1925 * Read a directory tree. We currently ignore anything but1926 * directories, regular files and symlinks. That's because git1927 * doesn't handle them at all yet. Maybe that will change some1928 * day.1929 *1930 * Also, we ignore the name ".git" (even if it is not a directory).1931 * That likely will not change.1932 *1933 * If 'stop_at_first_file' is specified, 'path_excluded' is returned1934 * to signal that a file was found. This is the least significant value that1935 * indicates that a file was encountered that does not depend on the order of1936 * whether an untracked or exluded path was encountered first.1937 *1938 * Returns the most significant path_treatment value encountered in the scan.1939 * If 'stop_at_first_file' is specified, `path_excluded` is the most1940 * significant path_treatment value that will be returned.1941 */19421943static enum path_treatment read_directory_recursive(struct dir_struct *dir,1944struct index_state *istate,const char*base,int baselen,1945struct untracked_cache_dir *untracked,int check_only,1946int stop_at_first_file,const struct pathspec *pathspec)1947{1948struct cached_dir cdir;1949enum path_treatment state, subdir_state, dir_state = path_none;1950struct strbuf path = STRBUF_INIT;19511952strbuf_add(&path, base, baselen);19531954if(open_cached_dir(&cdir, dir, untracked, istate, &path, check_only))1955goto out;19561957if(untracked)1958 untracked->check_only = !!check_only;19591960while(!read_cached_dir(&cdir)) {1961/* check how the file or directory should be treated */1962 state =treat_path(dir, untracked, &cdir, istate, &path,1963 baselen, pathspec);19641965if(state > dir_state)1966 dir_state = state;19671968/* recurse into subdir if instructed by treat_path */1969if((state == path_recurse) ||1970((state == path_untracked) &&1971(dir->flags & DIR_SHOW_IGNORED_TOO) &&1972(get_dtype(cdir.de, istate, path.buf, path.len) == DT_DIR))) {1973struct untracked_cache_dir *ud;1974 ud =lookup_untracked(dir->untracked, untracked,1975 path.buf + baselen,1976 path.len - baselen);1977 subdir_state =1978read_directory_recursive(dir, istate, path.buf,1979 path.len, ud,1980 check_only, stop_at_first_file, pathspec);1981if(subdir_state > dir_state)1982 dir_state = subdir_state;1983}19841985if(check_only) {1986if(stop_at_first_file) {1987/*1988 * If stopping at first file, then1989 * signal that a file was found by1990 * returning `path_excluded`. This is1991 * to return a consistent value1992 * regardless of whether an ignored or1993 * excluded file happened to be1994 * encountered 1st.1995 *1996 * In current usage, the1997 * `stop_at_first_file` is passed when1998 * an ancestor directory has matched1999 * an exclude pattern, so any found2000 * files will be excluded.2001 */2002if(dir_state >= path_excluded) {2003 dir_state = path_excluded;2004break;2005}2006}20072008/* abort early if maximum state has been reached */2009if(dir_state == path_untracked) {2010if(cdir.fdir)2011add_untracked(untracked, path.buf + baselen);2012break;2013}2014/* skip the dir_add_* part */2015continue;2016}20172018/* add the path to the appropriate result list */2019switch(state) {2020case path_excluded:2021if(dir->flags & DIR_SHOW_IGNORED)2022dir_add_name(dir, istate, path.buf, path.len);2023else if((dir->flags & DIR_SHOW_IGNORED_TOO) ||2024((dir->flags & DIR_COLLECT_IGNORED) &&2025exclude_matches_pathspec(path.buf, path.len,2026 pathspec)))2027dir_add_ignored(dir, istate, path.buf, path.len);2028break;20292030case path_untracked:2031if(dir->flags & DIR_SHOW_IGNORED)2032break;2033dir_add_name(dir, istate, path.buf, path.len);2034if(cdir.fdir)2035add_untracked(untracked, path.buf + baselen);2036break;20372038default:2039break;2040}2041}2042close_cached_dir(&cdir);2043 out:2044strbuf_release(&path);20452046return dir_state;2047}20482049intcmp_dir_entry(const void*p1,const void*p2)2050{2051const struct dir_entry *e1 = *(const struct dir_entry **)p1;2052const struct dir_entry *e2 = *(const struct dir_entry **)p2;20532054returnname_compare(e1->name, e1->len, e2->name, e2->len);2055}20562057/* check if *out lexically strictly contains *in */2058intcheck_dir_entry_contains(const struct dir_entry *out,const struct dir_entry *in)2059{2060return(out->len < in->len) &&2061(out->name[out->len -1] =='/') &&2062!memcmp(out->name, in->name, out->len);2063}20642065static inttreat_leading_path(struct dir_struct *dir,2066struct index_state *istate,2067const char*path,int len,2068const struct pathspec *pathspec)2069{2070struct strbuf sb = STRBUF_INIT;2071int baselen, rc =0;2072const char*cp;2073int old_flags = dir->flags;20742075while(len && path[len -1] =='/')2076 len--;2077if(!len)2078return1;2079 baselen =0;2080 dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES;2081while(1) {2082 cp = path + baselen + !!baselen;2083 cp =memchr(cp,'/', path + len - cp);2084if(!cp)2085 baselen = len;2086else2087 baselen = cp - path;2088strbuf_setlen(&sb,0);2089strbuf_add(&sb, path, baselen);2090if(!is_directory(sb.buf))2091break;2092if(simplify_away(sb.buf, sb.len, pathspec))2093break;2094if(treat_one_path(dir, NULL, istate, &sb, baselen, pathspec,2095 DT_DIR, NULL) == path_none)2096break;/* do not recurse into it */2097if(len <= baselen) {2098 rc =1;2099break;/* finished checking */2100}2101}2102strbuf_release(&sb);2103 dir->flags = old_flags;2104return rc;2105}21062107static const char*get_ident_string(void)2108{2109static struct strbuf sb = STRBUF_INIT;2110struct utsname uts;21112112if(sb.len)2113return sb.buf;2114if(uname(&uts) <0)2115die_errno(_("failed to get kernel name and information"));2116strbuf_addf(&sb,"Location%s, system%s",get_git_work_tree(),2117 uts.sysname);2118return sb.buf;2119}21202121static intident_in_untracked(const struct untracked_cache *uc)2122{2123/*2124 * Previous git versions may have saved many NUL separated2125 * strings in the "ident" field, but it is insane to manage2126 * many locations, so just take care of the first one.2127 */21282129return!strcmp(uc->ident.buf,get_ident_string());2130}21312132static voidset_untracked_ident(struct untracked_cache *uc)2133{2134strbuf_reset(&uc->ident);2135strbuf_addstr(&uc->ident,get_ident_string());21362137/*2138 * This strbuf used to contain a list of NUL separated2139 * strings, so save NUL too for backward compatibility.2140 */2141strbuf_addch(&uc->ident,0);2142}21432144static voidnew_untracked_cache(struct index_state *istate)2145{2146struct untracked_cache *uc =xcalloc(1,sizeof(*uc));2147strbuf_init(&uc->ident,100);2148 uc->exclude_per_dir =".gitignore";2149/* should be the same flags used by git-status */2150 uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;2151set_untracked_ident(uc);2152 istate->untracked = uc;2153 istate->cache_changed |= UNTRACKED_CHANGED;2154}21552156voidadd_untracked_cache(struct index_state *istate)2157{2158if(!istate->untracked) {2159new_untracked_cache(istate);2160}else{2161if(!ident_in_untracked(istate->untracked)) {2162free_untracked_cache(istate->untracked);2163new_untracked_cache(istate);2164}2165}2166}21672168voidremove_untracked_cache(struct index_state *istate)2169{2170if(istate->untracked) {2171free_untracked_cache(istate->untracked);2172 istate->untracked = NULL;2173 istate->cache_changed |= UNTRACKED_CHANGED;2174}2175}21762177static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,2178int base_len,2179const struct pathspec *pathspec)2180{2181struct untracked_cache_dir *root;2182static int untracked_cache_disabled = -1;21832184if(!dir->untracked)2185return NULL;2186if(untracked_cache_disabled <0)2187 untracked_cache_disabled =git_env_bool("GIT_DISABLE_UNTRACKED_CACHE",0);2188if(untracked_cache_disabled)2189return NULL;21902191/*2192 * We only support $GIT_DIR/info/exclude and core.excludesfile2193 * as the global ignore rule files. Any other additions2194 * (e.g. from command line) invalidate the cache. This2195 * condition also catches running setup_standard_excludes()2196 * before setting dir->untracked!2197 */2198if(dir->unmanaged_exclude_files)2199return NULL;22002201/*2202 * Optimize for the main use case only: whole-tree git2203 * status. More work involved in treat_leading_path() if we2204 * use cache on just a subset of the worktree. pathspec2205 * support could make the matter even worse.2206 */2207if(base_len || (pathspec && pathspec->nr))2208return NULL;22092210/* Different set of flags may produce different results */2211if(dir->flags != dir->untracked->dir_flags ||2212/*2213 * See treat_directory(), case index_nonexistent. Without2214 * this flag, we may need to also cache .git file content2215 * for the resolve_gitlink_ref() call, which we don't.2216 */2217!(dir->flags & DIR_SHOW_OTHER_DIRECTORIES) ||2218/* We don't support collecting ignore files */2219(dir->flags & (DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO |2220 DIR_COLLECT_IGNORED)))2221return NULL;22222223/*2224 * If we use .gitignore in the cache and now you change it to2225 * .gitexclude, everything will go wrong.2226 */2227if(dir->exclude_per_dir != dir->untracked->exclude_per_dir &&2228strcmp(dir->exclude_per_dir, dir->untracked->exclude_per_dir))2229return NULL;22302231/*2232 * EXC_CMDL is not considered in the cache. If people set it,2233 * skip the cache.2234 */2235if(dir->exclude_list_group[EXC_CMDL].nr)2236return NULL;22372238if(!ident_in_untracked(dir->untracked)) {2239warning(_("untracked cache is disabled on this system or location"));2240return NULL;2241}22422243if(!dir->untracked->root) {2244const int len =sizeof(*dir->untracked->root);2245 dir->untracked->root =xmalloc(len);2246memset(dir->untracked->root,0, len);2247}22482249/* Validate $GIT_DIR/info/exclude and core.excludesfile */2250 root = dir->untracked->root;2251if(oidcmp(&dir->ss_info_exclude.oid,2252&dir->untracked->ss_info_exclude.oid)) {2253invalidate_gitignore(dir->untracked, root);2254 dir->untracked->ss_info_exclude = dir->ss_info_exclude;2255}2256if(oidcmp(&dir->ss_excludes_file.oid,2257&dir->untracked->ss_excludes_file.oid)) {2258invalidate_gitignore(dir->untracked, root);2259 dir->untracked->ss_excludes_file = dir->ss_excludes_file;2260}22612262/* Make sure this directory is not dropped out at saving phase */2263 root->recurse =1;2264return root;2265}22662267intread_directory(struct dir_struct *dir,struct index_state *istate,2268const char*path,int len,const struct pathspec *pathspec)2269{2270struct untracked_cache_dir *untracked;2271uint64_t start =getnanotime();22722273if(has_symlink_leading_path(path, len))2274return dir->nr;22752276 untracked =validate_untracked_cache(dir, len, pathspec);2277if(!untracked)2278/*2279 * make sure untracked cache code path is disabled,2280 * e.g. prep_exclude()2281 */2282 dir->untracked = NULL;2283if(!len ||treat_leading_path(dir, istate, path, len, pathspec))2284read_directory_recursive(dir, istate, path, len, untracked,0,0, pathspec);2285QSORT(dir->entries, dir->nr, cmp_dir_entry);2286QSORT(dir->ignored, dir->ignored_nr, cmp_dir_entry);22872288/*2289 * If DIR_SHOW_IGNORED_TOO is set, read_directory_recursive() will2290 * also pick up untracked contents of untracked dirs; by default2291 * we discard these, but given DIR_KEEP_UNTRACKED_CONTENTS we do not.2292 */2293if((dir->flags & DIR_SHOW_IGNORED_TOO) &&2294!(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {2295int i, j;22962297/* remove from dir->entries untracked contents of untracked dirs */2298for(i = j =0; j < dir->nr; j++) {2299if(i &&2300check_dir_entry_contains(dir->entries[i -1], dir->entries[j])) {2301FREE_AND_NULL(dir->entries[j]);2302}else{2303 dir->entries[i++] = dir->entries[j];2304}2305}23062307 dir->nr = i;2308}23092310trace_performance_since(start,"read directory %.*s", len, path);2311if(dir->untracked) {2312static int force_untracked_cache = -1;2313static struct trace_key trace_untracked_stats =TRACE_KEY_INIT(UNTRACKED_STATS);23142315if(force_untracked_cache <0)2316 force_untracked_cache =2317git_env_bool("GIT_FORCE_UNTRACKED_CACHE",0);2318trace_printf_key(&trace_untracked_stats,2319"node creation:%u\n"2320"gitignore invalidation:%u\n"2321"directory invalidation:%u\n"2322"opendir:%u\n",2323 dir->untracked->dir_created,2324 dir->untracked->gitignore_invalidated,2325 dir->untracked->dir_invalidated,2326 dir->untracked->dir_opened);2327if(force_untracked_cache &&2328 dir->untracked == istate->untracked &&2329(dir->untracked->dir_opened ||2330 dir->untracked->gitignore_invalidated ||2331 dir->untracked->dir_invalidated))2332 istate->cache_changed |= UNTRACKED_CHANGED;2333if(dir->untracked != istate->untracked) {2334FREE_AND_NULL(dir->untracked);2335}2336}2337return dir->nr;2338}23392340intfile_exists(const char*f)2341{2342struct stat sb;2343returnlstat(f, &sb) ==0;2344}23452346static intcmp_icase(char a,char b)2347{2348if(a == b)2349return0;2350if(ignore_case)2351returntoupper(a) -toupper(b);2352return a - b;2353}23542355/*2356 * Given two normalized paths (a trailing slash is ok), if subdir is2357 * outside dir, return -1. Otherwise return the offset in subdir that2358 * can be used as relative path to dir.2359 */2360intdir_inside_of(const char*subdir,const char*dir)2361{2362int offset =0;23632364assert(dir && subdir && *dir && *subdir);23652366while(*dir && *subdir && !cmp_icase(*dir, *subdir)) {2367 dir++;2368 subdir++;2369 offset++;2370}23712372/* hel[p]/me vs hel[l]/yeah */2373if(*dir && *subdir)2374return-1;23752376if(!*subdir)2377return!*dir ? offset : -1;/* same dir */23782379/* foo/[b]ar vs foo/[] */2380if(is_dir_sep(dir[-1]))2381returnis_dir_sep(subdir[-1]) ? offset : -1;23822383/* foo[/]bar vs foo[] */2384returnis_dir_sep(*subdir) ? offset +1: -1;2385}23862387intis_inside_dir(const char*dir)2388{2389char*cwd;2390int rc;23912392if(!dir)2393return0;23942395 cwd =xgetcwd();2396 rc = (dir_inside_of(cwd, dir) >=0);2397free(cwd);2398return rc;2399}24002401intis_empty_dir(const char*path)2402{2403DIR*dir =opendir(path);2404struct dirent *e;2405int ret =1;24062407if(!dir)2408return0;24092410while((e =readdir(dir)) != NULL)2411if(!is_dot_or_dotdot(e->d_name)) {2412 ret =0;2413break;2414}24152416closedir(dir);2417return ret;2418}24192420static intremove_dir_recurse(struct strbuf *path,int flag,int*kept_up)2421{2422DIR*dir;2423struct dirent *e;2424int ret =0, original_len = path->len, len, kept_down =0;2425int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);2426int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);2427struct object_id submodule_head;24282429if((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&2430!resolve_gitlink_ref(path->buf,"HEAD", &submodule_head)) {2431/* Do not descend and nuke a nested git work tree. */2432if(kept_up)2433*kept_up =1;2434return0;2435}24362437 flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;2438 dir =opendir(path->buf);2439if(!dir) {2440if(errno == ENOENT)2441return keep_toplevel ? -1:0;2442else if(errno == EACCES && !keep_toplevel)2443/*2444 * An empty dir could be removable even if it2445 * is unreadable:2446 */2447returnrmdir(path->buf);2448else2449return-1;2450}2451strbuf_complete(path,'/');24522453 len = path->len;2454while((e =readdir(dir)) != NULL) {2455struct stat st;2456if(is_dot_or_dotdot(e->d_name))2457continue;24582459strbuf_setlen(path, len);2460strbuf_addstr(path, e->d_name);2461if(lstat(path->buf, &st)) {2462if(errno == ENOENT)2463/*2464 * file disappeared, which is what we2465 * wanted anyway2466 */2467continue;2468/* fall thru */2469}else if(S_ISDIR(st.st_mode)) {2470if(!remove_dir_recurse(path, flag, &kept_down))2471continue;/* happy */2472}else if(!only_empty &&2473(!unlink(path->buf) || errno == ENOENT)) {2474continue;/* happy, too */2475}24762477/* path too long, stat fails, or non-directory still exists */2478 ret = -1;2479break;2480}2481closedir(dir);24822483strbuf_setlen(path, original_len);2484if(!ret && !keep_toplevel && !kept_down)2485 ret = (!rmdir(path->buf) || errno == ENOENT) ?0: -1;2486else if(kept_up)2487/*2488 * report the uplevel that it is not an error that we2489 * did not rmdir() our directory.2490 */2491*kept_up = !ret;2492return ret;2493}24942495intremove_dir_recursively(struct strbuf *path,int flag)2496{2497returnremove_dir_recurse(path, flag, NULL);2498}24992500staticGIT_PATH_FUNC(git_path_info_exclude,"info/exclude")25012502voidsetup_standard_excludes(struct dir_struct *dir)2503{2504 dir->exclude_per_dir =".gitignore";25052506/* core.excludesfile defaulting to $XDG_CONFIG_HOME/git/ignore */2507if(!excludes_file)2508 excludes_file =xdg_config_home("ignore");2509if(excludes_file && !access_or_warn(excludes_file, R_OK,0))2510add_excludes_from_file_1(dir, excludes_file,2511 dir->untracked ? &dir->ss_excludes_file : NULL);25122513/* per repository user preference */2514if(startup_info->have_repository) {2515const char*path =git_path_info_exclude();2516if(!access_or_warn(path, R_OK,0))2517add_excludes_from_file_1(dir, path,2518 dir->untracked ? &dir->ss_info_exclude : NULL);2519}2520}25212522intremove_path(const char*name)2523{2524char*slash;25252526if(unlink(name) && !is_missing_file_error(errno))2527return-1;25282529 slash =strrchr(name,'/');2530if(slash) {2531char*dirs =xstrdup(name);2532 slash = dirs + (slash - name);2533do{2534*slash ='\0';2535}while(rmdir(dirs) ==0&& (slash =strrchr(dirs,'/')));2536free(dirs);2537}2538return0;2539}25402541/*2542 * Frees memory within dir which was allocated for exclude lists and2543 * the exclude_stack. Does not free dir itself.2544 */2545voidclear_directory(struct dir_struct *dir)2546{2547int i, j;2548struct exclude_list_group *group;2549struct exclude_list *el;2550struct exclude_stack *stk;25512552for(i = EXC_CMDL; i <= EXC_FILE; i++) {2553 group = &dir->exclude_list_group[i];2554for(j =0; j < group->nr; j++) {2555 el = &group->el[j];2556if(i == EXC_DIRS)2557free((char*)el->src);2558clear_exclude_list(el);2559}2560free(group->el);2561}25622563 stk = dir->exclude_stack;2564while(stk) {2565struct exclude_stack *prev = stk->prev;2566free(stk);2567 stk = prev;2568}2569strbuf_release(&dir->basebuf);2570}25712572struct ondisk_untracked_cache {2573struct stat_data info_exclude_stat;2574struct stat_data excludes_file_stat;2575uint32_t dir_flags;2576unsigned char info_exclude_sha1[20];2577unsigned char excludes_file_sha1[20];2578char exclude_per_dir[FLEX_ARRAY];2579};25802581#define ouc_offset(x) offsetof(struct ondisk_untracked_cache, x)2582#define ouc_size(len) (ouc_offset(exclude_per_dir) + len + 1)25832584struct write_data {2585int index;/* number of written untracked_cache_dir */2586struct ewah_bitmap *check_only;/* from untracked_cache_dir */2587struct ewah_bitmap *valid;/* from untracked_cache_dir */2588struct ewah_bitmap *sha1_valid;/* set if exclude_sha1 is not null */2589struct strbuf out;2590struct strbuf sb_stat;2591struct strbuf sb_sha1;2592};25932594static voidstat_data_to_disk(struct stat_data *to,const struct stat_data *from)2595{2596 to->sd_ctime.sec =htonl(from->sd_ctime.sec);2597 to->sd_ctime.nsec =htonl(from->sd_ctime.nsec);2598 to->sd_mtime.sec =htonl(from->sd_mtime.sec);2599 to->sd_mtime.nsec =htonl(from->sd_mtime.nsec);2600 to->sd_dev =htonl(from->sd_dev);2601 to->sd_ino =htonl(from->sd_ino);2602 to->sd_uid =htonl(from->sd_uid);2603 to->sd_gid =htonl(from->sd_gid);2604 to->sd_size =htonl(from->sd_size);2605}26062607static voidwrite_one_dir(struct untracked_cache_dir *untracked,2608struct write_data *wd)2609{2610struct stat_data stat_data;2611struct strbuf *out = &wd->out;2612unsigned char intbuf[16];2613unsigned int intlen, value;2614int i = wd->index++;26152616/*2617 * untracked_nr should be reset whenever valid is clear, but2618 * for safety..2619 */2620if(!untracked->valid) {2621 untracked->untracked_nr =0;2622 untracked->check_only =0;2623}26242625if(untracked->check_only)2626ewah_set(wd->check_only, i);2627if(untracked->valid) {2628ewah_set(wd->valid, i);2629stat_data_to_disk(&stat_data, &untracked->stat_data);2630strbuf_add(&wd->sb_stat, &stat_data,sizeof(stat_data));2631}2632if(!is_null_oid(&untracked->exclude_oid)) {2633ewah_set(wd->sha1_valid, i);2634strbuf_add(&wd->sb_sha1, untracked->exclude_oid.hash,2635 the_hash_algo->rawsz);2636}26372638 intlen =encode_varint(untracked->untracked_nr, intbuf);2639strbuf_add(out, intbuf, intlen);26402641/* skip non-recurse directories */2642for(i =0, value =0; i < untracked->dirs_nr; i++)2643if(untracked->dirs[i]->recurse)2644 value++;2645 intlen =encode_varint(value, intbuf);2646strbuf_add(out, intbuf, intlen);26472648strbuf_add(out, untracked->name,strlen(untracked->name) +1);26492650for(i =0; i < untracked->untracked_nr; i++)2651strbuf_add(out, untracked->untracked[i],2652strlen(untracked->untracked[i]) +1);26532654for(i =0; i < untracked->dirs_nr; i++)2655if(untracked->dirs[i]->recurse)2656write_one_dir(untracked->dirs[i], wd);2657}26582659voidwrite_untracked_extension(struct strbuf *out,struct untracked_cache *untracked)2660{2661struct ondisk_untracked_cache *ouc;2662struct write_data wd;2663unsigned char varbuf[16];2664int varint_len;2665size_t len =strlen(untracked->exclude_per_dir);26662667FLEX_ALLOC_MEM(ouc, exclude_per_dir, untracked->exclude_per_dir, len);2668stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat);2669stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat);2670hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.oid.hash);2671hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.oid.hash);2672 ouc->dir_flags =htonl(untracked->dir_flags);26732674 varint_len =encode_varint(untracked->ident.len, varbuf);2675strbuf_add(out, varbuf, varint_len);2676strbuf_addbuf(out, &untracked->ident);26772678strbuf_add(out, ouc,ouc_size(len));2679FREE_AND_NULL(ouc);26802681if(!untracked->root) {2682 varint_len =encode_varint(0, varbuf);2683strbuf_add(out, varbuf, varint_len);2684return;2685}26862687 wd.index =0;2688 wd.check_only =ewah_new();2689 wd.valid =ewah_new();2690 wd.sha1_valid =ewah_new();2691strbuf_init(&wd.out,1024);2692strbuf_init(&wd.sb_stat,1024);2693strbuf_init(&wd.sb_sha1,1024);2694write_one_dir(untracked->root, &wd);26952696 varint_len =encode_varint(wd.index, varbuf);2697strbuf_add(out, varbuf, varint_len);2698strbuf_addbuf(out, &wd.out);2699ewah_serialize_strbuf(wd.valid, out);2700ewah_serialize_strbuf(wd.check_only, out);2701ewah_serialize_strbuf(wd.sha1_valid, out);2702strbuf_addbuf(out, &wd.sb_stat);2703strbuf_addbuf(out, &wd.sb_sha1);2704strbuf_addch(out,'\0');/* safe guard for string lists */27052706ewah_free(wd.valid);2707ewah_free(wd.check_only);2708ewah_free(wd.sha1_valid);2709strbuf_release(&wd.out);2710strbuf_release(&wd.sb_stat);2711strbuf_release(&wd.sb_sha1);2712}27132714static voidfree_untracked(struct untracked_cache_dir *ucd)2715{2716int i;2717if(!ucd)2718return;2719for(i =0; i < ucd->dirs_nr; i++)2720free_untracked(ucd->dirs[i]);2721for(i =0; i < ucd->untracked_nr; i++)2722free(ucd->untracked[i]);2723free(ucd->untracked);2724free(ucd->dirs);2725free(ucd);2726}27272728voidfree_untracked_cache(struct untracked_cache *uc)2729{2730if(uc)2731free_untracked(uc->root);2732free(uc);2733}27342735struct read_data {2736int index;2737struct untracked_cache_dir **ucd;2738struct ewah_bitmap *check_only;2739struct ewah_bitmap *valid;2740struct ewah_bitmap *sha1_valid;2741const unsigned char*data;2742const unsigned char*end;2743};27442745static voidstat_data_from_disk(struct stat_data *to,const unsigned char*data)2746{2747memcpy(to, data,sizeof(*to));2748 to->sd_ctime.sec =ntohl(to->sd_ctime.sec);2749 to->sd_ctime.nsec =ntohl(to->sd_ctime.nsec);2750 to->sd_mtime.sec =ntohl(to->sd_mtime.sec);2751 to->sd_mtime.nsec =ntohl(to->sd_mtime.nsec);2752 to->sd_dev =ntohl(to->sd_dev);2753 to->sd_ino =ntohl(to->sd_ino);2754 to->sd_uid =ntohl(to->sd_uid);2755 to->sd_gid =ntohl(to->sd_gid);2756 to->sd_size =ntohl(to->sd_size);2757}27582759static intread_one_dir(struct untracked_cache_dir **untracked_,2760struct read_data *rd)2761{2762struct untracked_cache_dir ud, *untracked;2763const unsigned char*next, *data = rd->data, *end = rd->end;2764unsigned int value;2765int i, len;27662767memset(&ud,0,sizeof(ud));27682769 next = data;2770 value =decode_varint(&next);2771if(next > end)2772return-1;2773 ud.recurse =1;2774 ud.untracked_alloc = value;2775 ud.untracked_nr = value;2776if(ud.untracked_nr)2777ALLOC_ARRAY(ud.untracked, ud.untracked_nr);2778 data = next;27792780 next = data;2781 ud.dirs_alloc = ud.dirs_nr =decode_varint(&next);2782if(next > end)2783return-1;2784ALLOC_ARRAY(ud.dirs, ud.dirs_nr);2785 data = next;27862787 len =strlen((const char*)data);2788 next = data + len +1;2789if(next > rd->end)2790return-1;2791*untracked_ = untracked =xmalloc(st_add(sizeof(*untracked), len));2792memcpy(untracked, &ud,sizeof(ud));2793memcpy(untracked->name, data, len +1);2794 data = next;27952796for(i =0; i < untracked->untracked_nr; i++) {2797 len =strlen((const char*)data);2798 next = data + len +1;2799if(next > rd->end)2800return-1;2801 untracked->untracked[i] =xstrdup((const char*)data);2802 data = next;2803}28042805 rd->ucd[rd->index++] = untracked;2806 rd->data = data;28072808for(i =0; i < untracked->dirs_nr; i++) {2809 len =read_one_dir(untracked->dirs + i, rd);2810if(len <0)2811return-1;2812}2813return0;2814}28152816static voidset_check_only(size_t pos,void*cb)2817{2818struct read_data *rd = cb;2819struct untracked_cache_dir *ud = rd->ucd[pos];2820 ud->check_only =1;2821}28222823static voidread_stat(size_t pos,void*cb)2824{2825struct read_data *rd = cb;2826struct untracked_cache_dir *ud = rd->ucd[pos];2827if(rd->data +sizeof(struct stat_data) > rd->end) {2828 rd->data = rd->end +1;2829return;2830}2831stat_data_from_disk(&ud->stat_data, rd->data);2832 rd->data +=sizeof(struct stat_data);2833 ud->valid =1;2834}28352836static voidread_oid(size_t pos,void*cb)2837{2838struct read_data *rd = cb;2839struct untracked_cache_dir *ud = rd->ucd[pos];2840if(rd->data + the_hash_algo->rawsz > rd->end) {2841 rd->data = rd->end +1;2842return;2843}2844hashcpy(ud->exclude_oid.hash, rd->data);2845 rd->data += the_hash_algo->rawsz;2846}28472848static voidload_oid_stat(struct oid_stat *oid_stat,const unsigned char*data,2849const unsigned char*sha1)2850{2851stat_data_from_disk(&oid_stat->stat, data);2852hashcpy(oid_stat->oid.hash, sha1);2853 oid_stat->valid =1;2854}28552856struct untracked_cache *read_untracked_extension(const void*data,unsigned long sz)2857{2858struct untracked_cache *uc;2859struct read_data rd;2860const unsigned char*next = data, *end = (const unsigned char*)data + sz;2861const char*ident;2862int ident_len;2863 ssize_t len;2864const char*exclude_per_dir;28652866if(sz <=1|| end[-1] !='\0')2867return NULL;2868 end--;28692870 ident_len =decode_varint(&next);2871if(next + ident_len > end)2872return NULL;2873 ident = (const char*)next;2874 next += ident_len;28752876if(next +ouc_size(0) > end)2877return NULL;28782879 uc =xcalloc(1,sizeof(*uc));2880strbuf_init(&uc->ident, ident_len);2881strbuf_add(&uc->ident, ident, ident_len);2882load_oid_stat(&uc->ss_info_exclude,2883 next +ouc_offset(info_exclude_stat),2884 next +ouc_offset(info_exclude_sha1));2885load_oid_stat(&uc->ss_excludes_file,2886 next +ouc_offset(excludes_file_stat),2887 next +ouc_offset(excludes_file_sha1));2888 uc->dir_flags =get_be32(next +ouc_offset(dir_flags));2889 exclude_per_dir = (const char*)next +ouc_offset(exclude_per_dir);2890 uc->exclude_per_dir =xstrdup(exclude_per_dir);2891/* NUL after exclude_per_dir is covered by sizeof(*ouc) */2892 next +=ouc_size(strlen(exclude_per_dir));2893if(next >= end)2894goto done2;28952896 len =decode_varint(&next);2897if(next > end || len ==0)2898goto done2;28992900 rd.valid =ewah_new();2901 rd.check_only =ewah_new();2902 rd.sha1_valid =ewah_new();2903 rd.data = next;2904 rd.end = end;2905 rd.index =0;2906ALLOC_ARRAY(rd.ucd, len);29072908if(read_one_dir(&uc->root, &rd) || rd.index != len)2909goto done;29102911 next = rd.data;2912 len =ewah_read_mmap(rd.valid, next, end - next);2913if(len <0)2914goto done;29152916 next += len;2917 len =ewah_read_mmap(rd.check_only, next, end - next);2918if(len <0)2919goto done;29202921 next += len;2922 len =ewah_read_mmap(rd.sha1_valid, next, end - next);2923if(len <0)2924goto done;29252926ewah_each_bit(rd.check_only, set_check_only, &rd);2927 rd.data = next + len;2928ewah_each_bit(rd.valid, read_stat, &rd);2929ewah_each_bit(rd.sha1_valid, read_oid, &rd);2930 next = rd.data;29312932done:2933free(rd.ucd);2934ewah_free(rd.valid);2935ewah_free(rd.check_only);2936ewah_free(rd.sha1_valid);2937done2:2938if(next != end) {2939free_untracked_cache(uc);2940 uc = NULL;2941}2942return uc;2943}29442945static voidinvalidate_one_directory(struct untracked_cache *uc,2946struct untracked_cache_dir *ucd)2947{2948 uc->dir_invalidated++;2949 ucd->valid =0;2950 ucd->untracked_nr =0;2951}29522953/*2954 * Normally when an entry is added or removed from a directory,2955 * invalidating that directory is enough. No need to touch its2956 * ancestors. When a directory is shown as "foo/bar/" in git-status2957 * however, deleting or adding an entry may have cascading effect.2958 *2959 * Say the "foo/bar/file" has become untracked, we need to tell the2960 * untracked_cache_dir of "foo" that "bar/" is not an untracked2961 * directory any more (because "bar" is managed by foo as an untracked2962 * "file").2963 *2964 * Similarly, if "foo/bar/file" moves from untracked to tracked and it2965 * was the last untracked entry in the entire "foo", we should show2966 * "foo/" instead. Which means we have to invalidate past "bar" up to2967 * "foo".2968 *2969 * This function traverses all directories from root to leaf. If there2970 * is a chance of one of the above cases happening, we invalidate back2971 * to root. Otherwise we just invalidate the leaf. There may be a more2972 * sophisticated way than checking for SHOW_OTHER_DIRECTORIES to2973 * detect these cases and avoid unnecessary invalidation, for example,2974 * checking for the untracked entry named "bar/" in "foo", but for now2975 * stick to something safe and simple.2976 */2977static intinvalidate_one_component(struct untracked_cache *uc,2978struct untracked_cache_dir *dir,2979const char*path,int len)2980{2981const char*rest =strchr(path,'/');29822983if(rest) {2984int component_len = rest - path;2985struct untracked_cache_dir *d =2986lookup_untracked(uc, dir, path, component_len);2987int ret =2988invalidate_one_component(uc, d, rest +1,2989 len - (component_len +1));2990if(ret)2991invalidate_one_directory(uc, dir);2992return ret;2993}29942995invalidate_one_directory(uc, dir);2996return uc->dir_flags & DIR_SHOW_OTHER_DIRECTORIES;2997}29982999voiduntracked_cache_invalidate_path(struct index_state *istate,3000const char*path,int safe_path)3001{3002if(!istate->untracked || !istate->untracked->root)3003return;3004if(!safe_path && !verify_path(path,0))3005return;3006invalidate_one_component(istate->untracked, istate->untracked->root,3007 path,strlen(path));3008}30093010voiduntracked_cache_remove_from_index(struct index_state *istate,3011const char*path)3012{3013untracked_cache_invalidate_path(istate, path,1);3014}30153016voiduntracked_cache_add_to_index(struct index_state *istate,3017const char*path)3018{3019untracked_cache_invalidate_path(istate, path,1);3020}30213022static voidconnect_wt_gitdir_in_nested(const char*sub_worktree,3023const char*sub_gitdir)3024{3025int i;3026struct repository subrepo;3027struct strbuf sub_wt = STRBUF_INIT;3028struct strbuf sub_gd = STRBUF_INIT;30293030const struct submodule *sub;30313032/* If the submodule has no working tree, we can ignore it. */3033if(repo_init(&subrepo, sub_gitdir, sub_worktree))3034return;30353036if(repo_read_index(&subrepo) <0)3037die(_("index file corrupt in repo%s"), subrepo.gitdir);30383039for(i =0; i < subrepo.index->cache_nr; i++) {3040const struct cache_entry *ce = subrepo.index->cache[i];30413042if(!S_ISGITLINK(ce->ce_mode))3043continue;30443045while(i +1< subrepo.index->cache_nr &&3046!strcmp(ce->name, subrepo.index->cache[i +1]->name))3047/*3048 * Skip entries with the same name in different stages3049 * to make sure an entry is returned only once.3050 */3051 i++;30523053 sub =submodule_from_path(&subrepo, &null_oid, ce->name);3054if(!sub || !is_submodule_active(&subrepo, ce->name))3055/* .gitmodules broken or inactive sub */3056continue;30573058strbuf_reset(&sub_wt);3059strbuf_reset(&sub_gd);3060strbuf_addf(&sub_wt,"%s/%s", sub_worktree, sub->path);3061strbuf_addf(&sub_gd,"%s/modules/%s", sub_gitdir, sub->name);30623063connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf,1);3064}3065strbuf_release(&sub_wt);3066strbuf_release(&sub_gd);3067repo_clear(&subrepo);3068}30693070voidconnect_work_tree_and_git_dir(const char*work_tree_,3071const char*git_dir_,3072int recurse_into_nested)3073{3074struct strbuf gitfile_sb = STRBUF_INIT;3075struct strbuf cfg_sb = STRBUF_INIT;3076struct strbuf rel_path = STRBUF_INIT;3077char*git_dir, *work_tree;30783079/* Prepare .git file */3080strbuf_addf(&gitfile_sb,"%s/.git", work_tree_);3081if(safe_create_leading_directories_const(gitfile_sb.buf))3082die(_("could not create directories for%s"), gitfile_sb.buf);30833084/* Prepare config file */3085strbuf_addf(&cfg_sb,"%s/config", git_dir_);3086if(safe_create_leading_directories_const(cfg_sb.buf))3087die(_("could not create directories for%s"), cfg_sb.buf);30883089 git_dir =real_pathdup(git_dir_,1);3090 work_tree =real_pathdup(work_tree_,1);30913092/* Write .git file */3093write_file(gitfile_sb.buf,"gitdir:%s",3094relative_path(git_dir, work_tree, &rel_path));3095/* Update core.worktree setting */3096git_config_set_in_file(cfg_sb.buf,"core.worktree",3097relative_path(work_tree, git_dir, &rel_path));30983099strbuf_release(&gitfile_sb);3100strbuf_release(&cfg_sb);3101strbuf_release(&rel_path);31023103if(recurse_into_nested)3104connect_wt_gitdir_in_nested(work_tree, git_dir);31053106free(work_tree);3107free(git_dir);3108}31093110/*3111 * Migrate the git directory of the given path from old_git_dir to new_git_dir.3112 */3113voidrelocate_gitdir(const char*path,const char*old_git_dir,const char*new_git_dir)3114{3115if(rename(old_git_dir, new_git_dir) <0)3116die_errno(_("could not migrate git directory from '%s' to '%s'"),3117 old_git_dir, new_git_dir);31183119connect_work_tree_and_git_dir(path, new_git_dir,0);3120}