49
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
50
struct index_state *istate, const char *path, int len,
51
struct untracked_cache_dir *untracked,
52
- int check_only, const struct pathspec *pathspec);
52
+ int check_only, int stop_at_first_file, const struct pathspec *pathspec);
53
static int get_dtype(struct dirent *de, struct index_state *istate,
54
const char *path, int len);
55
1404
1405
untracked = lookup_untracked(dir->untracked, untracked,
1406
dirname + baselen, len - baselen);
1407
+
1408
+ /*
1409
+ * If this is an excluded directory, then we only need to check if
1410
+ * the directory contains any files.
1411
+ */
1412
return read_directory_recursive(dir, istate, dirname, len,
1408
- untracked, 1, pathspec);
1413
+ untracked, 1, exclude, pathspec);
1414
}
1415
1416
/*
1638
* with check_only set.
1639
*/
1640
return read_directory_recursive(dir, istate, path->buf, path->len,
1636
- cdir->ucd, 1, pathspec);
1641
+ cdir->ucd, 1, 0, pathspec);
1642
/*
1643
* We get path_recurse in the first run when
1644
* directory_exists_in_index() returns index_nonexistent. We
1798
* Also, we ignore the name ".git" (even if it is not a directory).
1799
* That likely will not change.
1800
*
1801
+ * If 'stop_at_first_file' is specified, 'path_excluded' is returned
1802
+ * to signal that a file was found. This is the least significant value that
1803
+ * indicates that a file was encountered that does not depend on the order of
1804
+ * whether an untracked or exluded path was encountered first.
1805
+ *
1806
* Returns the most significant path_treatment value encountered in the scan.
1807
+ * If 'stop_at_first_file' is specified, `path_excluded` is the most
1808
+ * significant path_treatment value that will be returned.
1809
*/
1810
+
1811
static enum path_treatment read_directory_recursive(struct dir_struct *dir,
1812
struct index_state *istate, const char *base, int baselen,
1813
struct untracked_cache_dir *untracked, int check_only,
1801
- const struct pathspec *pathspec)
1814
+ int stop_at_first_file, const struct pathspec *pathspec)
1815
{
1816
struct cached_dir cdir;
1817
enum path_treatment state, subdir_state, dir_state = path_none;
1845
subdir_state =
1846
read_directory_recursive(dir, istate, path.buf,
1847
path.len, ud,
1835
- check_only, pathspec);
1848
+ check_only, stop_at_first_file, pathspec);
1849
if (subdir_state > dir_state)
1850
dir_state = subdir_state;
1851
}
1852
1853
if (check_only) {
1854
+ if (stop_at_first_file) {
1855
+ /*
1856
+ * If stopping at first file, then
1857
+ * signal that a file was found by
1858
+ * returning `path_excluded`. This is
1859
+ * to return a consistent value
1860
+ * regardless of whether an ignored or
1861
+ * excluded file happened to be
1862
+ * encountered 1st.
1863
+ *
1864
+ * In current usage, the
1865
+ * `stop_at_first_file` is passed when
1866
+ * an ancestor directory has matched
1867
+ * an exclude pattern, so any found
1868
+ * files will be excluded.
1869
+ */
1870
+ if (dir_state >= path_excluded) {
1871
+ dir_state = path_excluded;
1872
+ break;
1873
+ }
1874
+ }
1875
+
1876
/* abort early if maximum state has been reached */
1877
if (dir_state == path_untracked) {
1878
if (cdir.fdir)
2143
*/
2144
dir->untracked = NULL;
2145
if (!len || treat_leading_path(dir, istate, path, len, pathspec))
2111
- read_directory_recursive(dir, istate, path, len, untracked, 0, pathspec);
2146
+ read_directory_recursive(dir, istate, path, len, untracked, 0, 0, pathspec);
2147
QSORT(dir->entries, dir->nr, cmp_dir_entry);
2148
QSORT(dir->ignored, dir->ignored_nr, cmp_dir_entry);
2149