dir.c 24.8 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*
 * This handles recursive filename detection with exclude
 * files, index knowledge etc..
 *
 * Copyright (C) Linus Torvalds, 2005-2006
 *		 Junio Hamano, 2005-2006
 */
#include "cache.h"
#include "dir.h"
10
#include "refs.h"
11

12 13 14 15 16
struct path_simplify {
	int len;
	const char *path;
};

17
static int read_directory_recursive(struct dir_struct *dir, const char *path, int len,
18
	int check_only, const struct path_simplify *simplify);
19
static int get_dtype(struct dirent *de, const char *path, int len);
20

21
static int common_prefix(const char **pathspec)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
{
	const char *path, *slash, *next;
	int prefix;

	if (!pathspec)
		return 0;

	path = *pathspec;
	slash = strrchr(path, '/');
	if (!slash)
		return 0;

	prefix = slash - path + 1;
	while ((next = *++pathspec) != NULL) {
		int len = strlen(next);
37
		if (len >= prefix && !memcmp(path, next, prefix))
38
			continue;
39
		len = prefix - 1;
40 41 42 43 44 45 46 47 48 49 50 51 52 53
		for (;;) {
			if (!len)
				return 0;
			if (next[--len] != '/')
				continue;
			if (memcmp(path, next, len+1))
				continue;
			prefix = len + 1;
			break;
		}
	}
	return prefix;
}

54 55
int fill_directory(struct dir_struct *dir, const char **pathspec)
{
56 57
	const char *path;
	int len;
58 59 60 61 62

	/*
	 * Calculate common prefix for the pathspec, and
	 * use that to optimize the directory walk
	 */
63
	len = common_prefix(pathspec);
64 65
	path = "";

66 67
	if (len)
		path = xmemdupz(*pathspec, len);
68 69

	/* Read the directory and prune it */
70 71
	read_directory(dir, path, len, pathspec);
	return len;
72 73
}

74
/*
75
 * Does 'match' match the given name?
76 77 78 79 80 81 82 83 84 85
 * A match is found if
 *
 * (1) the 'match' string is leading directory of 'name', or
 * (2) the 'match' string is a wildcard and matches 'name', or
 * (3) the 'match' string is exactly the same as 'name'.
 *
 * and the return value tells which case it was.
 *
 * It returns 0 when there is no match.
 */
86 87 88 89 90
static int match_one(const char *match, const char *name, int namelen)
{
	int matchlen;

	/* If the match was just the prefix, we matched */
91
	if (!*match)
92
		return MATCHED_RECURSIVELY;
93

94 95 96
	for (;;) {
		unsigned char c1 = *match;
		unsigned char c2 = *name;
97
		if (c1 == '\0' || is_glob_special(c1))
98 99 100 101 102 103 104 105 106
			break;
		if (c1 != c2)
			return 0;
		match++;
		name++;
		namelen--;
	}


107 108 109 110
	/*
	 * If we don't match the matchstring exactly,
	 * we need to match by fnmatch
	 */
111
	matchlen = strlen(match);
112
	if (strncmp(match, name, matchlen))
113
		return !fnmatch(match, name, 0) ? MATCHED_FNMATCH : 0;
114

115
	if (namelen == matchlen)
116 117 118 119
		return MATCHED_EXACTLY;
	if (match[matchlen-1] == '/' || name[matchlen] == '/')
		return MATCHED_RECURSIVELY;
	return 0;
120 121
}

122 123 124 125 126 127 128 129
/*
 * Given a name and a list of pathspecs, see if the name matches
 * any of the pathspecs.  The caller is also interested in seeing
 * all pathspec matches some names it calls this function with
 * (otherwise the user could have mistyped the unmatched pathspec),
 * and a mark is left in seen[] array for pathspec element that
 * actually matched anything.
 */
130 131
int match_pathspec(const char **pathspec, const char *name, int namelen,
		int prefix, char *seen)
