Signed-off-by: Nguyán ThÃi Ngác Duy <pclouds@xxxxxxxxx> --- This patch should be after 14/16. Otherwise the requirement in path_too_deep() is just wrong. Too late to reorder the series for sending. builtin/ls-files.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 52 insertions(+), 2 deletions(-) diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 3195f75..87ee728 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -27,6 +27,7 @@ static int show_killed; static int show_valid_bit; static int line_terminator = '\n'; static int debug_mode; +static int depth_limit; static const char *prefix; static int max_prefix_len; @@ -63,18 +64,54 @@ static void write_name(const char* name, size_t len) line_terminator); } +static const char *path_too_deep(const char *name) +{ + int common = 0; + if (!depth_limit) + return NULL; + + /* When depth_limit is set, pathspec contains exactly 1 item */ + while (name[common] && + name[common] == pathspec[0][common]) + common++; + while (common && name[common] != '/') + common--; + if (name[common] == '/') + common++; + return strchr(name + common, '/'); +} + +static int already_shown(const char *name) +{ + const char *last_item; + int len; + + if (!output.nr) + return 0; + + last_item = output.items[output.nr-1].string; + len = strlen(last_item); + return !strncmp(last_item, name, len) && name[len] == '/'; +} + static void show_dir_entry(const char *tag, struct dir_entry *ent) { int len = max_prefix_len; + const char *too_deep; if (len >= ent->len) die("git ls-files: internal error - directory entry not superset of prefix"); + if (already_shown(ent->name)) + return; + + too_deep = path_too_deep(ent->name); if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched)) return; + len = too_deep ? too_deep - ent->name : ent->len; fputs(tag, stdout); - write_name(ent->name, ent->len); + write_name(ent->name, len); } static void show_other_files(struct dir_struct *dir) @@ -141,12 +178,19 @@ static void show_killed_files(struct dir_struct *dir) static void show_ce_entry(const char *tag, struct cache_entry *ce) { int len = max_prefix_len; + const char *too_deep; + int namelen; if (len >= ce_namelen(ce)) die("git ls-files: internal error - cache entry not superset of prefix"); + if (already_shown(ce->name)) + return; + + too_deep = path_too_deep(ce->name); if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched)) return; + namelen = too_deep ? too_deep - ce->name : ce_namelen(ce); if (tag && *tag && show_valid_bit && (ce->ce_flags & CE_VALID)) { @@ -174,7 +218,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) find_unique_abbrev(ce->sha1,abbrev), ce_stage(ce)); } - write_name(ce->name, ce_namelen(ce)); + write_name(ce->name, namelen); if (debug_mode) { printf(" ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec); printf(" mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec); @@ -635,6 +679,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) int cmd_ls(int argc, const char **argv, const char *cmd_prefix) { struct dir_struct dir; + int recursive = 0; struct option builtin_ls_files_options[] = { OPT_BOOLEAN('c', "cached", &show_cached, "show cached files in the output (default)"), @@ -647,6 +692,8 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix) OPT_BIT('i', "ignored", &dir.flags, "show ignored files in the output", DIR_SHOW_IGNORED), + OPT_BOOLEAN('r', "recursive", &recursive, + "list recursively"), OPT_BOOLEAN('k', "killed", &show_killed, "show files on the filesystem that need to be removed"), OPT_COLUMN(0, "column", &column_mode, "show files in columns" ), @@ -683,6 +730,9 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix) show_killed | show_modified | show_resolve_undo)) show_cached = 1; + if (!recursive) + depth_limit = 1; + show_files(&dir); display_columns(&output, column_mode, term_columns(), 2, NULL); return 0; -- 1.7.2.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html