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"config.h" 12#include"dir.h" 13#include"object-store.h" 14#include"attr.h" 15#include"refs.h" 16#include"wildmatch.h" 17#include"pathspec.h" 18#include"utf8.h" 19#include"varint.h" 20#include"ewah/ewok.h" 21#include"fsmonitor.h" 22#include"submodule-config.h" 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, 52struct index_state *istate,const char*path,int len, 53struct untracked_cache_dir *untracked, 54int check_only,int stop_at_first_file,const struct pathspec *pathspec); 55static intget_dtype(struct dirent *de,struct index_state *istate, 56const char*path,int len); 57 58intcount_slashes(const char*s) 59{ 60int cnt =0; 61while(*s) 62if(*s++ =='/') 63 cnt++; 64return cnt; 65} 66 67intfspathcmp(const char*a,const char*b) 68{ 69return ignore_case ?strcasecmp(a, b) :strcmp(a, b); 70} 71 72intfspathncmp(const char*a,const char*b,size_t count) 73{ 74return ignore_case ?strncasecmp(a, b, count) :strncmp(a, b, count); 75} 76 77intgit_fnmatch(const struct pathspec_item *item, 78const char*pattern,const char*string, 79int prefix) 80{ 81if(prefix >0) { 82if(ps_strncmp(item, pattern, string, prefix)) 83return WM_NOMATCH; 84 pattern += prefix; 85 string += prefix; 86} 87if(item->flags & PATHSPEC_ONESTAR) { 88int pattern_len =strlen(++pattern); 89int string_len =strlen(string); 90return string_len < pattern_len || 91ps_strcmp(item, pattern, 92 string + string_len - pattern_len); 93} 94if(item->magic & PATHSPEC_GLOB) 95returnwildmatch(pattern, string, 96 WM_PATHNAME | 97(item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0)); 98else 99/* wildmatch has not learned no FNM_PATHNAME mode yet */ 100returnwildmatch(pattern, string, 101 item->magic & PATHSPEC_ICASE ? WM_CASEFOLD :0); 102} 103 104static intfnmatch_icase_mem(const char*pattern,int patternlen, 105const char*string,int stringlen, 106int flags) 107{ 108int match_status; 109struct strbuf pat_buf = STRBUF_INIT; 110struct strbuf str_buf = STRBUF_INIT; 111const char*use_pat = pattern; 112const char*use_str = string; 113 114if(pattern[patternlen]) { 115strbuf_add(&pat_buf, pattern, patternlen); 116 use_pat = pat_buf.buf; 117} 118if(string[stringlen]) { 119strbuf_add(&str_buf, string, stringlen); 120 use_str = str_buf.buf; 121} 122 123if(ignore_case) 124 flags |= WM_CASEFOLD; 125 match_status =wildmatch(use_pat, use_str, flags); 126 127strbuf_release(&pat_buf); 128strbuf_release(&str_buf); 129 130return match_status; 131} 132 133static size_tcommon_prefix_len(const struct pathspec *pathspec) 134{ 135int n; 136size_t max =0; 137 138/* 139 * ":(icase)path" is treated as a pathspec full of 140 * wildcard. In other words, only prefix is considered common 141 * prefix. If the pathspec is abc/foo abc/bar, running in 142 * subdir xyz, the common prefix is still xyz, not xuz/abc as 143 * in non-:(icase). 144 */ 145GUARD_PATHSPEC(pathspec, 146 PATHSPEC_FROMTOP | 147 PATHSPEC_MAXDEPTH | 148 PATHSPEC_LITERAL | 149 PATHSPEC_GLOB | 150 PATHSPEC_ICASE | 151 PATHSPEC_EXCLUDE | 152 PATHSPEC_ATTR); 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, 191struct index_state *istate, 192const struct pathspec *pathspec) 193{ 194const char*prefix; 195size_t prefix_len; 196 197/* 198 * Calculate common prefix for the pathspec, and 199 * use that to optimize the directory walk 200 */ 201 prefix_len =common_prefix_len(pathspec); 202 prefix = prefix_len ? pathspec->items[0].match :""; 203 204/* Read the directory and prune it */ 205read_directory(dir, istate, prefix, prefix_len, pathspec); 206 207return prefix_len; 208} 209 210intwithin_depth(const char*name,int namelen, 211int depth,int max_depth) 212{ 213const char*cp = name, *cpe = name + namelen; 214 215while(cp < cpe) { 216if(*cp++ !='/') 217continue; 218 depth++; 219if(depth > max_depth) 220return0; 221} 222return1; 223} 224 225/* 226 * Read the contents of the blob with the given OID into a buffer. 227 * Append a trailing LF to the end if the last line doesn't have one. 228 * 229 * Returns: 230 * -1 when the OID is invalid or unknown or does not refer to a blob. 231 * 0 when the blob is empty. 232 * 1 along with { data, size } of the (possibly augmented) buffer 233 * when successful. 234 * 235 * Optionally updates the given oid_stat with the given OID (when valid). 236 */ 237static intdo_read_blob(const struct object_id *oid,struct oid_stat *oid_stat, 238size_t*size_out,char**data_out) 239{ 240enum object_type type; 241unsigned long sz; 242char*data; 243 244*size_out =0; 245*data_out = NULL; 246 247 data =read_object_file(oid, &type, &sz); 248if(!data || type != OBJ_BLOB) { 249free(data); 250return-1; 251} 252 253if(oid_stat) { 254memset(&oid_stat->stat,0,sizeof(oid_stat->stat)); 255oidcpy(&oid_stat->oid, oid); 256} 257 258if(sz ==0) { 259free(data); 260return0; 261} 262 263if(data[sz -1] !='\n') { 264 data =xrealloc(data,st_add(sz,1)); 265 data[sz++] ='\n'; 266} 267 268*size_out =xsize_t(sz); 269*data_out = data; 270 271return1; 272} 273 274#define DO_MATCH_EXCLUDE (1<<0) 275#define DO_MATCH_DIRECTORY (1<<1) 276#define DO_MATCH_SUBMODULE (1<<2) 277 278/* 279 * Does 'match' match the given name? 280 * A match is found if 281 * 282 * (1) the 'match' string is leading directory of 'name', or 283 * (2) the 'match' string is a wildcard and matches 'name', or 284 * (3) the 'match' string is exactly the same as 'name'. 285 * 286 * and the return value tells which case it was. 287 * 288 * It returns 0 when there is no match. 289 */ 290static intmatch_pathspec_item(const struct index_state *istate, 291const struct pathspec_item *item,int prefix, 292const char*name,int namelen,unsigned flags) 293{ 294/* name/namelen has prefix cut off by caller */ 295const char*match = item->match + prefix; 296int matchlen = item->len - prefix; 297 298/* 299 * The normal call pattern is: 300 * 1. prefix = common_prefix_len(ps); 301 * 2. prune something, or fill_directory 302 * 3. match_pathspec() 303 * 304 * 'prefix' at #1 may be shorter than the command's prefix and 305 * it's ok for #2 to match extra files. Those extras will be 306 * trimmed at #3. 307 * 308 * Suppose the pathspec is 'foo' and '../bar' running from 309 * subdir 'xyz'. The common prefix at #1 will be empty, thanks 310 * to "../". We may have xyz/foo _and_ XYZ/foo after #2. The 311 * user does not want XYZ/foo, only the "foo" part should be 312 * case-insensitive. We need to filter out XYZ/foo here. In 313 * other words, we do not trust the caller on comparing the 314 * prefix part when :(icase) is involved. We do exact 315 * comparison ourselves. 316 * 317 * Normally the caller (common_prefix_len() in fact) does 318 * _exact_ matching on name[-prefix+1..-1] and we do not need 319 * to check that part. Be defensive and check it anyway, in 320 * case common_prefix_len is changed, or a new caller is 321 * introduced that does not use common_prefix_len. 322 * 323 * If the penalty turns out too high when prefix is really 324 * long, maybe change it to 325 * strncmp(match, name, item->prefix - prefix) 326 */ 327if(item->prefix && (item->magic & PATHSPEC_ICASE) && 328strncmp(item->match, name - prefix, item->prefix)) 329return0; 330 331if(item->attr_match_nr && 332!match_pathspec_attrs(istate, name, namelen, item)) 333return0; 334 335/* If the match was just the prefix, we matched */ 336if(!*match) 337return MATCHED_RECURSIVELY; 338 339if(matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) { 340if(matchlen == namelen) 341return MATCHED_EXACTLY; 342 343if(match[matchlen-1] =='/'|| name[matchlen] =='/') 344return MATCHED_RECURSIVELY; 345}else if((flags & DO_MATCH_DIRECTORY) && 346 match[matchlen -1] =='/'&& 347 namelen == matchlen -1&& 348!ps_strncmp(item, match, name, namelen)) 349return MATCHED_EXACTLY; 350 351if(item->nowildcard_len < item->len && 352!git_fnmatch(item, match, name, 353 item->nowildcard_len - prefix)) 354return MATCHED_FNMATCH; 355 356/* Perform checks to see if "name" is a super set of the pathspec */ 357if(flags & DO_MATCH_SUBMODULE) { 358/* name is a literal prefix of the pathspec */ 359if((namelen < matchlen) && 360(match[namelen] =='/') && 361!ps_strncmp(item, match, name, namelen)) 362return MATCHED_RECURSIVELY; 363 364/* name" doesn't match up to the first wild character */ 365if(item->nowildcard_len < item->len && 366ps_strncmp(item, match, name, 367 item->nowildcard_len - prefix)) 368return0; 369 370/* 371 * Here is where we would perform a wildmatch to check if 372 * "name" can be matched as a directory (or a prefix) against 373 * the pathspec. Since wildmatch doesn't have this capability 374 * at the present we have to punt and say that it is a match, 375 * potentially returning a false positive 376 * The submodules themselves will be able to perform more 377 * accurate matching to determine if the pathspec matches. 378 */ 379return MATCHED_RECURSIVELY; 380} 381 382return0; 383} 384 385/* 386 * Given a name and a list of pathspecs, returns the nature of the 387 * closest (i.e. most specific) match of the name to any of the 388 * pathspecs. 389 * 390 * The caller typically calls this multiple times with the same 391 * pathspec and seen[] array but with different name/namelen 392 * (e.g. entries from the index) and is interested in seeing if and 393 * how each pathspec matches all the names it calls this function 394 * with. A mark is left in the seen[] array for each pathspec element 395 * indicating the closest type of match that element achieved, so if 396 * seen[n] remains zero after multiple invocations, that means the nth 397 * pathspec did not match any names, which could indicate that the 398 * user mistyped the nth pathspec. 399 */ 400static intdo_match_pathspec(const struct index_state *istate, 401const struct pathspec *ps, 402const char*name,int namelen, 403int prefix,char*seen, 404unsigned flags) 405{ 406int i, retval =0, exclude = flags & DO_MATCH_EXCLUDE; 407 408GUARD_PATHSPEC(ps, 409 PATHSPEC_FROMTOP | 410 PATHSPEC_MAXDEPTH | 411 PATHSPEC_LITERAL | 412 PATHSPEC_GLOB | 413 PATHSPEC_ICASE | 414 PATHSPEC_EXCLUDE | 415 PATHSPEC_ATTR); 416 417if(!ps->nr) { 418if(!ps->recursive || 419!(ps->magic & PATHSPEC_MAXDEPTH) || 420 ps->max_depth == -1) 421return MATCHED_RECURSIVELY; 422 423if(within_depth(name, namelen,0, ps->max_depth)) 424return MATCHED_EXACTLY; 425else 426return0; 427} 428 429 name += prefix; 430 namelen -= prefix; 431 432for(i = ps->nr -1; i >=0; i--) { 433int how; 434 435if((!exclude && ps->items[i].magic & PATHSPEC_EXCLUDE) || 436( exclude && !(ps->items[i].magic & PATHSPEC_EXCLUDE))) 437continue; 438 439if(seen && seen[i] == MATCHED_EXACTLY) 440continue; 441/* 442 * Make exclude patterns optional and never report 443 * "pathspec ':(exclude)foo' matches no files" 444 */ 445if(seen && ps->items[i].magic & PATHSPEC_EXCLUDE) 446 seen[i] = MATCHED_FNMATCH; 447 how =match_pathspec_item(istate, ps->items+i, prefix, name, 448 namelen, flags); 449if(ps->recursive && 450(ps->magic & PATHSPEC_MAXDEPTH) && 451 ps->max_depth != -1&& 452 how && how != MATCHED_FNMATCH) { 453int len = ps->items[i].len; 454if(name[len] =='/') 455 len++; 456if(within_depth(name+len, namelen-len,0, ps->max_depth)) 457 how = MATCHED_EXACTLY; 458else 459 how =0; 460} 461if(how) { 462if(retval < how) 463 retval = how; 464if(seen && seen[i] < how) 465 seen[i] = how; 466} 467} 468return retval; 469} 470 471intmatch_pathspec(const struct index_state *istate, 472const struct pathspec *ps, 473const char*name,int namelen, 474int prefix,char*seen,int is_dir) 475{ 476int positive, negative; 477unsigned flags = is_dir ? DO_MATCH_DIRECTORY :0; 478 positive =do_match_pathspec(istate, ps, name, namelen, 479 prefix, seen, flags); 480if(!(ps->magic & PATHSPEC_EXCLUDE) || !positive) 481return positive; 482 negative =do_match_pathspec(istate, ps, name, namelen, 483 prefix, seen, 484 flags | DO_MATCH_EXCLUDE); 485return negative ?0: positive; 486} 487 488/** 489 * Check if a submodule is a superset of the pathspec 490 */ 491intsubmodule_path_match(const struct index_state *istate, 492const struct pathspec *ps, 493const char*submodule_name, 494char*seen) 495{ 496int matched =do_match_pathspec(istate, ps, submodule_name, 497strlen(submodule_name), 4980, seen, 499 DO_MATCH_DIRECTORY | 500 DO_MATCH_SUBMODULE); 501return matched; 502} 503 504intreport_path_error(const char*ps_matched, 505const struct pathspec *pathspec) 506{ 507/* 508 * Make sure all pathspec matched; otherwise it is an error. 509 */ 510int num, errors =0; 511for(num =0; num < pathspec->nr; num++) { 512int other, found_dup; 513 514if(ps_matched[num]) 515continue; 516/* 517 * The caller might have fed identical pathspec 518 * twice. Do not barf on such a mistake. 519 * FIXME: parse_pathspec should have eliminated 520 * duplicate pathspec. 521 */ 522for(found_dup = other =0; 523!found_dup && other < pathspec->nr; 524 other++) { 525if(other == num || !ps_matched[other]) 526continue; 527if(!strcmp(pathspec->items[other].original, 528 pathspec->items[num].original)) 529/* 530 * Ok, we have a match already. 531 */ 532 found_dup =1; 533} 534if(found_dup) 535continue; 536 537error(_("pathspec '%s' did not match any file(s) known to git"), 538 pathspec->items[num].original); 539 errors++; 540} 541return errors; 542} 543 544/* 545 * Return the length of the "simple" part of a path match limiter. 546 */ 547intsimple_length(const char*match) 548{ 549int len = -1; 550 551for(;;) { 552unsigned char c = *match++; 553 len++; 554if(c =='\0'||is_glob_special(c)) 555return len; 556} 557} 558 559intno_wildcard(const char*string) 560{ 561return string[simple_length(string)] =='\0'; 562} 563 564voidparse_exclude_pattern(const char**pattern, 565int*patternlen, 566unsigned*flags, 567int*nowildcardlen) 568{ 569const char*p = *pattern; 570size_t i, len; 571 572*flags =0; 573if(*p =='!') { 574*flags |= EXC_FLAG_NEGATIVE; 575 p++; 576} 577 len =strlen(p); 578if(len && p[len -1] =='/') { 579 len--; 580*flags |= EXC_FLAG_MUSTBEDIR; 581} 582for(i =0; i < len; i++) { 583if(p[i] =='/') 584break; 585} 586if(i == len) 587*flags |= EXC_FLAG_NODIR; 588*nowildcardlen =simple_length(p); 589/* 590 * we should have excluded the trailing slash from 'p' too, 591 * but that's one more allocation. Instead just make sure 592 * nowildcardlen does not exceed real patternlen 593 */ 594if(*nowildcardlen > len) 595*nowildcardlen = len; 596if(*p =='*'&&no_wildcard(p +1)) 597*flags |= EXC_FLAG_ENDSWITH; 598*pattern = p; 599*patternlen = len; 600} 601 602voidadd_exclude(const char*string,const char*base, 603int baselen,struct exclude_list *el,int srcpos) 604{ 605struct exclude *x; 606int patternlen; 607unsigned flags; 608int nowildcardlen; 609 610parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen); 611if(flags & EXC_FLAG_MUSTBEDIR) { 612FLEXPTR_ALLOC_MEM(x, pattern, string, patternlen); 613}else{ 614 x =xmalloc(sizeof(*x)); 615 x->pattern = string; 616} 617 x->patternlen = patternlen; 618 x->nowildcardlen = nowildcardlen; 619 x->base = base; 620 x->baselen = baselen; 621 x->flags = flags; 622 x->srcpos = srcpos; 623ALLOC_GROW(el->excludes, el->nr +1, el->alloc); 624 el->excludes[el->nr++] = x; 625 x->el = el; 626} 627 628static intread_skip_worktree_file_from_index(const struct index_state *istate, 629const char*path, 630size_t*size_out,char**data_out, 631struct oid_stat *oid_stat) 632{ 633int pos, len; 634 635 len =strlen(path); 636 pos =index_name_pos(istate, path, len); 637if(pos <0) 638return-1; 639if(!ce_skip_worktree(istate->cache[pos])) 640return-1; 641 642returndo_read_blob(&istate->cache[pos]->oid, oid_stat, size_out, data_out); 643} 644 645/* 646 * Frees memory within el which was allocated for exclude patterns and 647 * the file buffer. Does not free el itself. 648 */ 649voidclear_exclude_list(struct exclude_list *el) 650{ 651int i; 652 653for(i =0; i < el->nr; i++) 654free(el->excludes[i]); 655free(el->excludes); 656free(el->filebuf); 657 658memset(el,0,sizeof(*el)); 659} 660 661static voidtrim_trailing_spaces(char*buf) 662{ 663char*p, *last_space = NULL; 664 665for(p = buf; *p; p++) 666switch(*p) { 667case' ': 668if(!last_space) 669 last_space = p; 670break; 671case'\\': 672 p++; 673if(!*p) 674return; 675/* fallthrough */ 676default: 677 last_space = NULL; 678} 679 680if(last_space) 681*last_space ='\0'; 682} 683 684/* 685 * Given a subdirectory name and "dir" of the current directory, 686 * search the subdir in "dir" and return it, or create a new one if it 687 * does not exist in "dir". 688 * 689 * If "name" has the trailing slash, it'll be excluded in the search. 690 */ 691static struct untracked_cache_dir *lookup_untracked(struct untracked_cache *uc, 692struct untracked_cache_dir *dir, 693const char*name,int len) 694{ 695int first, last; 696struct untracked_cache_dir *d; 697if(!dir) 698return NULL; 699if(len && name[len -1] =='/') 700 len--; 701 first =0; 702 last = dir->dirs_nr; 703while(last > first) { 704int cmp, next = first + ((last - first) >>1); 705 d = dir->dirs[next]; 706 cmp =strncmp(name, d->name, len); 707if(!cmp &&strlen(d->name) > len) 708 cmp = -1; 709if(!cmp) 710return d; 711if(cmp <0) { 712 last = next; 713continue; 714} 715 first = next+1; 716} 717 718 uc->dir_created++; 719FLEX_ALLOC_MEM(d, name, name, len); 720 721ALLOC_GROW(dir->dirs, dir->dirs_nr +1, dir->dirs_alloc); 722MOVE_ARRAY(dir->dirs + first +1, dir->dirs + first, 723 dir->dirs_nr - first); 724 dir->dirs_nr++; 725 dir->dirs[first] = d; 726return d; 727} 728 729static voiddo_invalidate_gitignore(struct untracked_cache_dir *dir) 730{ 731int i; 732 dir->valid =0; 733 dir->untracked_nr =0; 734for(i =0; i < dir->dirs_nr; i++) 735do_invalidate_gitignore(dir->dirs[i]); 736} 737 738static voidinvalidate_gitignore(struct untracked_cache *uc, 739struct untracked_cache_dir *dir) 740{ 741 uc->gitignore_invalidated++; 742do_invalidate_gitignore(dir); 743} 744 745static voidinvalidate_directory(struct untracked_cache *uc, 746struct untracked_cache_dir *dir) 747{ 748int i; 749 750/* 751 * Invalidation increment here is just roughly correct. If 752 * untracked_nr or any of dirs[].recurse is non-zero, we 753 * should increment dir_invalidated too. But that's more 754 * expensive to do. 755 */ 756if(dir->valid) 757 uc->dir_invalidated++; 758 759 dir->valid =0; 760 dir->untracked_nr =0; 761for(i =0; i < dir->dirs_nr; i++) 762 dir->dirs[i]->recurse =0; 763} 764 765static intadd_excludes_from_buffer(char*buf,size_t size, 766const char*base,int baselen, 767struct exclude_list *el); 768 769/* 770 * Given a file with name "fname", read it (either from disk, or from 771 * an index if 'istate' is non-null), parse it and store the 772 * exclude rules in "el". 773 * 774 * If "ss" is not NULL, compute SHA-1 of the exclude file and fill 775 * stat data from disk (only valid if add_excludes returns zero). If 776 * ss_valid is non-zero, "ss" must contain good value as input. 777 */ 778static intadd_excludes(const char*fname,const char*base,int baselen, 779struct exclude_list *el,struct index_state *istate, 780struct oid_stat *oid_stat) 781{ 782struct stat st; 783int r; 784int fd; 785size_t size =0; 786char*buf; 787 788 fd =open(fname, O_RDONLY); 789if(fd <0||fstat(fd, &st) <0) { 790if(fd <0) 791warn_on_fopen_errors(fname); 792else 793close(fd); 794if(!istate) 795return-1; 796 r =read_skip_worktree_file_from_index(istate, fname, 797&size, &buf, 798 oid_stat); 799if(r !=1) 800return r; 801}else{ 802 size =xsize_t(st.st_size); 803if(size ==0) { 804if(oid_stat) { 805fill_stat_data(&oid_stat->stat, &st); 806oidcpy(&oid_stat->oid, the_hash_algo->empty_blob); 807 oid_stat->valid =1; 808} 809close(fd); 810return0; 811} 812 buf =xmallocz(size); 813if(read_in_full(fd, buf, size) != size) { 814free(buf); 815close(fd); 816return-1; 817} 818 buf[size++] ='\n'; 819close(fd); 820if(oid_stat) { 821int pos; 822if(oid_stat->valid && 823!match_stat_data_racy(istate, &oid_stat->stat, &st)) 824;/* no content change, ss->sha1 still good */ 825else if(istate && 826(pos =index_name_pos(istate, fname,strlen(fname))) >=0&& 827!ce_stage(istate->cache[pos]) && 828ce_uptodate(istate->cache[pos]) && 829!would_convert_to_git(istate, fname)) 830oidcpy(&oid_stat->oid, 831&istate->cache[pos]->oid); 832else 833hash_object_file(buf, size,"blob", 834&oid_stat->oid); 835fill_stat_data(&oid_stat->stat, &st); 836 oid_stat->valid =1; 837} 838} 839 840add_excludes_from_buffer(buf, size, base, baselen, el); 841return0; 842} 843 844static intadd_excludes_from_buffer(char*buf,size_t size, 845const char*base,int baselen, 846struct exclude_list *el) 847{ 848int i, lineno =1; 849char*entry; 850 851 el->filebuf = buf; 852 853if(skip_utf8_bom(&buf, size)) 854 size -= buf - el->filebuf; 855 856 entry = buf; 857 858for(i =0; i < size; i++) { 859if(buf[i] =='\n') { 860if(entry != buf + i && entry[0] !='#') { 861 buf[i - (i && buf[i-1] =='\r')] =0; 862trim_trailing_spaces(entry); 863add_exclude(entry, base, baselen, el, lineno); 864} 865 lineno++; 866 entry = buf + i +1; 867} 868} 869return0; 870} 871 872intadd_excludes_from_file_to_list(const char*fname,const char*base, 873int baselen,struct exclude_list *el, 874struct index_state *istate) 875{ 876returnadd_excludes(fname, base, baselen, el, istate, NULL); 877} 878 879intadd_excludes_from_blob_to_list( 880struct object_id *oid, 881const char*base,int baselen, 882struct exclude_list *el) 883{ 884char*buf; 885size_t size; 886int r; 887 888 r =do_read_blob(oid, NULL, &size, &buf); 889if(r !=1) 890return r; 891 892add_excludes_from_buffer(buf, size, base, baselen, el); 893return0; 894} 895 896struct exclude_list *add_exclude_list(struct dir_struct *dir, 897int group_type,const char*src) 898{ 899struct exclude_list *el; 900struct exclude_list_group *group; 901 902 group = &dir->exclude_list_group[group_type]; 903ALLOC_GROW(group->el, group->nr +1, group->alloc); 904 el = &group->el[group->nr++]; 905memset(el,0,sizeof(*el)); 906 el->src = src; 907return el; 908} 909 910/* 911 * Used to set up core.excludesfile and .git/info/exclude lists. 912 */ 913static voidadd_excludes_from_file_1(struct dir_struct *dir,const char*fname, 914struct oid_stat *oid_stat) 915{ 916struct exclude_list *el; 917/* 918 * catch setup_standard_excludes() that's called before 919 * dir->untracked is assigned. That function behaves 920 * differently when dir->untracked is non-NULL. 921 */ 922if(!dir->untracked) 923 dir->unmanaged_exclude_files++; 924 el =add_exclude_list(dir, EXC_FILE, fname); 925if(add_excludes(fname,"",0, el, NULL, oid_stat) <0) 926die(_("cannot use%sas an exclude file"), fname); 927} 928 929voidadd_excludes_from_file(struct dir_struct *dir,const char*fname) 930{ 931 dir->unmanaged_exclude_files++;/* see validate_untracked_cache() */ 932add_excludes_from_file_1(dir, fname, NULL); 933} 934 935intmatch_basename(const char*basename,int basenamelen, 936const char*pattern,int prefix,int patternlen, 937unsigned flags) 938{ 939if(prefix == patternlen) { 940if(patternlen == basenamelen && 941!fspathncmp(pattern, basename, basenamelen)) 942return1; 943}else if(flags & EXC_FLAG_ENDSWITH) { 944/* "*literal" matching against "fooliteral" */ 945if(patternlen -1<= basenamelen && 946!fspathncmp(pattern +1, 947 basename + basenamelen - (patternlen -1), 948 patternlen -1)) 949return1; 950}else{ 951if(fnmatch_icase_mem(pattern, patternlen, 952 basename, basenamelen, 9530) ==0) 954return1; 955} 956return0; 957} 958 959intmatch_pathname(const char*pathname,int pathlen, 960const char*base,int baselen, 961const char*pattern,int prefix,int patternlen, 962unsigned flags) 963{ 964const char*name; 965int namelen; 966 967/* 968 * match with FNM_PATHNAME; the pattern has base implicitly 969 * in front of it. 970 */ 971if(*pattern =='/') { 972 pattern++; 973 patternlen--; 974 prefix--; 975} 976 977/* 978 * baselen does not count the trailing slash. base[] may or 979 * may not end with a trailing slash though. 980 */ 981if(pathlen < baselen +1|| 982(baselen && pathname[baselen] !='/') || 983fspathncmp(pathname, base, baselen)) 984return0; 985 986 namelen = baselen ? pathlen - baselen -1: pathlen; 987 name = pathname + pathlen - namelen; 988 989if(prefix) { 990/* 991 * if the non-wildcard part is longer than the 992 * remaining pathname, surely it cannot match. 993 */ 994if(prefix > namelen) 995return0; 996 997if(fspathncmp(pattern, name, prefix)) 998return0; 999 pattern += prefix;1000 patternlen -= prefix;1001 name += prefix;1002 namelen -= prefix;10031004/*1005 * If the whole pattern did not have a wildcard,1006 * then our prefix match is all we need; we1007 * do not need to call fnmatch at all.1008 */1009if(!patternlen && !namelen)1010return1;1011}10121013returnfnmatch_icase_mem(pattern, patternlen,1014 name, namelen,1015 WM_PATHNAME) ==0;1016}10171018/*1019 * Scan the given exclude list in reverse to see whether pathname1020 * should be ignored. The first match (i.e. the last on the list), if1021 * any, determines the fate. Returns the exclude_list element which1022 * matched, or NULL for undecided.1023 */1024static struct exclude *last_exclude_matching_from_list(const char*pathname,1025int pathlen,1026const char*basename,1027int*dtype,1028struct exclude_list *el,1029struct index_state *istate)1030{1031struct exclude *exc = NULL;/* undecided */1032int i;10331034if(!el->nr)1035return NULL;/* undefined */10361037for(i = el->nr -1;0<= i; i--) {1038struct exclude *x = el->excludes[i];1039const char*exclude = x->pattern;1040int prefix = x->nowildcardlen;10411042if(x->flags & EXC_FLAG_MUSTBEDIR) {1043if(*dtype == DT_UNKNOWN)1044*dtype =get_dtype(NULL, istate, pathname, pathlen);1045if(*dtype != DT_DIR)1046continue;1047}10481049if(x->flags & EXC_FLAG_NODIR) {1050if(match_basename(basename,1051 pathlen - (basename - pathname),1052 exclude, prefix, x->patternlen,1053 x->flags)) {1054 exc = x;1055break;1056}1057continue;1058}10591060assert(x->baselen ==0|| x->base[x->baselen -1] =='/');1061if(match_pathname(pathname, pathlen,1062 x->base, x->baselen ? x->baselen -1:0,1063 exclude, prefix, x->patternlen, x->flags)) {1064 exc = x;1065break;1066}1067}1068return exc;1069}10701071/*1072 * Scan the list and let the last match determine the fate.1073 * Return 1 for exclude, 0 for include and -1 for undecided.1074 */1075intis_excluded_from_list(const char*pathname,1076int pathlen,const char*basename,int*dtype,1077struct exclude_list *el,struct index_state *istate)1078{1079struct exclude *exclude;1080 exclude =last_exclude_matching_from_list(pathname, pathlen, basename,1081 dtype, el, istate);1082if(exclude)1083return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1084return-1;/* undecided */1085}10861087static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir,1088struct index_state *istate,1089const char*pathname,int pathlen,const char*basename,1090int*dtype_p)1091{1092int i, j;1093struct exclude_list_group *group;1094struct exclude *exclude;1095for(i = EXC_CMDL; i <= EXC_FILE; i++) {1096 group = &dir->exclude_list_group[i];1097for(j = group->nr -1; j >=0; j--) {1098 exclude =last_exclude_matching_from_list(1099 pathname, pathlen, basename, dtype_p,1100&group->el[j], istate);1101if(exclude)1102return exclude;1103}1104}1105return NULL;1106}11071108/*1109 * Loads the per-directory exclude list for the substring of base1110 * which has a char length of baselen.1111 */1112static voidprep_exclude(struct dir_struct *dir,1113struct index_state *istate,1114const char*base,int baselen)1115{1116struct exclude_list_group *group;1117struct exclude_list *el;1118struct exclude_stack *stk = NULL;1119struct untracked_cache_dir *untracked;1120int current;11211122 group = &dir->exclude_list_group[EXC_DIRS];11231124/*1125 * Pop the exclude lists from the EXCL_DIRS exclude_list_group1126 * which originate from directories not in the prefix of the1127 * path being checked.1128 */1129while((stk = dir->exclude_stack) != NULL) {1130if(stk->baselen <= baselen &&1131!strncmp(dir->basebuf.buf, base, stk->baselen))1132break;1133 el = &group->el[dir->exclude_stack->exclude_ix];1134 dir->exclude_stack = stk->prev;1135 dir->exclude = NULL;1136free((char*)el->src);/* see strbuf_detach() below */1137clear_exclude_list(el);1138free(stk);1139 group->nr--;1140}11411142/* Skip traversing into sub directories if the parent is excluded */1143if(dir->exclude)1144return;11451146/*1147 * Lazy initialization. All call sites currently just1148 * memset(dir, 0, sizeof(*dir)) before use. Changing all of1149 * them seems lots of work for little benefit.1150 */1151if(!dir->basebuf.buf)1152strbuf_init(&dir->basebuf, PATH_MAX);11531154/* Read from the parent directories and push them down. */1155 current = stk ? stk->baselen : -1;1156strbuf_setlen(&dir->basebuf, current <0?0: current);1157if(dir->untracked)1158 untracked = stk ? stk->ucd : dir->untracked->root;1159else1160 untracked = NULL;11611162while(current < baselen) {1163const char*cp;1164struct oid_stat oid_stat;11651166 stk =xcalloc(1,sizeof(*stk));1167if(current <0) {1168 cp = base;1169 current =0;1170}else{1171 cp =strchr(base + current +1,'/');1172if(!cp)1173die("oops in prep_exclude");1174 cp++;1175 untracked =1176lookup_untracked(dir->untracked, untracked,1177 base + current,1178 cp - base - current);1179}1180 stk->prev = dir->exclude_stack;1181 stk->baselen = cp - base;1182 stk->exclude_ix = group->nr;1183 stk->ucd = untracked;1184 el =add_exclude_list(dir, EXC_DIRS, NULL);1185strbuf_add(&dir->basebuf, base + current, stk->baselen - current);1186assert(stk->baselen == dir->basebuf.len);11871188/* Abort if the directory is excluded */1189if(stk->baselen) {1190int dt = DT_DIR;1191 dir->basebuf.buf[stk->baselen -1] =0;1192 dir->exclude =last_exclude_matching_from_lists(dir,1193 istate,1194 dir->basebuf.buf, stk->baselen -1,1195 dir->basebuf.buf + current, &dt);1196 dir->basebuf.buf[stk->baselen -1] ='/';1197if(dir->exclude &&1198 dir->exclude->flags & EXC_FLAG_NEGATIVE)1199 dir->exclude = NULL;1200if(dir->exclude) {1201 dir->exclude_stack = stk;1202return;1203}1204}12051206/* Try to read per-directory file */1207oidclr(&oid_stat.oid);1208 oid_stat.valid =0;1209if(dir->exclude_per_dir &&1210/*1211 * If we know that no files have been added in1212 * this directory (i.e. valid_cached_dir() has1213 * been executed and set untracked->valid) ..1214 */1215(!untracked || !untracked->valid ||1216/*1217 * .. and .gitignore does not exist before1218 * (i.e. null exclude_oid). Then we can skip1219 * loading .gitignore, which would result in1220 * ENOENT anyway.1221 */1222!is_null_oid(&untracked->exclude_oid))) {1223/*1224 * dir->basebuf gets reused by the traversal, but we1225 * need fname to remain unchanged to ensure the src1226 * member of each struct exclude correctly1227 * back-references its source file. Other invocations1228 * of add_exclude_list provide stable strings, so we1229 * strbuf_detach() and free() here in the caller.1230 */1231struct strbuf sb = STRBUF_INIT;1232strbuf_addbuf(&sb, &dir->basebuf);1233strbuf_addstr(&sb, dir->exclude_per_dir);1234 el->src =strbuf_detach(&sb, NULL);1235add_excludes(el->src, el->src, stk->baselen, el, istate,1236 untracked ? &oid_stat : NULL);1237}1238/*1239 * NEEDSWORK: when untracked cache is enabled, prep_exclude()1240 * will first be called in valid_cached_dir() then maybe many1241 * times more in last_exclude_matching(). When the cache is1242 * used, last_exclude_matching() will not be called and1243 * reading .gitignore content will be a waste.1244 *1245 * So when it's called by valid_cached_dir() and we can get1246 * .gitignore SHA-1 from the index (i.e. .gitignore is not1247 * modified on work tree), we could delay reading the1248 * .gitignore content until we absolutely need it in1249 * last_exclude_matching(). Be careful about ignore rule1250 * order, though, if you do that.1251 */1252if(untracked &&1253!oideq(&oid_stat.oid, &untracked->exclude_oid)) {1254invalidate_gitignore(dir->untracked, untracked);1255oidcpy(&untracked->exclude_oid, &oid_stat.oid);1256}1257 dir->exclude_stack = stk;1258 current = stk->baselen;1259}1260strbuf_setlen(&dir->basebuf, baselen);1261}12621263/*1264 * Loads the exclude lists for the directory containing pathname, then1265 * scans all exclude lists to determine whether pathname is excluded.1266 * Returns the exclude_list element which matched, or NULL for1267 * undecided.1268 */1269struct exclude *last_exclude_matching(struct dir_struct *dir,1270struct index_state *istate,1271const char*pathname,1272int*dtype_p)1273{1274int pathlen =strlen(pathname);1275const char*basename =strrchr(pathname,'/');1276 basename = (basename) ? basename+1: pathname;12771278prep_exclude(dir, istate, pathname, basename-pathname);12791280if(dir->exclude)1281return dir->exclude;12821283returnlast_exclude_matching_from_lists(dir, istate, pathname, pathlen,1284 basename, dtype_p);1285}12861287/*1288 * Loads the exclude lists for the directory containing pathname, then1289 * scans all exclude lists to determine whether pathname is excluded.1290 * Returns 1 if true, otherwise 0.1291 */1292intis_excluded(struct dir_struct *dir,struct index_state *istate,1293const char*pathname,int*dtype_p)1294{1295struct exclude *exclude =1296last_exclude_matching(dir, istate, pathname, dtype_p);1297if(exclude)1298return exclude->flags & EXC_FLAG_NEGATIVE ?0:1;1299return0;1300}13011302static struct dir_entry *dir_entry_new(const char*pathname,int len)1303{1304struct dir_entry *ent;13051306FLEX_ALLOC_MEM(ent, name, pathname, len);1307 ent->len = len;1308return ent;1309}13101311static struct dir_entry *dir_add_name(struct dir_struct *dir,1312struct index_state *istate,1313const char*pathname,int len)1314{1315if(index_file_exists(istate, pathname, len, ignore_case))1316return NULL;13171318ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);1319return dir->entries[dir->nr++] =dir_entry_new(pathname, len);1320}13211322struct dir_entry *dir_add_ignored(struct dir_struct *dir,1323struct index_state *istate,1324const char*pathname,int len)1325{1326if(!index_name_is_other(istate, pathname, len))1327return NULL;13281329ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);1330return dir->ignored[dir->ignored_nr++] =dir_entry_new(pathname, len);1331}13321333enum exist_status {1334 index_nonexistent =0,1335 index_directory,1336 index_gitdir1337};13381339/*1340 * Do not use the alphabetically sorted index to look up1341 * the directory name; instead, use the case insensitive1342 * directory hash.1343 */1344static enum exist_status directory_exists_in_index_icase(struct index_state *istate,1345const char*dirname,int len)1346{1347struct cache_entry *ce;13481349if(index_dir_exists(istate, dirname, len))1350return index_directory;13511352 ce =index_file_exists(istate, dirname, len, ignore_case);1353if(ce &&S_ISGITLINK(ce->ce_mode))1354return index_gitdir;13551356return index_nonexistent;1357}13581359/*1360 * The index sorts alphabetically by entry name, which1361 * means that a gitlink sorts as '\0' at the end, while1362 * a directory (which is defined not as an entry, but as1363 * the files it contains) will sort with the '/' at the1364 * end.1365 */1366static enum exist_status directory_exists_in_index(struct index_state *istate,1367const char*dirname,int len)1368{1369int pos;13701371if(ignore_case)1372returndirectory_exists_in_index_icase(istate, dirname, len);13731374 pos =index_name_pos(istate, dirname, len);1375if(pos <0)1376 pos = -pos-1;1377while(pos < istate->cache_nr) {1378const struct cache_entry *ce = istate->cache[pos++];1379unsigned char endchar;13801381if(strncmp(ce->name, dirname, len))1382break;1383 endchar = ce->name[len];1384if(endchar >'/')1385break;1386if(endchar =='/')1387return index_directory;1388if(!endchar &&S_ISGITLINK(ce->ce_mode))1389return index_gitdir;1390}1391return index_nonexistent;1392}13931394/*1395 * When we find a directory when traversing the filesystem, we1396 * have three distinct cases:1397 *1398 * - ignore it1399 * - see it as a directory1400 * - recurse into it1401 *1402 * and which one we choose depends on a combination of existing1403 * git index contents and the flags passed into the directory1404 * traversal routine.1405 *1406 * Case 1: If we *already* have entries in the index under that1407 * directory name, we always recurse into the directory to see1408 * all the files.1409 *1410 * Case 2: If we *already* have that directory name as a gitlink,1411 * we always continue to see it as a gitlink, regardless of whether1412 * there is an actual git directory there or not (it might not1413 * be checked out as a subproject!)1414 *1415 * Case 3: if we didn't have it in the index previously, we1416 * have a few sub-cases:1417 *1418 * (a) if "show_other_directories" is true, we show it as1419 * just a directory, unless "hide_empty_directories" is1420 * also true, in which case we need to check if it contains any1421 * untracked and / or ignored files.1422 * (b) if it looks like a git directory, and we don't have1423 * 'no_gitlinks' set we treat it as a gitlink, and show it1424 * as a directory.1425 * (c) otherwise, we recurse into it.1426 */1427static enum path_treatment treat_directory(struct dir_struct *dir,1428struct index_state *istate,1429struct untracked_cache_dir *untracked,1430const char*dirname,int len,int baselen,int exclude,1431const struct pathspec *pathspec)1432{1433/* The "len-1" is to strip the final '/' */1434switch(directory_exists_in_index(istate, dirname, len-1)) {1435case index_directory:1436return path_recurse;14371438case index_gitdir:1439return path_none;14401441case index_nonexistent:1442if(dir->flags & DIR_SHOW_OTHER_DIRECTORIES)1443break;1444if(exclude &&1445(dir->flags & DIR_SHOW_IGNORED_TOO) &&1446(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING)) {14471448/*1449 * This is an excluded directory and we are1450 * showing ignored paths that match an exclude1451 * pattern. (e.g. show directory as ignored1452 * only if it matches an exclude pattern).1453 * This path will either be 'path_excluded`1454 * (if we are showing empty directories or if1455 * the directory is not empty), or will be1456 * 'path_none' (empty directory, and we are1457 * not showing empty directories).1458 */1459if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1460return path_excluded;14611462if(read_directory_recursive(dir, istate, dirname, len,1463 untracked,1,1, pathspec) == path_excluded)1464return path_excluded;14651466return path_none;1467}1468if(!(dir->flags & DIR_NO_GITLINKS)) {1469struct strbuf sb = STRBUF_INIT;1470strbuf_addstr(&sb, dirname);1471if(is_nonbare_repository_dir(&sb))1472return exclude ? path_excluded : path_untracked;1473strbuf_release(&sb);1474}1475return path_recurse;1476}14771478/* This is the "show_other_directories" case */14791480if(!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))1481return exclude ? path_excluded : path_untracked;14821483 untracked =lookup_untracked(dir->untracked, untracked,1484 dirname + baselen, len - baselen);14851486/*1487 * If this is an excluded directory, then we only need to check if1488 * the directory contains any files.1489 */1490returnread_directory_recursive(dir, istate, dirname, len,1491 untracked,1, exclude, pathspec);1492}14931494/*1495 * This is an inexact early pruning of any recursive directory1496 * reading - if the path cannot possibly be in the pathspec,1497 * return true, and we'll skip it early.1498 */1499static intsimplify_away(const char*path,int pathlen,1500const struct pathspec *pathspec)1501{1502int i;15031504if(!pathspec || !pathspec->nr)1505return0;15061507GUARD_PATHSPEC(pathspec,1508 PATHSPEC_FROMTOP |1509 PATHSPEC_MAXDEPTH |1510 PATHSPEC_LITERAL |1511 PATHSPEC_GLOB |1512 PATHSPEC_ICASE |1513 PATHSPEC_EXCLUDE |1514 PATHSPEC_ATTR);15151516for(i =0; i < pathspec->nr; i++) {1517const struct pathspec_item *item = &pathspec->items[i];1518int len = item->nowildcard_len;15191520if(len > pathlen)1521 len = pathlen;1522if(!ps_strncmp(item, item->match, path, len))1523return0;1524}15251526return1;1527}15281529/*1530 * This function tells us whether an excluded path matches a1531 * list of "interesting" pathspecs. That is, whether a path matched1532 * by any of the pathspecs could possibly be ignored by excluding1533 * the specified path. This can happen if:1534 *1535 * 1. the path is mentioned explicitly in the pathspec1536 *1537 * 2. the path is a directory prefix of some element in the1538 * pathspec1539 */1540static intexclude_matches_pathspec(const char*path,int pathlen,1541const struct pathspec *pathspec)1542{1543int i;15441545if(!pathspec || !pathspec->nr)1546return0;15471548GUARD_PATHSPEC(pathspec,1549 PATHSPEC_FROMTOP |1550 PATHSPEC_MAXDEPTH |1551 PATHSPEC_LITERAL |1552 PATHSPEC_GLOB |1553 PATHSPEC_ICASE |1554 PATHSPEC_EXCLUDE);15551556for(i =0; i < pathspec->nr; i++) {1557const struct pathspec_item *item = &pathspec->items[i];1558int len = item->nowildcard_len;15591560if(len == pathlen &&1561!ps_strncmp(item, item->match, path, pathlen))1562return1;1563if(len > pathlen &&1564 item->match[pathlen] =='/'&&1565!ps_strncmp(item, item->match, path, pathlen))1566return1;1567}1568return0;1569}15701571static intget_index_dtype(struct index_state *istate,1572const char*path,int len)1573{1574int pos;1575const struct cache_entry *ce;15761577 ce =index_file_exists(istate, path, len,0);1578if(ce) {1579if(!ce_uptodate(ce))1580return DT_UNKNOWN;1581if(S_ISGITLINK(ce->ce_mode))1582return DT_DIR;1583/*1584 * Nobody actually cares about the1585 * difference between DT_LNK and DT_REG1586 */1587return DT_REG;1588}15891590/* Try to look it up as a directory */1591 pos =index_name_pos(istate, path, len);1592if(pos >=0)1593return DT_UNKNOWN;1594 pos = -pos-1;1595while(pos < istate->cache_nr) {1596 ce = istate->cache[pos++];1597if(strncmp(ce->name, path, len))1598break;1599if(ce->name[len] >'/')1600break;1601if(ce->name[len] <'/')1602continue;1603if(!ce_uptodate(ce))1604break;/* continue? */1605return DT_DIR;1606}1607return DT_UNKNOWN;1608}16091610static intget_dtype(struct dirent *de,struct index_state *istate,1611const char*path,int len)1612{1613int dtype = de ?DTYPE(de) : DT_UNKNOWN;1614struct stat st;16151616if(dtype != DT_UNKNOWN)1617return dtype;1618 dtype =get_index_dtype(istate, path, len);1619if(dtype != DT_UNKNOWN)1620return dtype;1621if(lstat(path, &st))1622return dtype;1623if(S_ISREG(st.st_mode))1624return DT_REG;1625if(S_ISDIR(st.st_mode))1626return DT_DIR;1627if(S_ISLNK(st.st_mode))1628return DT_LNK;1629return dtype;1630}16311632static enum path_treatment treat_one_path(struct dir_struct *dir,1633struct untracked_cache_dir *untracked,1634struct index_state *istate,1635struct strbuf *path,1636int baselen,1637const struct pathspec *pathspec,1638int dtype,struct dirent *de)1639{1640int exclude;1641int has_path_in_index = !!index_file_exists(istate, path->buf, path->len, ignore_case);1642enum path_treatment path_treatment;16431644if(dtype == DT_UNKNOWN)1645 dtype =get_dtype(de, istate, path->buf, path->len);16461647/* Always exclude indexed files */1648if(dtype != DT_DIR && has_path_in_index)1649return path_none;16501651/*1652 * When we are looking at a directory P in the working tree,1653 * there are three cases:1654 *1655 * (1) P exists in the index. Everything inside the directory P in1656 * the working tree needs to go when P is checked out from the1657 * index.1658 *1659 * (2) P does not exist in the index, but there is P/Q in the index.1660 * We know P will stay a directory when we check out the contents1661 * of the index, but we do not know yet if there is a directory1662 * P/Q in the working tree to be killed, so we need to recurse.1663 *1664 * (3) P does not exist in the index, and there is no P/Q in the index1665 * to require P to be a directory, either. Only in this case, we1666 * know that everything inside P will not be killed without1667 * recursing.1668 */1669if((dir->flags & DIR_COLLECT_KILLED_ONLY) &&1670(dtype == DT_DIR) &&1671!has_path_in_index &&1672(directory_exists_in_index(istate, path->buf, path->len) == index_nonexistent))1673return path_none;16741675 exclude =is_excluded(dir, istate, path->buf, &dtype);16761677/*1678 * Excluded? If we don't explicitly want to show1679 * ignored files, ignore it1680 */1681if(exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO)))1682return path_excluded;16831684switch(dtype) {1685default:1686return path_none;1687case DT_DIR:1688strbuf_addch(path,'/');1689 path_treatment =treat_directory(dir, istate, untracked,1690 path->buf, path->len,1691 baselen, exclude, pathspec);1692/*1693 * If 1) we only want to return directories that1694 * match an exclude pattern and 2) this directory does1695 * not match an exclude pattern but all of its1696 * contents are excluded, then indicate that we should1697 * recurse into this directory (instead of marking the1698 * directory itself as an ignored path).1699 */1700if(!exclude &&1701 path_treatment == path_excluded &&1702(dir->flags & DIR_SHOW_IGNORED_TOO) &&1703(dir->flags & DIR_SHOW_IGNORED_TOO_MODE_MATCHING))1704return path_recurse;1705return path_treatment;1706case DT_REG:1707case DT_LNK:1708return exclude ? path_excluded : path_untracked;1709}1710}17111712static enum path_treatment treat_path_fast(struct dir_struct *dir,1713struct untracked_cache_dir *untracked,1714struct cached_dir *cdir,1715struct index_state *istate,1716struct strbuf *path,1717int baselen,1718const struct pathspec *pathspec)1719{1720strbuf_setlen(path, baselen);1721if(!cdir->ucd) {1722strbuf_addstr(path, cdir->file);1723return path_untracked;1724}1725strbuf_addstr(path, cdir->ucd->name);1726/* treat_one_path() does this before it calls treat_directory() */1727strbuf_complete(path,'/');1728if(cdir->ucd->check_only)1729/*1730 * check_only is set as a result of treat_directory() getting1731 * to its bottom. Verify again the same set of directories1732 * with check_only set.1733 */1734returnread_directory_recursive(dir, istate, path->buf, path->len,1735 cdir->ucd,1,0, pathspec);1736/*1737 * We get path_recurse in the first run when1738 * directory_exists_in_index() returns index_nonexistent. We1739 * are sure that new changes in the index does not impact the1740 * outcome. Return now.1741 */1742return path_recurse;1743}17441745static enum path_treatment treat_path(struct dir_struct *dir,1746struct untracked_cache_dir *untracked,1747struct cached_dir *cdir,1748struct index_state *istate,1749struct strbuf *path,1750int baselen,1751const struct pathspec *pathspec)1752{1753int dtype;1754struct dirent *de = cdir->de;17551756if(!de)1757returntreat_path_fast(dir, untracked, cdir, istate, path,1758 baselen, pathspec);1759if(is_dot_or_dotdot(de->d_name) || !fspathcmp(de->d_name,".git"))1760return path_none;1761strbuf_setlen(path, baselen);1762strbuf_addstr(path, de->d_name);1763if(simplify_away(path->buf, path->len, pathspec))1764return path_none;17651766 dtype =DTYPE(de);1767returntreat_one_path(dir, untracked, istate, path, baselen, pathspec, dtype, de);1768}17691770static voidadd_untracked(struct untracked_cache_dir *dir,const char*name)1771{1772if(!dir)1773return;1774ALLOC_GROW(dir->untracked, dir->untracked_nr +1,1775 dir->untracked_alloc);1776 dir->untracked[dir->untracked_nr++] =xstrdup(name);1777}17781779static intvalid_cached_dir(struct dir_struct *dir,1780struct untracked_cache_dir *untracked,1781struct index_state *istate,1782struct strbuf *path,1783int check_only)1784{1785struct stat st;17861787if(!untracked)1788return0;17891790/*1791 * With fsmonitor, we can trust the untracked cache's valid field.1792 */1793refresh_fsmonitor(istate);1794if(!(dir->untracked->use_fsmonitor && untracked->valid)) {1795if(lstat(path->len ? path->buf :".", &st)) {1796memset(&untracked->stat_data,0,sizeof(untracked->stat_data));1797return0;1798}1799if(!untracked->valid ||1800match_stat_data_racy(istate, &untracked->stat_data, &st)) {1801fill_stat_data(&untracked->stat_data, &st);1802return0;1803}1804}18051806if(untracked->check_only != !!check_only)1807return0;18081809/*1810 * prep_exclude will be called eventually on this directory,1811 * but it's called much later in last_exclude_matching(). We1812 * need it now to determine the validity of the cache for this1813 * path. The next calls will be nearly no-op, the way1814 * prep_exclude() is designed.1815 */1816if(path->len && path->buf[path->len -1] !='/') {1817strbuf_addch(path,'/');1818prep_exclude(dir, istate, path->buf, path->len);1819strbuf_setlen(path, path->len -1);1820}else1821prep_exclude(dir, istate, path->buf, path->len);18221823/* hopefully prep_exclude() haven't invalidated this entry... */1824return untracked->valid;1825}18261827static intopen_cached_dir(struct cached_dir *cdir,1828struct dir_struct *dir,1829struct untracked_cache_dir *untracked,1830struct index_state *istate,1831struct strbuf *path,1832int check_only)1833{1834const char*c_path;18351836memset(cdir,0,sizeof(*cdir));1837 cdir->untracked = untracked;1838if(valid_cached_dir(dir, untracked, istate, path, check_only))1839return0;1840 c_path = path->len ? path->buf :".";1841 cdir->fdir =opendir(c_path);1842if(!cdir->fdir)1843warning_errno(_("could not open directory '%s'"), c_path);1844if(dir->untracked) {1845invalidate_directory(dir->untracked, untracked);1846 dir->untracked->dir_opened++;1847}1848if(!cdir->fdir)1849return-1;1850return0;1851}18521853static intread_cached_dir(struct cached_dir *cdir)1854{1855if(cdir->fdir) {1856 cdir->de =readdir(cdir->fdir);1857if(!cdir->de)1858return-1;1859return0;1860}1861while(cdir->nr_dirs < cdir->untracked->dirs_nr) {1862struct untracked_cache_dir *d = cdir->untracked->dirs[cdir->nr_dirs];1863if(!d->recurse) {1864 cdir->nr_dirs++;1865continue;1866}1867 cdir->ucd = d;1868 cdir->nr_dirs++;1869return0;1870}1871 cdir->ucd = NULL;1872if(cdir->nr_files < cdir->untracked->untracked_nr) {1873struct untracked_cache_dir *d = cdir->untracked;1874 cdir->file = d->untracked[cdir->nr_files++];1875return0;1876}1877return-1;1878}18791880static voidclose_cached_dir(struct cached_dir *cdir)1881{1882if(cdir->fdir)1883closedir(cdir->fdir);1884/*1885 * We have gone through this directory and found no untracked1886 * entries. Mark it valid.1887 */1888if(cdir->untracked) {1889 cdir->untracked->valid =1;1890 cdir->untracked->recurse =1;1891}1892}18931894/*1895 * Read a directory tree. We currently ignore anything but1896 * directories, regular files and symlinks. That's because git1897 * doesn't handle them at all yet. Maybe that will change some1898 * day.1899 *1900 * Also, we ignore the name ".git" (even if it is not a directory).1901 * That likely will not change.1902 *1903 * If 'stop_at_first_file' is specified, 'path_excluded' is returned1904 * to signal that a file was found. This is the least significant value that1905 * indicates that a file was encountered that does not depend on the order of1906 * whether an untracked or exluded path was encountered first.1907 *1908 * Returns the most significant path_treatment value encountered in the scan.1909 * If 'stop_at_first_file' is specified, `path_excluded` is the most1910 * significant path_treatment value that will be returned.1911 */19121913static enum path_treatment read_directory_recursive(struct dir_struct *dir,1914struct index_state *istate,const char*base,int baselen,1915struct untracked_cache_dir *untracked,int check_only,1916int stop_at_first_file,const struct pathspec *pathspec)1917{1918struct cached_dir cdir;1919enum path_treatment state, subdir_state, dir_state = path_none;1920struct strbuf path = STRBUF_INIT;19211922strbuf_add(&path, base, baselen);19231924if(open_cached_dir(&cdir, dir, untracked, istate, &path, check_only))1925goto out;19261927if(untracked)1928 untracked->check_only = !!check_only;19291930while(!read_cached_dir(&cdir)) {1931/* check how the file or directory should be treated */1932 state =treat_path(dir, untracked, &cdir, istate, &path,1933 baselen, pathspec);19341935if(state > dir_state)1936 dir_state = state;19371938/* recurse into subdir if instructed by treat_path */1939if((state == path_recurse) ||1940((state == path_untracked) &&1941(dir->flags & DIR_SHOW_IGNORED_TOO) &&1942(get_dtype(cdir.de, istate, path.buf, path.len) == DT_DIR))) {1943struct untracked_cache_dir *ud;1944 ud =lookup_untracked(dir->untracked, untracked,1945 path.buf + baselen,1946 path.len - baselen);1947 subdir_state =1948read_directory_recursive(dir, istate, path.buf,1949 path.len, ud,1950 check_only, stop_at_first_file, pathspec);1951if(subdir_state > dir_state)1952 dir_state = subdir_state;1953}19541955if(check_only) {1956if(stop_at_first_file) {1957/*1958 * If stopping at first file, then1959 * signal that a file was found by1960 * returning `path_excluded`. This is1961 * to return a consistent value1962 * regardless of whether an ignored or1963 * excluded file happened to be1964 * encountered 1st.1965 *1966 * In current usage, the1967 * `stop_at_first_file` is passed when1968 * an ancestor directory has matched1969 * an exclude pattern, so any found1970 * files will be excluded.1971 */1972if(dir_state >= path_excluded) {1973 dir_state = path_excluded;1974break;1975}1976}19771978/* abort early if maximum state has been reached */1979if(dir_state == path_untracked) {1980if(cdir.fdir)1981add_untracked(untracked, path.buf + baselen);1982break;1983}1984/* skip the dir_add_* part */1985continue;1986}19871988/* add the path to the appropriate result list */1989switch(state) {1990case path_excluded:1991if(dir->flags & DIR_SHOW_IGNORED)1992dir_add_name(dir, istate, path.buf, path.len);1993else if((dir->flags & DIR_SHOW_IGNORED_TOO) ||1994((dir->flags & DIR_COLLECT_IGNORED) &&1995exclude_matches_pathspec(path.buf, path.len,1996 pathspec)))1997dir_add_ignored(dir, istate, path.buf, path.len);1998break;19992000case path_untracked:2001if(dir->flags & DIR_SHOW_IGNORED)2002break;2003dir_add_name(dir, istate, path.buf, path.len);2004if(cdir.fdir)2005add_untracked(untracked, path.buf + baselen);2006break;20072008default:2009break;2010}2011}2012close_cached_dir(&cdir);2013 out:2014strbuf_release(&path);20152016return dir_state;2017}20182019intcmp_dir_entry(const void*p1,const void*p2)2020{2021const struct dir_entry *e1 = *(const struct dir_entry **)p1;2022const struct dir_entry *e2 = *(const struct dir_entry **)p2;20232024returnname_compare(e1->name, e1->len, e2->name, e2->len);2025}20262027/* check if *out lexically strictly contains *in */2028intcheck_dir_entry_contains(const struct dir_entry *out,const struct dir_entry *in)2029{2030return(out->len < in->len) &&2031(out->name[out->len -1] =='/') &&2032!memcmp(out->name, in->name, out->len);2033}20342035static inttreat_leading_path(struct dir_struct *dir,2036struct index_state *istate,2037const char*path,int len,2038const struct pathspec *pathspec)2039{2040struct strbuf sb = STRBUF_INIT;2041int baselen, rc =0;2042const char*cp;2043int old_flags = dir->flags;20442045while(len && path[len -1] =='/')2046 len--;2047if(!len)2048return1;2049 baselen =0;2050 dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES;2051while(1) {2052 cp = path + baselen + !!baselen;2053 cp =memchr(cp,'/', path + len - cp);2054if(!cp)2055 baselen = len;2056else2057 baselen = cp - path;2058strbuf_setlen(&sb,0);2059strbuf_add(&sb, path, baselen);2060if(!is_directory(sb.buf))2061break;2062if(simplify_away(sb.buf, sb.len, pathspec))2063break;2064if(treat_one_path(dir, NULL, istate, &sb, baselen, pathspec,2065 DT_DIR, NULL) == path_none)2066break;/* do not recurse into it */2067if(len <= baselen) {2068 rc =1;2069break;/* finished checking */2070}2071}2072strbuf_release(&sb);2073 dir->flags = old_flags;2074return rc;2075}20762077static const char*get_ident_string(void)2078{2079static struct strbuf sb = STRBUF_INIT;2080struct utsname uts;20812082if(sb.len)2083return sb.buf;2084if(uname(&uts) <0)2085die_errno(_("failed to get kernel name and information"));2086strbuf_addf(&sb,"Location%s, system%s",get_git_work_tree(),2087 uts.sysname);2088return sb.buf;2089}20902091static intident_in_untracked(const struct untracked_cache *uc)2092{2093/*2094 * Previous git versions may have saved many NUL separated2095 * strings in the "ident" field, but it is insane to manage2096 * many locations, so just take care of the first one.2097 */20982099return!strcmp(uc->ident.buf,get_ident_string());2100}21012102static voidset_untracked_ident(struct untracked_cache *uc)2103{2104strbuf_reset(&uc->ident);2105strbuf_addstr(&uc->ident,get_ident_string());21062107/*2108 * This strbuf used to contain a list of NUL separated2109 * strings, so save NUL too for backward compatibility.2110 */2111strbuf_addch(&uc->ident,0);2112}21132114static voidnew_untracked_cache(struct index_state *istate)2115{2116struct untracked_cache *uc =xcalloc(1,sizeof(*uc));2117strbuf_init(&uc->ident,100);2118 uc->exclude_per_dir =".gitignore";2119/* should be the same flags used by git-status */2120 uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;2121set_untracked_ident(uc);2122 istate->untracked = uc;2123 istate->cache_changed |= UNTRACKED_CHANGED;2124}21252126voidadd_untracked_cache(struct index_state *istate)2127{2128if(!istate->untracked) {2129new_untracked_cache(istate);2130}else{2131if(!ident_in_untracked(istate->untracked)) {2132free_untracked_cache(istate->untracked);2133new_untracked_cache(istate);2134}2135}2136}21372138voidremove_untracked_cache(struct index_state *istate)2139{2140if(istate->untracked) {2141free_untracked_cache(istate->untracked);2142 istate->untracked = NULL;2143 istate->cache_changed |= UNTRACKED_CHANGED;2144}2145}21462147static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,2148int base_len,2149const struct pathspec *pathspec)2150{2151struct untracked_cache_dir *root;2152static int untracked_cache_disabled = -1;21532154if(!dir->untracked)2155return NULL;2156if(untracked_cache_disabled <0)2157 untracked_cache_disabled =git_env_bool("GIT_DISABLE_UNTRACKED_CACHE",0);2158if(untracked_cache_disabled)2159return NULL;21602161/*2162 * We only support $GIT_DIR/info/exclude and core.excludesfile2163 * as the global ignore rule files. Any other additions2164 * (e.g. from command line) invalidate the cache. This2165 * condition also catches running setup_standard_excludes()2166 * before setting dir->untracked!2167 */2168if(dir->unmanaged_exclude_files)2169return NULL;21702171/*2172 * Optimize for the main use case only: whole-tree git2173 * status. More work involved in treat_leading_path() if we2174 * use cache on just a subset of the worktree. pathspec2175 * support could make the matter even worse.2176 */2177if(base_len || (pathspec && pathspec->nr))2178return NULL;21792180/* Different set of flags may produce different results */2181if(dir->flags != dir->untracked->dir_flags ||2182/*2183 * See treat_directory(), case index_nonexistent. Without2184 * this flag, we may need to also cache .git file content2185 * for the resolve_gitlink_ref() call, which we don't.2186 */2187!(dir->flags & DIR_SHOW_OTHER_DIRECTORIES) ||2188/* We don't support collecting ignore files */2189(dir->flags & (DIR_SHOW_IGNORED | DIR_SHOW_IGNORED_TOO |2190 DIR_COLLECT_IGNORED)))2191return NULL;21922193/*2194 * If we use .gitignore in the cache and now you change it to2195 * .gitexclude, everything will go wrong.2196 */2197if(dir->exclude_per_dir != dir->untracked->exclude_per_dir &&2198strcmp(dir->exclude_per_dir, dir->untracked->exclude_per_dir))2199return NULL;22002201/*2202 * EXC_CMDL is not considered in the cache. If people set it,2203 * skip the cache.2204 */2205if(dir->exclude_list_group[EXC_CMDL].nr)2206return NULL;22072208if(!ident_in_untracked(dir->untracked)) {2209warning(_("untracked cache is disabled on this system or location"));2210return NULL;2211}22122213if(!dir->untracked->root) {2214const int len =sizeof(*dir->untracked->root);2215 dir->untracked->root =xmalloc(len);2216memset(dir->untracked->root,0, len);2217}22182219/* Validate $GIT_DIR/info/exclude and core.excludesfile */2220 root = dir->untracked->root;2221if(!oideq(&dir->ss_info_exclude.oid,2222&dir->untracked->ss_info_exclude.oid)) {2223invalidate_gitignore(dir->untracked, root);2224 dir->untracked->ss_info_exclude = dir->ss_info_exclude;2225}2226if(!oideq(&dir->ss_excludes_file.oid,2227&dir->untracked->ss_excludes_file.oid)) {2228invalidate_gitignore(dir->untracked, root);2229 dir->untracked->ss_excludes_file = dir->ss_excludes_file;2230}22312232/* Make sure this directory is not dropped out at saving phase */2233 root->recurse =1;2234return root;2235}22362237intread_directory(struct dir_struct *dir,struct index_state *istate,2238const char*path,int len,const struct pathspec *pathspec)2239{2240struct untracked_cache_dir *untracked;22412242trace_performance_enter();22432244if(has_symlink_leading_path(path, len)) {2245trace_performance_leave("read directory %.*s", len, path);2246return dir->nr;2247}22482249 untracked =validate_untracked_cache(dir, len, pathspec);2250if(!untracked)2251/*2252 * make sure untracked cache code path is disabled,2253 * e.g. prep_exclude()2254 */2255 dir->untracked = NULL;2256if(!len ||treat_leading_path(dir, istate, path, len, pathspec))2257read_directory_recursive(dir, istate, path, len, untracked,0,0, pathspec);2258QSORT(dir->entries, dir->nr, cmp_dir_entry);2259QSORT(dir->ignored, dir->ignored_nr, cmp_dir_entry);22602261/*2262 * If DIR_SHOW_IGNORED_TOO is set, read_directory_recursive() will2263 * also pick up untracked contents of untracked dirs; by default2264 * we discard these, but given DIR_KEEP_UNTRACKED_CONTENTS we do not.2265 */2266if((dir->flags & DIR_SHOW_IGNORED_TOO) &&2267!(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {2268int i, j;22692270/* remove from dir->entries untracked contents of untracked dirs */2271for(i = j =0; j < dir->nr; j++) {2272if(i &&2273check_dir_entry_contains(dir->entries[i -1], dir->entries[j])) {2274FREE_AND_NULL(dir->entries[j]);2275}else{2276 dir->entries[i++] = dir->entries[j];2277}2278}22792280 dir->nr = i;2281}22822283trace_performance_leave("read directory %.*s", len, path);2284if(dir->untracked) {2285static int force_untracked_cache = -1;2286static struct trace_key trace_untracked_stats =TRACE_KEY_INIT(UNTRACKED_STATS);22872288if(force_untracked_cache <0)2289 force_untracked_cache =2290git_env_bool("GIT_FORCE_UNTRACKED_CACHE",0);2291trace_printf_key(&trace_untracked_stats,2292"node creation:%u\n"2293"gitignore invalidation:%u\n"2294"directory invalidation:%u\n"2295"opendir:%u\n",2296 dir->untracked->dir_created,2297 dir->untracked->gitignore_invalidated,2298 dir->untracked->dir_invalidated,2299 dir->untracked->dir_opened);2300if(force_untracked_cache &&2301 dir->untracked == istate->untracked &&2302(dir->untracked->dir_opened ||2303 dir->untracked->gitignore_invalidated ||2304 dir->untracked->dir_invalidated))2305 istate->cache_changed |= UNTRACKED_CHANGED;2306if(dir->untracked != istate->untracked) {2307FREE_AND_NULL(dir->untracked);2308}2309}2310return dir->nr;2311}23122313intfile_exists(const char*f)2314{2315struct stat sb;2316returnlstat(f, &sb) ==0;2317}23182319intrepo_file_exists(struct repository *repo,const char*path)2320{2321if(repo != the_repository)2322BUG("do not know how to check file existence in arbitrary repo");23232324returnfile_exists(path);2325}23262327static intcmp_icase(char a,char b)2328{2329if(a == b)2330return0;2331if(ignore_case)2332returntoupper(a) -toupper(b);2333return a - b;2334}23352336/*2337 * Given two normalized paths (a trailing slash is ok), if subdir is2338 * outside dir, return -1. Otherwise return the offset in subdir that2339 * can be used as relative path to dir.2340 */2341intdir_inside_of(const char*subdir,const char*dir)2342{2343int offset =0;23442345assert(dir && subdir && *dir && *subdir);23462347while(*dir && *subdir && !cmp_icase(*dir, *subdir)) {2348 dir++;2349 subdir++;2350 offset++;2351}23522353/* hel[p]/me vs hel[l]/yeah */2354if(*dir && *subdir)2355return-1;23562357if(!*subdir)2358return!*dir ? offset : -1;/* same dir */23592360/* foo/[b]ar vs foo/[] */2361if(is_dir_sep(dir[-1]))2362returnis_dir_sep(subdir[-1]) ? offset : -1;23632364/* foo[/]bar vs foo[] */2365returnis_dir_sep(*subdir) ? offset +1: -1;2366}23672368intis_inside_dir(const char*dir)2369{2370char*cwd;2371int rc;23722373if(!dir)2374return0;23752376 cwd =xgetcwd();2377 rc = (dir_inside_of(cwd, dir) >=0);2378free(cwd);2379return rc;2380}23812382intis_empty_dir(const char*path)2383{2384DIR*dir =opendir(path);2385struct dirent *e;2386int ret =1;23872388if(!dir)2389return0;23902391while((e =readdir(dir)) != NULL)2392if(!is_dot_or_dotdot(e->d_name)) {2393 ret =0;2394break;2395}23962397closedir(dir);2398return ret;2399}24002401static intremove_dir_recurse(struct strbuf *path,int flag,int*kept_up)2402{2403DIR*dir;2404struct dirent *e;2405int ret =0, original_len = path->len, len, kept_down =0;2406int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);2407int keep_toplevel = (flag & REMOVE_DIR_KEEP_TOPLEVEL);2408struct object_id submodule_head;24092410if((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&2411!resolve_gitlink_ref(path->buf,"HEAD", &submodule_head)) {2412/* Do not descend and nuke a nested git work tree. */2413if(kept_up)2414*kept_up =1;2415return0;2416}24172418 flag &= ~REMOVE_DIR_KEEP_TOPLEVEL;2419 dir =opendir(path->buf);2420if(!dir) {2421if(errno == ENOENT)2422return keep_toplevel ? -1:0;2423else if(errno == EACCES && !keep_toplevel)2424/*2425 * An empty dir could be removable even if it2426 * is unreadable:2427 */2428returnrmdir(path->buf);2429else2430return-1;2431}2432strbuf_complete(path,'/');24332434 len = path->len;2435while((e =readdir(dir)) != NULL) {2436struct stat st;2437if(is_dot_or_dotdot(e->d_name))2438continue;24392440strbuf_setlen(path, len);2441strbuf_addstr(path, e->d_name);2442if(lstat(path->buf, &st)) {2443if(errno == ENOENT)2444/*2445 * file disappeared, which is what we2446 * wanted anyway2447 */2448continue;2449/* fall thru */2450}else if(S_ISDIR(st.st_mode)) {2451if(!remove_dir_recurse(path, flag, &kept_down))2452continue;/* happy */2453}else if(!only_empty &&2454(!unlink(path->buf) || errno == ENOENT)) {2455continue;/* happy, too */2456}24572458/* path too long, stat fails, or non-directory still exists */2459 ret = -1;2460break;2461}2462closedir(dir);24632464strbuf_setlen(path, original_len);2465if(!ret && !keep_toplevel && !kept_down)2466 ret = (!rmdir(path->buf) || errno == ENOENT) ?0: -1;2467else if(kept_up)2468/*2469 * report the uplevel that it is not an error that we2470 * did not rmdir() our directory.2471 */2472*kept_up = !ret;2473return ret;2474}24752476intremove_dir_recursively(struct strbuf *path,int flag)2477{2478returnremove_dir_recurse(path, flag, NULL);2479}24802481staticGIT_PATH_FUNC(git_path_info_exclude,"info/exclude")24822483voidsetup_standard_excludes(struct dir_struct *dir)2484{2485 dir->exclude_per_dir =".gitignore";24862487/* core.excludesfile defaulting to $XDG_CONFIG_HOME/git/ignore */2488if(!excludes_file)2489 excludes_file =xdg_config_home("ignore");2490if(excludes_file && !access_or_warn(excludes_file, R_OK,0))2491add_excludes_from_file_1(dir, excludes_file,2492 dir->untracked ? &dir->ss_excludes_file : NULL);24932494/* per repository user preference */2495if(startup_info->have_repository) {2496const char*path =git_path_info_exclude();2497if(!access_or_warn(path, R_OK,0))2498add_excludes_from_file_1(dir, path,2499 dir->untracked ? &dir->ss_info_exclude : NULL);2500}2501}25022503intremove_path(const char*name)2504{2505char*slash;25062507if(unlink(name) && !is_missing_file_error(errno))2508return-1;25092510 slash =strrchr(name,'/');2511if(slash) {2512char*dirs =xstrdup(name);2513 slash = dirs + (slash - name);2514do{2515*slash ='\0';2516}while(rmdir(dirs) ==0&& (slash =strrchr(dirs,'/')));2517free(dirs);2518}2519return0;2520}25212522/*2523 * Frees memory within dir which was allocated for exclude lists and2524 * the exclude_stack. Does not free dir itself.2525 */2526voidclear_directory(struct dir_struct *dir)2527{2528int i, j;2529struct exclude_list_group *group;2530struct exclude_list *el;2531struct exclude_stack *stk;25322533for(i = EXC_CMDL; i <= EXC_FILE; i++) {2534 group = &dir->exclude_list_group[i];2535for(j =0; j < group->nr; j++) {2536 el = &group->el[j];2537if(i == EXC_DIRS)2538free((char*)el->src);2539clear_exclude_list(el);2540}2541free(group->el);2542}25432544 stk = dir->exclude_stack;2545while(stk) {2546struct exclude_stack *prev = stk->prev;2547free(stk);2548 stk = prev;2549}2550strbuf_release(&dir->basebuf);2551}25522553struct ondisk_untracked_cache {2554struct stat_data info_exclude_stat;2555struct stat_data excludes_file_stat;2556uint32_t dir_flags;2557};25582559#define ouc_offset(x) offsetof(struct ondisk_untracked_cache, x)25602561struct write_data {2562int index;/* number of written untracked_cache_dir */2563struct ewah_bitmap *check_only;/* from untracked_cache_dir */2564struct ewah_bitmap *valid;/* from untracked_cache_dir */2565struct ewah_bitmap *sha1_valid;/* set if exclude_sha1 is not null */2566struct strbuf out;2567struct strbuf sb_stat;2568struct strbuf sb_sha1;2569};25702571static voidstat_data_to_disk(struct stat_data *to,const struct stat_data *from)2572{2573 to->sd_ctime.sec =htonl(from->sd_ctime.sec);2574 to->sd_ctime.nsec =htonl(from->sd_ctime.nsec);2575 to->sd_mtime.sec =htonl(from->sd_mtime.sec);2576 to->sd_mtime.nsec =htonl(from->sd_mtime.nsec);2577 to->sd_dev =htonl(from->sd_dev);2578 to->sd_ino =htonl(from->sd_ino);2579 to->sd_uid =htonl(from->sd_uid);2580 to->sd_gid =htonl(from->sd_gid);2581 to->sd_size =htonl(from->sd_size);2582}25832584static voidwrite_one_dir(struct untracked_cache_dir *untracked,2585struct write_data *wd)2586{2587struct stat_data stat_data;2588struct strbuf *out = &wd->out;2589unsigned char intbuf[16];2590unsigned int intlen, value;2591int i = wd->index++;25922593/*2594 * untracked_nr should be reset whenever valid is clear, but2595 * for safety..2596 */2597if(!untracked->valid) {2598 untracked->untracked_nr =0;2599 untracked->check_only =0;2600}26012602if(untracked->check_only)2603ewah_set(wd->check_only, i);2604if(untracked->valid) {2605ewah_set(wd->valid, i);2606stat_data_to_disk(&stat_data, &untracked->stat_data);2607strbuf_add(&wd->sb_stat, &stat_data,sizeof(stat_data));2608}2609if(!is_null_oid(&untracked->exclude_oid)) {2610ewah_set(wd->sha1_valid, i);2611strbuf_add(&wd->sb_sha1, untracked->exclude_oid.hash,2612 the_hash_algo->rawsz);2613}26142615 intlen =encode_varint(untracked->untracked_nr, intbuf);2616strbuf_add(out, intbuf, intlen);26172618/* skip non-recurse directories */2619for(i =0, value =0; i < untracked->dirs_nr; i++)2620if(untracked->dirs[i]->recurse)2621 value++;2622 intlen =encode_varint(value, intbuf);2623strbuf_add(out, intbuf, intlen);26242625strbuf_add(out, untracked->name,strlen(untracked->name) +1);26262627for(i =0; i < untracked->untracked_nr; i++)2628strbuf_add(out, untracked->untracked[i],2629strlen(untracked->untracked[i]) +1);26302631for(i =0; i < untracked->dirs_nr; i++)2632if(untracked->dirs[i]->recurse)2633write_one_dir(untracked->dirs[i], wd);2634}26352636voidwrite_untracked_extension(struct strbuf *out,struct untracked_cache *untracked)2637{2638struct ondisk_untracked_cache *ouc;2639struct write_data wd;2640unsigned char varbuf[16];2641int varint_len;2642const unsigned hashsz = the_hash_algo->rawsz;26432644 ouc =xcalloc(1,sizeof(*ouc));2645stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat);2646stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat);2647 ouc->dir_flags =htonl(untracked->dir_flags);26482649 varint_len =encode_varint(untracked->ident.len, varbuf);2650strbuf_add(out, varbuf, varint_len);2651strbuf_addbuf(out, &untracked->ident);26522653strbuf_add(out, ouc,sizeof(*ouc));2654strbuf_add(out, untracked->ss_info_exclude.oid.hash, hashsz);2655strbuf_add(out, untracked->ss_excludes_file.oid.hash, hashsz);2656strbuf_add(out, untracked->exclude_per_dir,strlen(untracked->exclude_per_dir) +1);2657FREE_AND_NULL(ouc);26582659if(!untracked->root) {2660 varint_len =encode_varint(0, varbuf);2661strbuf_add(out, varbuf, varint_len);2662return;2663}26642665 wd.index =0;2666 wd.check_only =ewah_new();2667 wd.valid =ewah_new();2668 wd.sha1_valid =ewah_new();2669strbuf_init(&wd.out,1024);2670strbuf_init(&wd.sb_stat,1024);2671strbuf_init(&wd.sb_sha1,1024);2672write_one_dir(untracked->root, &wd);26732674 varint_len =encode_varint(wd.index, varbuf);2675strbuf_add(out, varbuf, varint_len);2676strbuf_addbuf(out, &wd.out);2677ewah_serialize_strbuf(wd.valid, out);2678ewah_serialize_strbuf(wd.check_only, out);2679ewah_serialize_strbuf(wd.sha1_valid, out);2680strbuf_addbuf(out, &wd.sb_stat);2681strbuf_addbuf(out, &wd.sb_sha1);2682strbuf_addch(out,'\0');/* safe guard for string lists */26832684ewah_free(wd.valid);2685ewah_free(wd.check_only);2686ewah_free(wd.sha1_valid);2687strbuf_release(&wd.out);2688strbuf_release(&wd.sb_stat);2689strbuf_release(&wd.sb_sha1);2690}26912692static voidfree_untracked(struct untracked_cache_dir *ucd)2693{2694int i;2695if(!ucd)2696return;2697for(i =0; i < ucd->dirs_nr; i++)2698free_untracked(ucd->dirs[i]);2699for(i =0; i < ucd->untracked_nr; i++)2700free(ucd->untracked[i]);2701free(ucd->untracked);2702free(ucd->dirs);2703free(ucd);2704}27052706voidfree_untracked_cache(struct untracked_cache *uc)2707{2708if(uc)2709free_untracked(uc->root);2710free(uc);2711}27122713struct read_data {2714int index;2715struct untracked_cache_dir **ucd;2716struct ewah_bitmap *check_only;2717struct ewah_bitmap *valid;2718struct ewah_bitmap *sha1_valid;2719const unsigned char*data;2720const unsigned char*end;2721};27222723static voidstat_data_from_disk(struct stat_data *to,const unsigned char*data)2724{2725memcpy(to, data,sizeof(*to));2726 to->sd_ctime.sec =ntohl(to->sd_ctime.sec);2727 to->sd_ctime.nsec =ntohl(to->sd_ctime.nsec);2728 to->sd_mtime.sec =ntohl(to->sd_mtime.sec);2729 to->sd_mtime.nsec =ntohl(to->sd_mtime.nsec);2730 to->sd_dev =ntohl(to->sd_dev);2731 to->sd_ino =ntohl(to->sd_ino);2732 to->sd_uid =ntohl(to->sd_uid);2733 to->sd_gid =ntohl(to->sd_gid);2734 to->sd_size =ntohl(to->sd_size);2735}27362737static intread_one_dir(struct untracked_cache_dir **untracked_,2738struct read_data *rd)2739{2740struct untracked_cache_dir ud, *untracked;2741const unsigned char*data = rd->data, *end = rd->end;2742const unsigned char*eos;2743unsigned int value;2744int i;27452746memset(&ud,0,sizeof(ud));27472748 value =decode_varint(&data);2749if(data > end)2750return-1;2751 ud.recurse =1;2752 ud.untracked_alloc = value;2753 ud.untracked_nr = value;2754if(ud.untracked_nr)2755ALLOC_ARRAY(ud.untracked, ud.untracked_nr);27562757 ud.dirs_alloc = ud.dirs_nr =decode_varint(&data);2758if(data > end)2759return-1;2760ALLOC_ARRAY(ud.dirs, ud.dirs_nr);27612762 eos =memchr(data,'\0', end - data);2763if(!eos || eos == end)2764return-1;27652766*untracked_ = untracked =xmalloc(st_add3(sizeof(*untracked), eos - data,1));2767memcpy(untracked, &ud,sizeof(ud));2768memcpy(untracked->name, data, eos - data +1);2769 data = eos +1;27702771for(i =0; i < untracked->untracked_nr; i++) {2772 eos =memchr(data,'\0', end - data);2773if(!eos || eos == end)2774return-1;2775 untracked->untracked[i] =xmemdupz(data, eos - data);2776 data = eos +1;2777}27782779 rd->ucd[rd->index++] = untracked;2780 rd->data = data;27812782for(i =0; i < untracked->dirs_nr; i++) {2783if(read_one_dir(untracked->dirs + i, rd) <0)2784return-1;2785}2786return0;2787}27882789static voidset_check_only(size_t pos,void*cb)2790{2791struct read_data *rd = cb;2792struct untracked_cache_dir *ud = rd->ucd[pos];2793 ud->check_only =1;2794}27952796static voidread_stat(size_t pos,void*cb)2797{2798struct read_data *rd = cb;2799struct untracked_cache_dir *ud = rd->ucd[pos];2800if(rd->data +sizeof(struct stat_data) > rd->end) {2801 rd->data = rd->end +1;2802return;2803}2804stat_data_from_disk(&ud->stat_data, rd->data);2805 rd->data +=sizeof(struct stat_data);2806 ud->valid =1;2807}28082809static voidread_oid(size_t pos,void*cb)2810{2811struct read_data *rd = cb;2812struct untracked_cache_dir *ud = rd->ucd[pos];2813if(rd->data + the_hash_algo->rawsz > rd->end) {2814 rd->data = rd->end +1;2815return;2816}2817hashcpy(ud->exclude_oid.hash, rd->data);2818 rd->data += the_hash_algo->rawsz;2819}28202821static voidload_oid_stat(struct oid_stat *oid_stat,const unsigned char*data,2822const unsigned char*sha1)2823{2824stat_data_from_disk(&oid_stat->stat, data);2825hashcpy(oid_stat->oid.hash, sha1);2826 oid_stat->valid =1;2827}28282829struct untracked_cache *read_untracked_extension(const void*data,unsigned long sz)2830{2831struct untracked_cache *uc;2832struct read_data rd;2833const unsigned char*next = data, *end = (const unsigned char*)data + sz;2834const char*ident;2835int ident_len;2836 ssize_t len;2837const char*exclude_per_dir;2838const unsigned hashsz = the_hash_algo->rawsz;2839const unsigned offset =sizeof(struct ondisk_untracked_cache);2840const unsigned exclude_per_dir_offset = offset +2* hashsz;28412842if(sz <=1|| end[-1] !='\0')2843return NULL;2844 end--;28452846 ident_len =decode_varint(&next);2847if(next + ident_len > end)2848return NULL;2849 ident = (const char*)next;2850 next += ident_len;28512852if(next + exclude_per_dir_offset +1> end)2853return NULL;28542855 uc =xcalloc(1,sizeof(*uc));2856strbuf_init(&uc->ident, ident_len);2857strbuf_add(&uc->ident, ident, ident_len);2858load_oid_stat(&uc->ss_info_exclude,2859 next +ouc_offset(info_exclude_stat),2860 next + offset);2861load_oid_stat(&uc->ss_excludes_file,2862 next +ouc_offset(excludes_file_stat),2863 next + offset + hashsz);2864 uc->dir_flags =get_be32(next +ouc_offset(dir_flags));2865 exclude_per_dir = (const char*)next + exclude_per_dir_offset;2866 uc->exclude_per_dir =xstrdup(exclude_per_dir);2867/* NUL after exclude_per_dir is covered by sizeof(*ouc) */2868 next += exclude_per_dir_offset +strlen(exclude_per_dir) +1;2869if(next >= end)2870goto done2;28712872 len =decode_varint(&next);2873if(next > end || len ==0)2874goto done2;28752876 rd.valid =ewah_new();2877 rd.check_only =ewah_new();2878 rd.sha1_valid =ewah_new();2879 rd.data = next;2880 rd.end = end;2881 rd.index =0;2882ALLOC_ARRAY(rd.ucd, len);28832884if(read_one_dir(&uc->root, &rd) || rd.index != len)2885goto done;28862887 next = rd.data;2888 len =ewah_read_mmap(rd.valid, next, end - next);2889if(len <0)2890goto done;28912892 next += len;2893 len =ewah_read_mmap(rd.check_only, next, end - next);2894if(len <0)2895goto done;28962897 next += len;2898 len =ewah_read_mmap(rd.sha1_valid, next, end - next);2899if(len <0)2900goto done;29012902ewah_each_bit(rd.check_only, set_check_only, &rd);2903 rd.data = next + len;2904ewah_each_bit(rd.valid, read_stat, &rd);2905ewah_each_bit(rd.sha1_valid, read_oid, &rd);2906 next = rd.data;29072908done:2909free(rd.ucd);2910ewah_free(rd.valid);2911ewah_free(rd.check_only);2912ewah_free(rd.sha1_valid);2913done2:2914if(next != end) {2915free_untracked_cache(uc);2916 uc = NULL;2917}2918return uc;2919}29202921static voidinvalidate_one_directory(struct untracked_cache *uc,2922struct untracked_cache_dir *ucd)2923{2924 uc->dir_invalidated++;2925 ucd->valid =0;2926 ucd->untracked_nr =0;2927}29282929/*2930 * Normally when an entry is added or removed from a directory,2931 * invalidating that directory is enough. No need to touch its2932 * ancestors. When a directory is shown as "foo/bar/" in git-status2933 * however, deleting or adding an entry may have cascading effect.2934 *2935 * Say the "foo/bar/file" has become untracked, we need to tell the2936 * untracked_cache_dir of "foo" that "bar/" is not an untracked2937 * directory any more (because "bar" is managed by foo as an untracked2938 * "file").2939 *2940 * Similarly, if "foo/bar/file" moves from untracked to tracked and it2941 * was the last untracked entry in the entire "foo", we should show2942 * "foo/" instead. Which means we have to invalidate past "bar" up to2943 * "foo".2944 *2945 * This function traverses all directories from root to leaf. If there2946 * is a chance of one of the above cases happening, we invalidate back2947 * to root. Otherwise we just invalidate the leaf. There may be a more2948 * sophisticated way than checking for SHOW_OTHER_DIRECTORIES to2949 * detect these cases and avoid unnecessary invalidation, for example,2950 * checking for the untracked entry named "bar/" in "foo", but for now2951 * stick to something safe and simple.2952 */2953static intinvalidate_one_component(struct untracked_cache *uc,2954struct untracked_cache_dir *dir,2955const char*path,int len)2956{2957const char*rest =strchr(path,'/');29582959if(rest) {2960int component_len = rest - path;2961struct untracked_cache_dir *d =2962lookup_untracked(uc, dir, path, component_len);2963int ret =2964invalidate_one_component(uc, d, rest +1,2965 len - (component_len +1));2966if(ret)2967invalidate_one_directory(uc, dir);2968return ret;2969}29702971invalidate_one_directory(uc, dir);2972return uc->dir_flags & DIR_SHOW_OTHER_DIRECTORIES;2973}29742975voiduntracked_cache_invalidate_path(struct index_state *istate,2976const char*path,int safe_path)2977{2978if(!istate->untracked || !istate->untracked->root)2979return;2980if(!safe_path && !verify_path(path,0))2981return;2982invalidate_one_component(istate->untracked, istate->untracked->root,2983 path,strlen(path));2984}29852986voiduntracked_cache_remove_from_index(struct index_state *istate,2987const char*path)2988{2989untracked_cache_invalidate_path(istate, path,1);2990}29912992voiduntracked_cache_add_to_index(struct index_state *istate,2993const char*path)2994{2995untracked_cache_invalidate_path(istate, path,1);2996}29972998static voidconnect_wt_gitdir_in_nested(const char*sub_worktree,2999const char*sub_gitdir)3000{3001int i;3002struct repository subrepo;3003struct strbuf sub_wt = STRBUF_INIT;3004struct strbuf sub_gd = STRBUF_INIT;30053006const struct submodule *sub;30073008/* If the submodule has no working tree, we can ignore it. */3009if(repo_init(&subrepo, sub_gitdir, sub_worktree))3010return;30113012if(repo_read_index(&subrepo) <0)3013die(_("index file corrupt in repo%s"), subrepo.gitdir);30143015for(i =0; i < subrepo.index->cache_nr; i++) {3016const struct cache_entry *ce = subrepo.index->cache[i];30173018if(!S_ISGITLINK(ce->ce_mode))3019continue;30203021while(i +1< subrepo.index->cache_nr &&3022!strcmp(ce->name, subrepo.index->cache[i +1]->name))3023/*3024 * Skip entries with the same name in different stages3025 * to make sure an entry is returned only once.3026 */3027 i++;30283029 sub =submodule_from_path(&subrepo, &null_oid, ce->name);3030if(!sub || !is_submodule_active(&subrepo, ce->name))3031/* .gitmodules broken or inactive sub */3032continue;30333034strbuf_reset(&sub_wt);3035strbuf_reset(&sub_gd);3036strbuf_addf(&sub_wt,"%s/%s", sub_worktree, sub->path);3037strbuf_addf(&sub_gd,"%s/modules/%s", sub_gitdir, sub->name);30383039connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf,1);3040}3041strbuf_release(&sub_wt);3042strbuf_release(&sub_gd);3043repo_clear(&subrepo);3044}30453046voidconnect_work_tree_and_git_dir(const char*work_tree_,3047const char*git_dir_,3048int recurse_into_nested)3049{3050struct strbuf gitfile_sb = STRBUF_INIT;3051struct strbuf cfg_sb = STRBUF_INIT;3052struct strbuf rel_path = STRBUF_INIT;3053char*git_dir, *work_tree;30543055/* Prepare .git file */3056strbuf_addf(&gitfile_sb,"%s/.git", work_tree_);3057if(safe_create_leading_directories_const(gitfile_sb.buf))3058die(_("could not create directories for%s"), gitfile_sb.buf);30593060/* Prepare config file */3061strbuf_addf(&cfg_sb,"%s/config", git_dir_);3062if(safe_create_leading_directories_const(cfg_sb.buf))3063die(_("could not create directories for%s"), cfg_sb.buf);30643065 git_dir =real_pathdup(git_dir_,1);3066 work_tree =real_pathdup(work_tree_,1);30673068/* Write .git file */3069write_file(gitfile_sb.buf,"gitdir:%s",3070relative_path(git_dir, work_tree, &rel_path));3071/* Update core.worktree setting */3072git_config_set_in_file(cfg_sb.buf,"core.worktree",3073relative_path(work_tree, git_dir, &rel_path));30743075strbuf_release(&gitfile_sb);3076strbuf_release(&cfg_sb);3077strbuf_release(&rel_path);30783079if(recurse_into_nested)3080connect_wt_gitdir_in_nested(work_tree, git_dir);30813082free(work_tree);3083free(git_dir);3084}30853086/*3087 * Migrate the git directory of the given path from old_git_dir to new_git_dir.3088 */3089voidrelocate_gitdir(const char*path,const char*old_git_dir,const char*new_git_dir)3090{3091if(rename(old_git_dir, new_git_dir) <0)3092die_errno(_("could not migrate git directory from '%s' to '%s'"),3093 old_git_dir, new_git_dir);30943095connect_work_tree_and_git_dir(path, new_git_dir,0);3096}