132
{
133 134 135 136
	int i, retval = 0;

	if (!pathspec)
		return 1;
137 138 139 140

	name += prefix;
	namelen -= prefix;

141
	for (i = 0; pathspec[i] != NULL; i++) {
142
		int how;
143 144
		const char *match = pathspec[i] + prefix;
		if (seen && seen[i] == MATCHED_EXACTLY)
145
			continue;
146 147 148 149
		how = match_one(match, name, namelen);
		if (how) {
			if (retval < how)
				retval = how;
150 151
			if (seen && seen[i] < how)
				seen[i] = how;
152 153 154 155 156
		}
	}
	return retval;
}

L
Lars Knoll 已提交
157 158
static int no_wildcard(const char *string)
{
159
	return string[strcspn(string, "*?[{\\")] == '\0';
L
Lars Knoll 已提交
160 161
}

162 163 164
void add_exclude(const char *string, const char *base,
		 int baselen, struct exclude_list *which)
{
165 166 167 168
	struct exclude *x;
	size_t len;
	int to_exclude = 1;
	int flags = 0;
169

L
Lars Knoll 已提交
170
	if (*string == '!') {
171
		to_exclude = 0;
L
Lars Knoll 已提交
172 173
		string++;
	}
174 175 176 177
	len = strlen(string);
	if (len && string[len - 1] == '/') {
		char *s;
		x = xmalloc(sizeof(*x) + len);
178
		s = (char *)(x+1);
179 180 181 182 183 184 185 186 187 188
		memcpy(s, string, len - 1);
		s[len - 1] = '\0';
		string = s;
		x->pattern = s;
		flags = EXC_FLAG_MUSTBEDIR;
	} else {
		x = xmalloc(sizeof(*x));
		x->pattern = string;
	}
	x->to_exclude = to_exclude;
L
Lars Knoll 已提交
189
	x->patternlen = strlen(string);
190 191
	x->base = base;
	x->baselen = baselen;
192
	x->flags = flags;
L
Lars Knoll 已提交
193 194 195 196 197 198
	if (!strchr(string, '/'))
		x->flags |= EXC_FLAG_NODIR;
	if (no_wildcard(string))
		x->flags |= EXC_FLAG_NOWILDCARD;
	if (*string == '*' && no_wildcard(string+1))
		x->flags |= EXC_FLAG_ENDSWITH;
J
Junio C Hamano 已提交
199
	ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
200 201 202
	which->excludes[which->nr++] = x;
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
{
	int pos, len;
	unsigned long sz;
	enum object_type type;
	void *data;
	struct index_state *istate = &the_index;

	len = strlen(path);
	pos = index_name_pos(istate, path, len);
	if (pos < 0)
		return NULL;
	if (!ce_skip_worktree(istate->cache[pos]))
		return NULL;
	data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz);
	if (!data || type != OBJ_BLOB) {
		free(data);
		return NULL;
	}
	*size = xsize_t(sz);
	return data;
}

226 227 228 229 230 231
int add_excludes_from_file_to_list(const char *fname,
				   const char *base,
				   int baselen,
				   char **buf_p,
				   struct exclude_list *which,
				   int check_index)
232
{
J
Jonas Fonseca 已提交
233
	struct stat st;
234
	int fd, i;
235
	size_t size;
236 237 238
	char *buf, *entry;

	fd = open(fname, O_RDONLY);
239 240 241 242 243 244
	if (fd < 0 || fstat(fd, &st) < 0) {
		if (0 <= fd)
			close(fd);
		if (!check_index ||
		    (buf = read_skip_worktree_file_from_index(fname, &size)) == NULL)
			return -1;
245 246 247 248 249 250 251 252
		if (size == 0) {
			free(buf);
			return 0;
		}
		if (buf[size-1] != '\n') {
			buf = xrealloc(buf, size+1);
			buf[size++] = '\n';
		}
253
	}
254 255 256 257 258 259
	else {
		size = xsize_t(st.st_size);
		if (size == 0) {
			close(fd);
			return 0;
		}
260
		buf = xmalloc(size+1);
261
		if (read_in_full(fd, buf, size) != size) {
262
			free(buf);
263 264 265
			close(fd);
			return -1;
		}
266
		buf[size++] = '\n';
267
		close(fd);
李鸿 已提交
268
	}
269

270 271
	if (buf_p)
		*buf_p = buf;
272
	entry = buf;
273 274
	for (i = 0; i < size; i++) {
		if (buf[i] == '\n') {
275 276 277 278 279 280 281 282 283 284 285 286
			if (entry != buf + i && entry[0] != '#') {
				buf[i - (i && buf[i-1] == '\r')] = 0;
				add_exclude(entry, base, baselen, which);
			}
			entry = buf + i + 1;
		}
	}
	return 0;
}

