list-files is supposed to be the user friendly version of ls-files, or an alternative to git-status. Nothing fancy in this patch yet. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@xxxxxxxxx> --- .gitignore | 1 + Makefile | 1 + builtin.h | 1 + builtin/list-files.c (new) | 107 +++++++++++++++++++++++++++++++++++++++++ git.c | 1 + t/t7013-list-files.sh (new +x) | 35 ++++++++++++++ 6 files changed, 146 insertions(+) create mode 100644 builtin/list-files.c create mode 100755 t/t7013-list-files.sh diff --git a/.gitignore b/.gitignore index a052419..0534225 100644 --- a/.gitignore +++ b/.gitignore @@ -77,6 +77,7 @@ /git-interpret-trailers /git-instaweb /git-log +/git-list-files /git-ls-files /git-ls-remote /git-ls-tree diff --git a/Makefile b/Makefile index 459121d..17f52b2 100644 --- a/Makefile +++ b/Makefile @@ -832,6 +832,7 @@ BUILTIN_OBJS += builtin/index-pack.o BUILTIN_OBJS += builtin/init-db.o BUILTIN_OBJS += builtin/interpret-trailers.o BUILTIN_OBJS += builtin/log.o +BUILTIN_OBJS += builtin/list-files.o BUILTIN_OBJS += builtin/ls-files.o BUILTIN_OBJS += builtin/ls-remote.o BUILTIN_OBJS += builtin/ls-tree.o diff --git a/builtin.h b/builtin.h index b87df70..afc29e7 100644 --- a/builtin.h +++ b/builtin.h @@ -76,6 +76,7 @@ extern int cmd_init_db(int argc, const char **argv, const char *prefix); extern int cmd_interpret_trailers(int argc, const char **argv, const char *prefix); extern int cmd_log(int argc, const char **argv, const char *prefix); extern int cmd_log_reflog(int argc, const char **argv, const char *prefix); +extern int cmd_list_files(int argc, const char **argv, const char *prefix); extern int cmd_ls_files(int argc, const char **argv, const char *prefix); extern int cmd_ls_tree(int argc, const char **argv, const char *prefix); extern int cmd_ls_remote(int argc, const char **argv, const char *prefix); diff --git a/builtin/list-files.c b/builtin/list-files.c new file mode 100644 index 0000000..8b74d79 --- /dev/null +++ b/builtin/list-files.c @@ -0,0 +1,107 @@ +#include "cache.h" +#include "builtin.h" +#include "parse-options.h" +#include "pathspec.h" +#include "dir.h" + +enum item_type { + FROM_INDEX +}; + +struct item { + enum item_type type; + const char *path; + const struct cache_entry *ce; +}; + +struct item_list { + struct item *items; + int nr, alloc; +}; + +static struct pathspec pathspec; +static const char *prefix; +static int prefix_length; + +static const char * const ls_usage[] = { + N_("git list-files [options] [<pathspec>...]"), + NULL +}; + +struct option ls_options[] = { + OPT_END() +}; + +static void populate_cached_entries(struct item_list *result, + const struct index_state *istate) +{ + int i; + + for (i = 0; i < istate->cache_nr; i++) { + const struct cache_entry *ce = istate->cache[i]; + struct item *item; + + if (!match_pathspec(&pathspec, ce->name, ce_namelen(ce), + 0, NULL, + S_ISDIR(ce->ce_mode) || + S_ISGITLINK(ce->ce_mode))) + continue; + + ALLOC_GROW(result->items, result->nr + 1, result->alloc); + item = result->items + result->nr++; + item->type = FROM_INDEX; + item->path = ce->name; + item->ce = ce; + } +} + +static void display(const struct item_list *result) +{ + int i; + + for (i = 0; i < result->nr; i++) { + const struct item *item = result->items + i; + + printf("%s\n", item->path); + } +} + +static int ls_config(const char *var, const char *value, void *cb) +{ + return git_default_config(var, value, cb); +} + +int cmd_list_files(int argc, const char **argv, const char *cmd_prefix) +{ + struct item_list result; + + if (argc == 2 && !strcmp(argv[1], "-h")) + usage_with_options(ls_usage, ls_options); + + prefix = cmd_prefix; + if (prefix) + prefix_length = strlen(prefix); + + if (read_cache() < 0) + die(_("index file corrupt")); + + git_config(ls_config, NULL); + + argc = parse_options(argc, argv, prefix, ls_options, ls_usage, 0); + + parse_pathspec(&pathspec, 0, + PATHSPEC_PREFER_CWD | + PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP, + cmd_prefix, argv); + pathspec.max_depth = 0; + pathspec.recursive = 1; + + refresh_index(&the_index, REFRESH_QUIET | REFRESH_UNMERGED, + &pathspec, NULL, NULL); + + memset(&result, 0, sizeof(result)); + populate_cached_entries(&result, &the_index); + display(&result); + /* free-ing result seems unnecessary */ + return 0; +} diff --git a/git.c b/git.c index 18fbf79..ae7fe77 100644 --- a/git.c +++ b/git.c @@ -418,6 +418,7 @@ static struct cmd_struct commands[] = { { "init", cmd_init_db, NO_SETUP }, { "init-db", cmd_init_db, NO_SETUP }, { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP }, + { "list-files", cmd_list_files, RUN_SETUP | USE_PAGER | NEED_WORK_TREE }, { "log", cmd_log, RUN_SETUP }, { "ls-files", cmd_ls_files, RUN_SETUP }, { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY }, diff --git a/t/t7013-list-files.sh b/t/t7013-list-files.sh new file mode 100755 index 0000000..f43776e --- /dev/null +++ b/t/t7013-list-files.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='list-files' + +. ./test-lib.sh + +test_expect_success 'setup' ' + mkdir sa sa/sb sc && + touch a b c sa/a sa/sb/b sc/c && + git add . +' + +test_expect_success 'list-files from index' ' + git list-files >actual && + cat >expect <<-\EOF && + a + b + c + sa/a + sa/sb/b + sc/c + EOF + test_cmp expect actual +' + +test_expect_success 'list-files selectively from index' ' + git list-files "*a" >actual && + cat >expect <<-\EOF && + a + sa/a + EOF + test_cmp expect actual +' + +test_done -- 2.3.0.rc1.137.g477eb31 -- 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