dir: include DIR_KEEP_UNTRACKED_CONTENTS handling in treat_directory()
Handling DIR_KEEP_UNTRACKED_CONTENTS within treat_directory() instead of as a post-processing step in read_directory(): * allows us to directly access and remove the relevant entries instead of needing to calculate which ones need to be removed * keeps the logic for directory handling in one location (and puts it closer the the logic for stripping out extra ignored entries, which seems logical). Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Elijah Newren committed
Apr 1, 2020 at 04:17 UTC
1684644489fbd76d01fe3bb53c65df6856fd00c5
1 file changed
+19
-24
dir.c
+19
-24
@@ -1665,7 +1665,8 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1665
* you CAN'T DO BOTH.
1666
*/
1667
enum path_treatment state;
1668
- int nested_repo = 0, old_ignored_nr, check_only, stop_early;
1668
+ int nested_repo = 0, check_only, stop_early;
1669
+ int old_ignored_nr, old_untracked_nr;
1670
/* The "len-1" is to strip the final '/' */
1671
enum exist_status status = directory_exists_in_index(istate, dirname, len-1);
1672
@@ -1785,9 +1786,13 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1786
* --porcelain), without listing the individual ignored files
1787
* underneath. To do so, we'll save the current ignored_nr, and
1788
* pop all the ones added after it if it turns out the entire
1788
- * directory is ignored.
1789
+ * directory is ignored. Also, when DIR_SHOW_IGNORED_TOO and
1790
+ * !DIR_KEEP_UNTRACKED_CONTENTS then we don't want to show
1791
+ * untracked paths so will need to pop all those off the last
1792
+ * after we traverse.
1793
*/
1794
old_ignored_nr = dir->ignored_nr;
1795
+ old_untracked_nr = dir->nr;
1796
1797
/* Actually recurse into dirname now, we'll fixup the state later. */
1798
untracked = lookup_untracked(dir->untracked, untracked,
@@ -1825,6 +1830,18 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
1830
}
1831
}
1832
1833
+ /*
1834
+ * We may need to ignore some of the untracked paths we found while
1835
+ * traversing subdirectories.
1836
+ */
1837
+ if ((dir->flags & DIR_SHOW_IGNORED_TOO) &&
1838
+ !(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {
1839
+ int i;
1840
+ for (i = old_untracked_nr + 1; i<dir->nr; ++i)
1841
+ FREE_AND_NULL(dir->entries[i]);
1842
+ dir->nr = old_untracked_nr;
1843
+ }
1844
+
1845
/*
1846
* If there is nothing under the current directory and we are not
1847
* hiding empty directories, then we need to report on the
@@ -2653,28 +2670,6 @@ int read_directory(struct dir_struct *dir, struct index_state *istate,
2670
QSORT(dir->entries, dir->nr, cmp_dir_entry);
2671
QSORT(dir->ignored, dir->ignored_nr, cmp_dir_entry);
2672
2656
- /*
2657
- * If DIR_SHOW_IGNORED_TOO is set, read_directory_recursive() will
2658
- * also pick up untracked contents of untracked dirs; by default
2659
- * we discard these, but given DIR_KEEP_UNTRACKED_CONTENTS we do not.
2660
- */
2661
- if ((dir->flags & DIR_SHOW_IGNORED_TOO) &&
2662
- !(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {
2663
- int i, j;
2664
-
2665
- /* remove from dir->entries untracked contents of untracked dirs */
2666
- for (i = j = 0; j < dir->nr; j++) {
2667
- if (i &&
2668
- check_dir_entry_contains(dir->entries[i - 1], dir->entries[j])) {
2669
- FREE_AND_NULL(dir->entries[j]);
2670
- } else {
2671
- dir->entries[i++] = dir->entries[j];
2672
- }
2673
- }
2674
-
2675
- dir->nr = i;
2676
- }
2677
-
2673
trace_performance_leave("read directory %.*s", len, path);
2674
if (dir->untracked) {
2675
static int force_untracked_cache = -1;