void add_excludes_from_file(struct dir_struct *dir, const char *fname)
{
287 288
	if (add_excludes_from_file_to_list(fname, "", 0, NULL,
					   &dir->exclude_list[EXC_FILE], 0) < 0)
289 290 291
		die("cannot use %s as an exclude file", fname);
}

292
static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
293
{
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
	struct exclude_list *el;
	struct exclude_stack *stk = NULL;
	int current;

	if ((!dir->exclude_per_dir) ||
	    (baselen + strlen(dir->exclude_per_dir) >= PATH_MAX))
		return; /* too long a path -- ignore */

	/* Pop the ones that are not the prefix of the path being checked. */
	el = &dir->exclude_list[EXC_DIRS];
	while ((stk = dir->exclude_stack) != NULL) {
		if (stk->baselen <= baselen &&
		    !strncmp(dir->basebuf, base, stk->baselen))
			break;
		dir->exclude_stack = stk->prev;
		while (stk->exclude_ix < el->nr)
			free(el->excludes[--el->nr]);
		free(stk->filebuf);
		free(stk);
313 314
	}

315 316 317 318 319
	/* Read from the parent directories and push them down. */
	current = stk ? stk->baselen : -1;
	while (current < baselen) {
		struct exclude_stack *stk = xcalloc(1, sizeof(*stk));
		const char *cp;
320

321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
		if (current < 0) {
			cp = base;
			current = 0;
		}
		else {
			cp = strchr(base + current + 1, '/');
			if (!cp)
				die("oops in prep_exclude");
			cp++;
		}
		stk->prev = dir->exclude_stack;
		stk->baselen = cp - base;
		stk->exclude_ix = el->nr;
		memcpy(dir->basebuf + current, base + current,
		       stk->baselen - current);
		strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
337 338 339
		add_excludes_from_file_to_list(dir->basebuf,
					       dir->basebuf, stk->baselen,
					       &stk->filebuf, el, 1);
340 341 342 343
		dir->exclude_stack = stk;
		current = stk->baselen;
	}
	dir->basebuf[baselen] = '\0';
344 345
}

346
/* Scan the list and let the last match determine the fate.
347 348
 * Return 1 for exclude, 0 for include and -1 for undecided.
 */
349 350 351
int excluded_from_list(const char *pathname,
		       int pathlen, const char *basename, int *dtype,
		       struct exclude_list *el)
352 353 354 355 356 357 358
{
	int i;

	if (el->nr) {
		for (i = el->nr - 1; 0 <= i; i--) {
			struct exclude *x = el->excludes[i];
			const char *exclude = x->pattern;
L
Lars Knoll 已提交
359
			int to_exclude = x->to_exclude;
360

J
Junio C Hamano 已提交
361
			if (x->flags & EXC_FLAG_MUSTBEDIR) {
362 363 364 365 366 367
				if (!dtype) {
					if (!prefixcmp(pathname, exclude))
						return to_exclude;
					else
						continue;
				}
J
Junio C Hamano 已提交
368
				if (*dtype == DT_UNKNOWN)
369
					*dtype = get_dtype(NULL, pathname, pathlen);
J
Junio C Hamano 已提交
370 371 372
				if (*dtype != DT_DIR)
					continue;
			}
373

L
Lars Knoll 已提交
374
			if (x->flags & EXC_FLAG_NODIR) {
375
				/* match basename */
L
Lars Knoll 已提交
376 377 378 379 380 381 382 383 384 385 386
				if (x->flags & EXC_FLAG_NOWILDCARD) {
					if (!strcmp(exclude, basename))
						return to_exclude;
				} else if (x->flags & EXC_FLAG_ENDSWITH) {
					if (x->patternlen - 1 <= pathlen &&
					    !strcmp(exclude + 1, pathname + pathlen - x->patternlen + 1))
						return to_exclude;
				} else {
					if (fnmatch(exclude, basename, 0) == 0)
						return to_exclude;
				}
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
			}
			else {
				/* match with FNM_PATHNAME:
				 * exclude has base (baselen long) implicitly
				 * in front of it.
				 */
				int baselen = x->baselen;
				if (*exclude == '/')
					exclude++;

				if (pathlen < baselen ||
				    (baselen && pathname[baselen-1] != '/') ||
				    strncmp(pathname, x->base, baselen))
				    continue;

L
Lars Knoll 已提交
402 403 404 405 406 407 408 409
				if (x->flags & EXC_FLAG_NOWILDCARD) {
					if (!strcmp(exclude, pathname + baselen))
						return to_exclude;
				} else {
					if (fnmatch(exclude, pathname+baselen,
						    FNM_PATHNAME) == 0)
					    return to_exclude;
				}
410 411 412 413 414 415
			}
		}
	}
	return -1; /* undecided */
}

