From: ZheNing Hu <adlternative@xxxxxxxxx> --object-only is an alias for --format=%(objectname), which output objectname of index entries, taking inspiration from the option with the same name in the `git ls-tree` command. --object-only cannot be used with --format, and -s, -o, -k, --resolve-undo, --deduplicate, --debug. Signed-off-by: ZheNing Hu <adlternative@xxxxxxxxx> --- Documentation/git-ls-files.txt | 8 +++++++- builtin/ls-files.c | 36 +++++++++++++++++++++++++++++++++- t/t3013-ls-files-format.sh | 34 ++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt index b22860ec8c0..c3f46bb821b 100644 --- a/Documentation/git-ls-files.txt +++ b/Documentation/git-ls-files.txt @@ -13,7 +13,7 @@ SYNOPSIS [-c|--cached] [-d|--deleted] [-o|--others] [-i|--|ignored] [-s|--stage] [-u|--unmerged] [-k|--|killed] [-m|--modified] [--directory [--no-empty-directory]] [--eol] - [--deduplicate] + [--deduplicate] [--object-only] [-x <pattern>|--exclude=<pattern>] [-X <file>|--exclude-from=<file>] [--exclude-per-directory=<file>] @@ -199,6 +199,12 @@ followed by the ("attr/<eolattr>"). interpolates to `\0` (NUL), `%09` to `\t` (TAB) and %0a to `\n` (LF). --format cannot be combined with `-s`, `-o`, `-k`, `--resolve-undo`, `--debug`. + +--object-only:: + List only names of the objects, one per line. This is equivalent + to specifying `--format='%(objectname)'`. Cannot be combined with + `--format=<format>`. + \--:: Do not interpret any more arguments as options. diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 9dd6c55eeb9..4ac8f34baac 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -60,6 +60,27 @@ static const char *tag_modified = ""; static const char *tag_skip_worktree = ""; static const char *tag_resolve_undo = ""; +static enum ls_files_cmdmode { + MODE_DEFAULT = 0, + MODE_OBJECT_ONLY, +} ls_files_cmdmode; + +struct ls_files_cmdmodee_to_fmt { + enum ls_files_cmdmode mode; + const char *const fmt; +}; + +static struct ls_files_cmdmodee_to_fmt ls_files_cmdmode_format[] = { + { + .mode = MODE_DEFAULT, + .fmt = NULL, + }, + { + .mode = MODE_OBJECT_ONLY, + .fmt = "%(objectname)", + }, +}; + static void write_eolinfo_internal(struct strbuf *sb, struct index_state *istate, const struct cache_entry *ce, const char *path) { @@ -747,6 +768,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) DIR_SHOW_IGNORED), OPT_BOOL('s', "stage", &show_stage, N_("show staged contents' object name in the output")), + OPT_CMDMODE(0, "object-only", &ls_files_cmdmode, N_("list only objects"), + MODE_OBJECT_ONLY), OPT_BOOL('k', "killed", &show_killed, N_("show files on the filesystem that need to be removed")), OPT_BIT(0, "directory", &dir.flags, @@ -815,9 +838,20 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix) add_pattern(exclude_list.items[i].string, "", 0, pl, --exclude_args); } + if (format && ls_files_cmdmode) + die(_("--format can't be combined with other format-altering options")); + + for (i = 0; !format && i < ARRAY_SIZE(ls_files_cmdmode_format); i++) { + if (ls_files_cmdmode == ls_files_cmdmode_format[i].mode) { + format = ls_files_cmdmode_format[i].fmt; + break; + } + } + if (format && (show_stage || show_others || show_killed || show_resolve_undo || skipping_duplicates || debug_mode)) - die(_("ls-files --format cannot used with -s, -o, -k, --resolve-undo, --deduplicate, --debug")); + die(_("ls-files --format or other format-altering options " + "cannot used with -s, -o, -k, --resolve-undo, --deduplicate, --debug")); if (show_tag || show_valid_bit || show_fsmonitor_bit) { tag_cached = "H "; diff --git a/t/t3013-ls-files-format.sh b/t/t3013-ls-files-format.sh index 61a2e68713a..1c982ea13e0 100755 --- a/t/t3013-ls-files-format.sh +++ b/t/t3013-ls-files-format.sh @@ -139,4 +139,38 @@ test_expect_success 'git ls-files --format with --debug must fail' ' test_must_fail git ls-files --format="%(objectname)" --debug ' +test_expect_success 'git ls-files --object-only equal to --format=%(objectname)' ' + git ls-files --format="%(objectname)" >expect && + git ls-files --object-only >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files --object-only with --format must fail' ' + test_must_fail git ls-files --format="%(path)" --object-only +' + +test_expect_success 'git ls-files --object-only with -s must fail' ' + test_must_fail git ls-files --object-only -s +' + +test_expect_success 'git ls-files --object-only with -o must fail' ' + test_must_fail git ls-files --object-only -o +' + +test_expect_success 'git ls-files --object-only with -k must fail' ' + test_must_fail git ls-files --object-only -k +' + +test_expect_success 'git ls-files --object-only with --resolve-undo must fail' ' + test_must_fail git ls-files --object-only --resolve-undo +' + +test_expect_success 'git ls-files --object-only with --deduplicate must fail' ' + test_must_fail git ls-files --object-only --deduplicate +' + +test_expect_success 'git ls-files --object-only with --debug must fail' ' + test_must_fail git ls-files --object-only --debug +' + test_done -- gitgitgadget