static int show_modified = 0;
static int show_killed = 0;
static int show_other_directories = 0;
+static int hide_empty_directories = 0;
static int show_valid_bit = 0;
static int line_terminator = '\n';
* Also, we ignore the name ".git" (even if it is not a directory).
* That likely will not change.
*/
-static void read_directory(const char *path, const char *base, int baselen)
+static int read_directory(const char *path, const char *base, int baselen)
{
- DIR *dir = opendir(path);
+ DIR *fdir = opendir(path);
+ int contents = 0;
- if (dir) {
+ if (fdir) {
int exclude_stk;
struct dirent *de;
char fullname[MAXPATHLEN + 1];
exclude_stk = push_exclude_per_directory(base, baselen);
- while ((de = readdir(dir)) != NULL) {
+ while ((de = readdir(fdir)) != NULL) {
int len;
if ((de->d_name[0] == '.') &&
switch (DTYPE(de)) {
struct stat st;
+ int subdir, rewind_base;
default:
continue;
case DT_UNKNOWN:
case DT_DIR:
memcpy(fullname + baselen + len, "/", 2);
len++;
+ rewind_base = nr_dir;
+ subdir = read_directory(fullname, fullname,
+ baselen + len);
if (show_other_directories &&
- !dir_exists(fullname, baselen + len))
+ (subdir || !hide_empty_directories) &&
+ !dir_exists(fullname, baselen + len)) {
+ // Rewind the read subdirectory
+ while (nr_dir > rewind_base)
+ free(dir[--nr_dir]);
break;
- read_directory(fullname, fullname,
- baselen + len);
+ }
+ contents += subdir;
continue;
case DT_REG:
case DT_LNK:
break;
}
add_name(fullname, baselen + len);
+ contents++;
}
- closedir(dir);
+ closedir(fdir);
pop_exclude_per_directory(exclude_stk);
}
+
+ return contents;
}
static int cmp_name(const void *p1, const void *p2)
show_other_directories = 1;
continue;
}
+ if (!strcmp(arg, "--no-empty-directory")) {
+ hide_empty_directories = 1;
+ continue;
+ }
if (!strcmp(arg, "-u") || !strcmp(arg, "--unmerged")) {
/* There's no point in showing unmerged unless
* you also show the stage information.