J
Junio C Hamano 已提交
416
int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
417 418 419
{
	int pathlen = strlen(pathname);
	int st;
L
Lars Knoll 已提交
420 421
	const char *basename = strrchr(pathname, '/');
	basename = (basename) ? basename+1 : pathname;
422

423
	prep_exclude(dir, pathname, basename-pathname);
424
	for (st = EXC_CMDL; st <= EXC_FILE; st++) {
425 426
		switch (excluded_from_list(pathname, pathlen, basename,
					   dtype_p, &dir->exclude_list[st])) {
427 428 429 430 431 432 433 434 435
		case 0:
			return 0;
		case 1:
			return 1;
		}
	}
	return 0;
}

436 437
static struct dir_entry *dir_entry_new(const char *pathname, int len)
{
438 439 440 441 442 443
	struct dir_entry *ent;

	ent = xmalloc(sizeof(*ent) + len + 1);
	ent->len = len;
	memcpy(ent->name, pathname, len);
	ent->name[len] = 0;
J
Junio C Hamano 已提交
444
	return ent;
445 446
}

447
static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len)
J
Jeff King 已提交
448
{
L
Linus Torvalds 已提交
449
	if (cache_name_exists(pathname, len, ignore_case))
J
Jeff King 已提交
450 451
		return NULL;

452
	ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc);
J
Jeff King 已提交
453 454 455
	return dir->entries[dir->nr++] = dir_entry_new(pathname, len);
}

456
static struct dir_entry *dir_add_ignored(struct dir_struct *dir, const char *pathname, int len)
457
{
458
	if (!cache_name_is_other(pathname, len))
459 460
		return NULL;

461
	ALLOC_GROW(dir->ignored, dir->ignored_nr+1, dir->ignored_alloc);
462 463 464
	return dir->ignored[dir->ignored_nr++] = dir_entry_new(pathname, len);
}

465 466 467 468 469 470 471 472 473 474 475 476 477 478
enum exist_status {
	index_nonexistent = 0,
	index_directory,
	index_gitdir,
};

/*
 * The index sorts alphabetically by entry name, which
 * means that a gitlink sorts as '\0' at the end, while
 * a directory (which is defined not as an entry, but as
 * the files it contains) will sort with the '/' at the
 * end.
 */
static enum exist_status directory_exists_in_index(const char *dirname, int len)
479 480
{
	int pos = cache_name_pos(dirname, len);
481 482 483 484 485 486 487 488 489 490 491 492 493
	if (pos < 0)
		pos = -pos-1;
	while (pos < active_nr) {
		struct cache_entry *ce = active_cache[pos++];
		unsigned char endchar;

		if (strncmp(ce->name, dirname, len))
			break;
		endchar = ce->name[len];
		if (endchar > '/')
			break;
		if (endchar == '/')
			return index_directory;
494
		if (!endchar && S_ISGITLINK(ce->ce_mode))
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
			return index_gitdir;
	}
	return index_nonexistent;
}

