On 2021-11-22 16:07:28+0800, Teng Long <dyroneteng@xxxxxxxxx> wrote: > Sometimes, we only want to get the objects from output of `ls-tree` > and commands like `sed` or `cut` is usually used to intercept the > origin output to achieve this purpose in practical. > > This commit supply an option names `--oid-only` to let `git ls-tree` > only print out the OID of the object. `--oid-only` and `--name-only` > are mutually exclusive in use. > > Signed-off-by: Teng Long <dyroneteng@xxxxxxxxx> > --- > Documentation/git-ls-tree.txt | 8 +++++-- > builtin/ls-tree.c | 27 ++++++++++++++++------- > t/t3104-ls-tree-oid.sh | 40 +++++++++++++++++++++++++++++++++++ > 3 files changed, 65 insertions(+), 10 deletions(-) > create mode 100755 t/t3104-ls-tree-oid.sh > > diff --git a/Documentation/git-ls-tree.txt b/Documentation/git-ls-tree.txt > index db02d6d79a..bc711dc00a 100644 > --- a/Documentation/git-ls-tree.txt > +++ b/Documentation/git-ls-tree.txt > @@ -10,7 +10,8 @@ SYNOPSIS > -------- > [verse] > 'git ls-tree' [-d] [-r] [-t] [-l] [-z] > - [--name-only] [--name-status] [--full-name] [--full-tree] [--abbrev[=<n>]] > + [--name-only] [--name-status] [--oid-only] Please indicate those options are incompatible (as someone else said): [--name-only | --name-status | --oid-only] > + [--full-name] [--full-tree] [--abbrev[=<n>]] > <tree-ish> [<path>...] > > DESCRIPTION > @@ -59,7 +60,10 @@ OPTIONS > --name-only:: > --name-status:: > List only filenames (instead of the "long" output), one per line. > - > + Cannot be used with `--oid-only` together. > +--oid-only:: > + List only OIDs of the objects, one per line. Cannot be used with > + `--name-only` or `--name-status` together. > --abbrev[=<n>]:: > Instead of showing the full 40-byte hexadecimal object > lines, show the shortest prefix that is at least '<n>' > diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c > index 3a442631c7..1e4a82e669 100644 > --- a/builtin/ls-tree.c > +++ b/builtin/ls-tree.c > @@ -18,19 +18,26 @@ static int line_termination = '\n'; > #define LS_RECURSIVE 1 > #define LS_TREE_ONLY 2 > #define LS_SHOW_TREES 4 > -#define LS_NAME_ONLY 8 > -#define LS_SHOW_SIZE 16 > +#define LS_SHOW_SIZE 8 > static int abbrev; > static int ls_options; > static struct pathspec pathspec; > static int chomp_prefix; > static const char *ls_tree_prefix; > > -static const char * const ls_tree_usage[] = { > +static const char * const ls_tree_usage[] = { > N_("git ls-tree [<options>] <tree-ish> [<path>...]"), > NULL > }; > > +enum { > + MODE_UNSPECIFIED = 0, > + MODE_NAME_ONLY, > + MODE_OID_ONLY > +}; > + > +static int cmdmode = MODE_UNSPECIFIED; > + > static int show_recursive(const char *base, int baselen, const char *pathname) > { > int i; > @@ -90,7 +97,12 @@ static int show_tree(const struct object_id *oid, struct strbuf *base, > else if (ls_options & LS_TREE_ONLY) > return 0; > > - if (!(ls_options & LS_NAME_ONLY)) { > + if (cmdmode == 2) { I think it's better to use the enum name: if (cmdmode == MODE_OID_ONLY) { > + printf("%s\n", find_unique_abbrev(oid, abbrev)); > + return 0; > + } > + > + if (cmdmode == 0) { Ditto: if (cmdmode == MODE_UNSPECIFIED) { Speaking about this, where will MODE_NAME_ONLY be used? > if (ls_options & LS_SHOW_SIZE) { > char size_text[24]; > if (!strcmp(type, blob_type)) { > @@ -135,10 +147,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix) > N_("terminate entries with NUL byte"), 0), > OPT_BIT('l', "long", &ls_options, N_("include object size"), > LS_SHOW_SIZE), > - OPT_BIT(0, "name-only", &ls_options, N_("list only filenames"), > - LS_NAME_ONLY), > - OPT_BIT(0, "name-status", &ls_options, N_("list only filenames"), > - LS_NAME_ONLY), > + OPT_CMDMODE('n', "name-only", &cmdmode, N_("list only filenames"), MODE_NAME_ONLY), > + OPT_CMDMODE('s', "name-status", &cmdmode, N_("list only filenames"), MODE_NAME_ONLY), > + OPT_CMDMODE('o', "oid-only", &cmdmode, N_("list only oids"), MODE_OID_ONLY), > OPT_SET_INT(0, "full-name", &chomp_prefix, > N_("use full path names"), 0), > OPT_BOOL(0, "full-tree", &full_tree, > diff --git a/t/t3104-ls-tree-oid.sh b/t/t3104-ls-tree-oid.sh > new file mode 100755 > index 0000000000..4c02cdd3c3 > --- /dev/null > +++ b/t/t3104-ls-tree-oid.sh > @@ -0,0 +1,40 @@ > +#!/bin/sh > + > +test_description='git ls-tree oids handling.' > + > +. ./test-lib.sh > + > +test_expect_success 'setup' ' > + echo 111 >1.txt && > + echo 222 >2.txt && > + mkdir -p path0/a/b/c && > + echo 333 >path0/a/b/c/3.txt && > + find *.txt path* \( -type f -o -type l \) -print | > + xargs git update-index --add && > + tree=$(git write-tree) && > + echo $tree > +' > + > +test_expect_success 'usage: --oid-only' ' > + git ls-tree --oid-only $tree >current && > + git ls-tree $tree | awk "{print \$3}" >expected && > + test_cmp current expected > +' > + > +test_expect_success 'usage: --oid-only with -r' ' > + git ls-tree --oid-only -r $tree >current && > + git ls-tree -r $tree | awk "{print \$3}" >expected && > + test_cmp current expected > +' > + > +test_expect_success 'usage: --oid-only with --abbrev' ' > + git ls-tree --oid-only --abbrev=6 $tree >current && > + git ls-tree --abbrev=6 $tree | awk "{print \$3}" > expected && > + test_cmp current expected > +' > + > +test_expect_failure 'usage: incompatible options: --name-only with --oid-only' ' > + test_incompatible_usage git ls-tree --oid-only --name-only > +' > + > +test_done It seems like you haven't updated the test code from v2 -- Danh