Commit Diff


commit - b343c297c60d4200da952ab5b2843eec39ed42b1
commit + 8f2ca62d67489d1f75ac4eb42590a9b720c66ccc
blob - fba8eb73431c038f4a91c744d8f6f0c55855c7e0
blob + 91a35e46fce2547ae0c44ba7edf82da9edd9e097
--- lib/fileindex.c
+++ lib/fileindex.c
@@ -986,7 +986,31 @@ free_dirlist(struct got_pathlist_head *dirlist)
 		free(dle->data);
 	got_pathlist_free(dirlist);
 }
+
+static int
+have_tracked_file_in_dir(struct got_fileindex *fileindex, const char *path)
+{
+	struct got_fileindex_entry *ie;
+	size_t path_len = strlen(path);
+	int cmp;
 
+	ie = RB_ROOT(&fileindex->entries);
+	while (ie) {
+		if (got_path_is_child(ie->path, path, path_len))
+			return 1;
+		cmp = got_path_cmp(path, ie->path, path_len,
+		    got_fileindex_entry_path_len(ie));
+		if (cmp < 0)
+			ie = RB_LEFT(ie, entry);
+		else if (cmp > 0)
+			ie = RB_RIGHT(ie, entry);
+		else
+			break;
+	}
+
+	return 0;
+}
+
 static const struct got_error *
 walk_dir(struct got_pathlist_entry **next, struct got_fileindex *fileindex,
     struct got_fileindex_entry **ie, struct got_pathlist_entry *dle, int fd,
@@ -1013,6 +1037,11 @@ walk_dir(struct got_pathlist_entry **next, struct got_
 	} else
 		type = de->d_type;
 
+	/* Must traverse ignored directories if they contain tracked files. */
+	if (type == DT_DIR && ignore &&
+	    have_tracked_file_in_dir(fileindex, path))
+		ignore = 0;
+
 	if (type == DT_DIR && !ignore) {
 		char *subpath;
 		char *subdirpath;
blob - 8b67476fd9377314c10033f7fe555651af4cda1a
blob + 9e581724fe4e03c1b4d098200691d364a658da87
--- regress/cmdline/status.sh
+++ regress/cmdline/status.sh
@@ -531,6 +531,7 @@ test_status_cvsignore() {
 	mkdir -p $testroot/wt/epsilon/new/
 	echo "unversioned file" > $testroot/wt/epsilon/new/foo
 	echo "**/foo" > $testroot/wt/.cvsignore
+	echo "**/gamma" >> $testroot/wt/.cvsignore
 	echo "bar" > $testroot/wt/epsilon/.cvsignore
 	echo "moo" >> $testroot/wt/epsilon/.cvsignore