/*
 * When we find a directory when traversing the filesystem, we
 * have three distinct cases:
 *
 *  - ignore it
 *  - see it as a directory
 *  - recurse into it
 *
 * and which one we choose depends on a combination of existing
 * git index contents and the flags passed into the directory
 * traversal routine.
 *
 * Case 1: If we *already* have entries in the index under that
 * directory name, we always recurse into the directory to see
 * all the files.
 *
 * Case 2: If we *already* have that directory name as a gitlink,
 * we always continue to see it as a gitlink, regardless of whether
 * there is an actual git directory there or not (it might not
 * be checked out as a subproject!)
 *
 * Case 3: if we didn't have it in the index previously, we
 * have a few sub-cases:
 *
 *  (a) if "show_other_directories" is true, we show it as
 *      just a directory, unless "hide_empty_directories" is
 *      also true and the directory is empty, in which case
 *      we just ignore it entirely.
 *  (b) if it looks like a git directory, and we don't have
M
Martin Waitz 已提交
529
 *      'no_gitlinks' set we treat it as a gitlink, and show it
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
 *      as a directory.
 *  (c) otherwise, we recurse into it.
 */
enum directory_treatment {
	show_directory,
	ignore_directory,
	recurse_into_directory,
};

static enum directory_treatment treat_directory(struct dir_struct *dir,
	const char *dirname, int len,
	const struct path_simplify *simplify)
{
	/* The "len-1" is to strip the final '/' */
	switch (directory_exists_in_index(dirname, len-1)) {
	case index_directory:
		return recurse_into_directory;

	case index_gitdir:
549
		if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
550
			return ignore_directory;
551 552 553
		return show_directory;

	case index_nonexistent:
554
		if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES)
555
			break;
556
		if (!(dir->flags & DIR_NO_GITLINKS)) {
557 558 559 560 561 562 563 564
			unsigned char sha1[20];
			if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0)
				return show_directory;
		}
		return recurse_into_directory;
	}

	/* This is the "show_other_directories" case */
565
	if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES))
566
		return show_directory;
567
	if (!read_directory_recursive(dir, dirname, len, 1, simplify))
568 569
		return ignore_directory;
	return show_directory;
570 571
}

572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
/*
 * This is an inexact early pruning of any recursive directory
 * reading - if the path cannot possibly be in the pathspec,
 * return true, and we'll skip it early.
 */
static int simplify_away(const char *path, int pathlen, const struct path_simplify *simplify)
{
	if (simplify) {
		for (;;) {
			const char *match = simplify->path;
			int len = simplify->len;

			if (!match)
				break;
			if (len > pathlen)
				len = pathlen;
			if (!memcmp(path, match, len))
				return 0;
			simplify++;
		}
		return 1;
	}
	return 0;
}

597 598 599 600 601 602 603 604 605 606 607 608 609
/*
 * This function tells us whether an excluded path matches a
 * list of "interesting" pathspecs. That is, whether a path matched
 * by any of the pathspecs could possibly be ignored by excluding
 * the specified path. This can happen if:
 *
 *   1. the path is mentioned explicitly in the pathspec
 *
 *   2. the path is a directory prefix of some element in the
 *      pathspec
 */
static int exclude_matches_pathspec(const char *path, int len,
		const struct path_simplify *simplify)
610 611 612 613 614 615
{
	if (simplify) {
		for (; simplify->path; simplify++) {
			if (len == simplify->len
			    && !memcmp(path, simplify->path, len))
				return 1;
616 617 618 619
			if (len < simplify->len
			    && simplify->path[len] == '/'
			    && !memcmp(path, simplify->path, len))
				return 1;
620 621 622 623 624
		}
	}
	return 0;
}

625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662
static int get_index_dtype(const char *path, int len)
{
	int pos;
	struct cache_entry *ce;

	ce = cache_name_exists(path, len, 0);
	if (ce) {
		if (!ce_uptodate(ce))
			return DT_UNKNOWN;
		if (S_ISGITLINK(ce->ce_mode))
			return DT_DIR;
		/*
		 * Nobody actually cares about the
		 * difference between DT_LNK and DT_REG
		 */
		return DT_REG;
	}

	/* Try to look it up as a directory */
	pos = cache_name_pos(path, len);
	if (pos >= 0)
		return DT_UNKNOWN;
	pos = -pos-1;
	while (pos < active_nr) {
		ce = active_cache[pos++];
		if (strncmp(ce->name, path, len))
			break;
		if (ce->name[len] > '/')
			break;
		if (ce->name[len] < '/')
			continue;
		if (!ce_uptodate(ce))
			break;	/* continue? */
		return DT_DIR;
	}
	return DT_UNKNOWN;
}

