summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Petr Baudis <pasky@suse.cz>2006-03-26 16:59:52 +0200
committerLibravatar Junio C Hamano <junkio@cox.net>2006-03-26 19:08:24 -0800
commitb0a3de42316a4e8f1d561cbe12b7bb282631a0d6 (patch)
tree627ae686f4f33521153436c28bb4a775c2b25a19
parentDocument git-rebase behavior on conflicts. (diff)
downloadtgif-b0a3de42316a4e8f1d561cbe12b7bb282631a0d6.tar.xz
Optionally do not list empty directories in git-ls-files --others
Without the --directory flag, git-ls-files wouldn't ever list directories, producing no output for empty directories, which is good since they cannot be added and they bear no content, even untracked one (if Git ever starts tracking directories on their own, this should obviously change since the content notion will change). With the --directory flag however, git-ls-files would list even empty directories. This may be good in some situations but sometimes you want to prevent that. This patch adds a --no-empty-directory option which makes git-ls-files omit empty directories. Signed-off-by: Petr Baudis <pasky@suse.cz>
-rw-r--r--Documentation/git-ls-files.txt3
-rw-r--r--ls-files.c33
2 files changed, 28 insertions, 8 deletions
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index e813f84202..980c5c9186 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -52,6 +52,9 @@ OPTIONS
If a whole directory is classified as "other", show just its
name (with a trailing slash) and not its whole contents.
+--no-empty-directory::
+ Do not list empty directories. Has no effect without --directory.
+
-u|--unmerged::
Show unmerged files in the output (forces --stage)
diff --git a/ls-files.c b/ls-files.c
index e42119c5ee..83b0a3b49f 100644
--- a/ls-files.c
+++ b/ls-files.c
@@ -20,6 +20,7 @@ static int show_unmerged = 0;
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';
@@ -258,11 +259,12 @@ static int dir_exists(const char *dirname, int len)
* 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];
@@ -270,7 +272,7 @@ static void read_directory(const char *path, const char *base, int baselen)
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] == '.') &&
@@ -288,6 +290,7 @@ static void read_directory(const char *path, const char *base, int baselen)
switch (DTYPE(de)) {
struct stat st;
+ int subdir, rewind_base;
default:
continue;
case DT_UNKNOWN:
@@ -301,22 +304,32 @@ static void read_directory(const char *path, const char *base, int baselen)
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)
@@ -696,6 +709,10 @@ int main(int argc, const char **argv)
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.