663
static int get_dtype(struct dirent *de, const char *path, int len)
664
{
J
Junio C Hamano 已提交
665
	int dtype = de ? DTYPE(de) : DT_UNKNOWN;
666 667 668 669
	struct stat st;

	if (dtype != DT_UNKNOWN)
		return dtype;
670 671 672 673
	dtype = get_index_dtype(path, len);
	if (dtype != DT_UNKNOWN)
		return dtype;
	if (lstat(path, &st))
674 675 676 677 678 679 680 681 682 683
		return dtype;
	if (S_ISREG(st.st_mode))
		return DT_REG;
	if (S_ISDIR(st.st_mode))
		return DT_DIR;
	if (S_ISLNK(st.st_mode))
		return DT_LNK;
	return dtype;
}

684 685 686 687 688 689
enum path_treatment {
	path_ignored,
	path_handled,
	path_recurse,
};

690 691 692 693
static enum path_treatment treat_one_path(struct dir_struct *dir,
					  char *path, int *len,
					  const struct path_simplify *simplify,
					  int dtype, struct dirent *de)
694
{
695
	int exclude = excluded(dir, path, &dtype);
696
	if (exclude && (dir->flags & DIR_COLLECT_IGNORED)
697
	    && exclude_matches_pathspec(path, *len, simplify))
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
		dir_add_ignored(dir, path, *len);

	/*
	 * Excluded? If we don't explicitly want to show
	 * ignored files, ignore it
	 */
	if (exclude && !(dir->flags & DIR_SHOW_IGNORED))
		return path_ignored;

	if (dtype == DT_UNKNOWN)
		dtype = get_dtype(de, path, *len);

	/*
	 * Do we want to see just the ignored files?
	 * We still need to recurse into directories,
	 * even if we don't ignore them, since the
	 * directory may contain files that we do..
	 */
	if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) {
		if (dtype != DT_DIR)
			return path_ignored;
	}

	switch (dtype) {
	default:
		return path_ignored;
	case DT_DIR:
		memcpy(path + *len, "/", 2);
		(*len)++;
		switch (treat_directory(dir, path, *len, simplify)) {
		case show_directory:
			if (exclude != !!(dir->flags
					  & DIR_SHOW_IGNORED))
				return path_ignored;
			break;
		case recurse_into_directory:
			return path_recurse;
		case ignore_directory:
			return path_ignored;
		}
		break;
	case DT_REG:
	case DT_LNK:
		break;
	}
	return path_handled;
}

746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
static enum path_treatment treat_path(struct dir_struct *dir,
				      struct dirent *de,
				      char *path, int path_max,
				      int baselen,
				      const struct path_simplify *simplify,
				      int *len)
{
	int dtype;

	if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git"))
		return path_ignored;
	*len = strlen(de->d_name);
	/* Ignore overly long pathnames! */
	if (*len + baselen + 8 > path_max)
		return path_ignored;
	memcpy(path + baselen, de->d_name, *len + 1);
	*len += baselen;
	if (simplify_away(path, *len, simplify))
		return path_ignored;

	dtype = DTYPE(de);
	return treat_one_path(dir, path, len, simplify, dtype, de);
}

770 771 772 773 774 775 776 777 778
/*
 * Read a directory tree. We currently ignore anything but
 * directories, regular files and symlinks. That's because git
 * doesn't handle them at all yet. Maybe that will change some
 * day.
 *
 * Also, we ignore the name ".git" (even if it is not a directory).
 * That likely will not change.
 */
779 780 781 782
static int read_directory_recursive(struct dir_struct *dir,
				    const char *base, int baselen,
				    int check_only,
				    const struct path_simplify *simplify)
783
{
784
	DIR *fdir = opendir(*base ? base : ".");
785 786 787 788
	int contents = 0;

	if (fdir) {
		struct dirent *de;
789 790
		char path[PATH_MAX + 1];
		memcpy(path, base, baselen);
791 792

		while ((de = readdir(fdir)) != NULL) {
793 794 795 796 797 798
			int len;
			switch (treat_path(dir, de, path, sizeof(path),
					   baselen, simplify, &len)) {
			case path_recurse:
				contents += read_directory_recursive
					(dir, path, len, 0, simplify);
799
				continue;
800
			case path_ignored:
801
				continue;
802
			case path_handled:
803 804 805
				break;
			}
			contents++;
806 807 808
			if (check_only)
				goto exit_early;
			else
809
				dir_add_name(dir, path, len);
810
		}
811
exit_early:
812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
		closedir(fdir);
	}

	return contents;
}

static int cmp_name(const void *p1, const void *p2)
{
	const struct dir_entry *e1 = *(const struct dir_entry **)p1;
	const struct dir_entry *e2 = *(const struct dir_entry **)p2;

	return cache_name_compare(e1->name, e1->len,
				  e2->name, e2->len);
}

827 828 829 830
/*
 * Return the length of the "simple" part of a path match limiter.
 */
static int simple_length(const char *match)
831
{
832 833 834 835 836
	int len = -1;

	for (;;) {
		unsigned char c = *match++;
		len++;
837
		if (c == '\0' || is_glob_special(c))
838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
			return len;
	}
}

static struct path_simplify *create_simplify(const char **pathspec)
{
	int nr, alloc = 0;
	struct path_simplify *simplify = NULL;

	if (!pathspec)
		return NULL;

	for (nr = 0 ; ; nr++) {
		const char *match;
		if (nr >= alloc) {
			alloc = alloc_nr(alloc);
			simplify = xrealloc(simplify, alloc * sizeof(*simplify));
		}
		match = *pathspec++;
		if (!match)
			break;
		simplify[nr].path = match;
		simplify[nr].len = simple_length(match);
	}
	simplify[nr].path = NULL;
	simplify[nr].len = 0;
	return simplify;
}

static void free_simplify(struct path_simplify *simplify)
{
869
	free(simplify);
870 871
}

872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
static int treat_leading_path(struct dir_struct *dir,
			      const char *path, int len,
			      const struct path_simplify *simplify)
{
	char pathbuf[PATH_MAX];
	int baselen, blen;
	const char *cp;

	while (len && path[len - 1] == '/')
		len--;
	if (!len)
		return 1;
	baselen = 0;
	while (1) {
		cp = path + baselen + !!baselen;
		cp = memchr(cp, '/', path + len - cp);
		if (!cp)
			baselen = len;
		else
			baselen = cp - path;
		memcpy(pathbuf, path, baselen);
		pathbuf[baselen] = '\0';
		if (!is_directory(pathbuf))
			return 0;
		if (simplify_away(pathbuf, baselen, simplify))
			return 0;
		blen = baselen;
		if (treat_one_path(dir, pathbuf, &blen, simplify,
				   DT_DIR, NULL) == path_ignored)
			return 0; /* do not recurse into it */
		if (len <= baselen)
			return 1; /* finished checking */
	}
}

907
int read_directory(struct dir_struct *dir, const char *path, int len, const char **pathspec)
908
{
909
	struct path_simplify *simplify;
910

911
	if (has_symlink_leading_path(path, len))
912 913 914
		return dir->nr;

	simplify = create_simplify(pathspec);
915 916
	if (!len || treat_leading_path(dir, path, len, simplify))
		read_directory_recursive(dir, path, len, 0, simplify);
917
	free_simplify(simplify);
918
	qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
919
	qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
920 921
	return dir->nr;
}
922

J
Junio C Hamano 已提交
923
int file_exists(const char *f)
924
{
J
Junio C Hamano 已提交
925
	struct stat sb;
926
	return lstat(f, &sb) == 0;
927
}
928 929 930 931

/*
 * get_relative_cwd() gets the prefix of the current working directory
 * relative to 'dir'.  If we are not inside 'dir', it returns NULL.
932 933 934 935 936 937 938 939 940 941
 *
 * As a convenience, it also returns NULL if 'dir' is already NULL.  The
 * reason for this behaviour is that it is natural for functions returning
 * directory names to return NULL to say "this directory does not exist"
 * or "this directory is invalid".  These cases are usually handled the
 * same as if the cwd is not inside 'dir' at all, so get_relative_cwd()
 * returns NULL for both of them.
 *
 * Most notably, get_relative_cwd(buffer, size, get_git_work_tree())
 * unifies the handling of "outside work tree" with "no work tree at all".
942 943 944 945 946 947 948 949
 */
char *get_relative_cwd(char *buffer, int size, const char *dir)
{
	char *cwd = buffer;

	if (!dir)
		return NULL;
	if (!getcwd(buffer, size))
950
		die_errno("can't find the current directory");
951 952 953 954 955 956 957 958 959 960

	if (!is_absolute_path(dir))
		dir = make_absolute_path(dir);

	while (*dir && *dir == *cwd) {
		dir++;
		cwd++;
	}
	if (*dir)
		return NULL;
961 962 963 964
	switch (*cwd) {
	case '\0':
		return cwd;
	case '/':
965
		return cwd + 1;
966 967 968
	default:
		return NULL;
	}
969 970 971 972 973 974 975
}

int is_inside_dir(const char *dir)
{
	char buffer[PATH_MAX];
	return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
}
976

977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995
int is_empty_dir(const char *path)
{
	DIR *dir = opendir(path);
	struct dirent *e;
	int ret = 1;

	if (!dir)
		return 0;

	while ((e = readdir(dir)) != NULL)
		if (!is_dot_or_dotdot(e->d_name)) {
			ret = 0;
			break;
		}

	closedir(dir);
	return ret;
}

996
int remove_dir_recursively(struct strbuf *path, int flag)
997
{
998
	DIR *dir;
999 1000
	struct dirent *e;
	int ret = 0, original_len = path->len, len;
1001 1002
	int only_empty = (flag & REMOVE_DIR_EMPTY_ONLY);
	unsigned char submodule_head[20];
1003

1004 1005 1006 1007 1008 1009
	if ((flag & REMOVE_DIR_KEEP_NESTED_GIT) &&
	    !resolve_gitlink_ref(path->buf, "HEAD", submodule_head))
		/* Do not descend and nuke a nested git work tree. */
		return 0;

	dir = opendir(path->buf);
1010 1011 1012 1013 1014 1015 1016 1017
	if (!dir)
		return -1;
	if (path->buf[original_len - 1] != '/')
		strbuf_addch(path, '/');

	len = path->len;
	while ((e = readdir(dir)) != NULL) {
		struct stat st;
1018 1019
		if (is_dot_or_dotdot(e->d_name))
			continue;
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041

		strbuf_setlen(path, len);
		strbuf_addstr(path, e->d_name);
		if (lstat(path->buf, &st))
			; /* fall thru */
		else if (S_ISDIR(st.st_mode)) {
			if (!remove_dir_recursively(path, only_empty))
				continue; /* happy */
		} else if (!only_empty && !unlink(path->buf))
			continue; /* happy, too */

		/* path too long, stat fails, or non-directory still exists */
		ret = -1;
		break;
	}
	closedir(dir);

	strbuf_setlen(path, original_len);
	if (!ret)
		ret = rmdir(path->buf);
	return ret;
}
J
Junio C Hamano 已提交
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053

void setup_standard_excludes(struct dir_struct *dir)
{
	const char *path;

	dir->exclude_per_dir = ".gitignore";
	path = git_path("info/exclude");
	if (!access(path, R_OK))
		add_excludes_from_file(dir, path);
	if (excludes_file && !access(excludes_file, R_OK))
		add_excludes_from_file(dir, excludes_file);
}
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067

int remove_path(const char *name)
{
	char *slash;

	if (unlink(name) && errno != ENOENT)
		return -1;

	slash = strrchr(name, '/');
	if (slash) {
		char *dirs = xstrdup(name);
		slash = dirs + (slash - name);
		do {
			*slash = '\0';
1068
		} while (rmdir(dirs) == 0 && (slash = strrchr(dirs, '/')));
1069 1070 1071 1072 1073
		free(dirs);
	}
	return 0;
}