git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v5 1/1] ls-tree.c: support `--object-only` option for "git-ls-tree"

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 15, 2021, 19:25 UTC
Message-ID
<xmqqk0g5656r.fsf@gitster.g>
In-Reply-To
<38d55a878c51104f0a5337481fdcd5c8818660ac.1638891420.git.dyroneteng@gmail.com>
Teng Long <dyroneteng@gmail.com> writes:
Show 10 quoted lines
> We usually pipe the output from `git ls-trees` to tools like
> `sed` or `cut` when we only want to extract some fields.
>
> When we want only the pathname component, we can pass
> `--name-only` option to omit such a pipeline, but there are no
> options for extracting other fields.
>
> Teach the "--object-only" option to the command to only show the
> object name. This option cannot be used together with
> "--name-only" or "--long" (mutually exclusive).

I notice that this changed from --oid to --object and I agree that it would probably be more friendly to end users. In fact, this

    $ sed -ne '/^SYNOPSIS/,/^DESCRIPTION/p' Documentation/git-*.txt |
      grep -e -oid
did not find any hits.
Show 17 quoted lines
> diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
> index 3a442631c7..beaa8bf13b 100644
> --- a/builtin/ls-tree.c
> +++ b/builtin/ls-tree.c
> @@ -16,21 +16,38 @@
>  
>  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_TREE_ONLY 1 << 1
> +#define LS_SHOW_TREES 1 << 2
> +#define LS_NAME_ONLY 1 << 3
> +#define LS_SHOW_SIZE 1 << 4
> +#define LS_OBJECT_ONLY 1 << 5

It usually is a good idea to enclose these in () so that they are safe to use in any context in a statement.

Luckily, bitwise-or and bitwise-and, which are the most likely candidates for these symbols to be used with, bind looser than left-shift, so something like

	if ((LS_TREE_ONLY | LS_SHOW_TREES) & opt)
		... do this ...

is safe either way, but (LS_TREE_ONLY + LS_SHOW_TREES) would have different value with and without () around (1 << N).

> +static unsigned int shown_bits = 0;
Style: we do not initialize statics explicitly to zero.
Show 6 quoted lines
> +#define SHOW_DEFAULT 29 /* 11101 size is not shown to output by default */
> +#define SHOW_MODE 1 << 4
> +#define SHOW_TYPE 1 << 3
> +#define SHOW_OBJECT_NAME 1 << 2
> +#define SHOW_SIZE 1 << 1
> +#define SHOW_FILE_NAME 1

Likewise. It is a bit curious to see these listed in decreasing order, though.

Show 10 quoted lines
>  static const  char * const ls_tree_usage[] = {
>  	N_("git ls-tree [<options>] <tree-ish> [<path>...]"),
>  	NULL
>  };
>  
> +enum {
> +	MODE_UNSPECIFIED = 0,
> +	MODE_NAME_ONLY,
> +	MODE_OBJECT_ONLY,
> +	MODE_LONG

It is a good idea to leave a comma even after the last element, _unless_ there is a strong reason why the element that currently is at the last MUST stay to be last when new elements are added to the enum. That way, a future patch that adds a new element can add it to the list with a patch noise with fewer lines.

> +};
> +
> +static int cmdmode = MODE_UNSPECIFIED;

This is also initializing a static variable to zero, and arguments can be made either way: (A) unspecified is set to zero in enum definition exactly so that we can use zero to signal the variable is unspecified, so an explicit zero initialization here goes against the spirit of choosing 0 as MODE_UNSPECIFIED; or (B) enum definition can be scrambled in future changes to use something other than zero for MODE_UNSPECIFIED, and explicitly writing it like this is more future-proof.

I am OK with the way it is written (i.e. (B)).
Show 5 quoted lines
> @@ -66,6 +83,7 @@ static int show_tree(const struct object_id *oid, struct strbuf *base,
>  {
>  	int retval = 0;
>  	int baselen;
> +	int follow = 0;
A better name, anybody?

This bit is to keep track of the fact that we made _some_ output already so any further output needs an inter-field space before writing what it wants to write out.

Show 13 quoted lines
>  	const char *type = blob_type;
>  
>  	if (S_ISGITLINK(mode)) {
> @@ -74,8 +92,8 @@ static int show_tree(const struct object_id *oid, struct strbuf *base,
>  		 *
>  		 * Something similar to this incomplete example:
>  		 *
> -		if (show_subprojects(base, baselen, pathname))
> -			retval = READ_TREE_RECURSIVE;
> +		 * if (show_subprojects(base, baselen, pathname))
> +		 *	retval = READ_TREE_RECURSIVE;
>  		 *
>  		 */
Nice ;-)
Show 23 quoted lines
>  		type = commit_type;
> @@ -90,35 +108,67 @@ 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 (ls_options & LS_SHOW_SIZE) {
> -			char size_text[24];
> -			if (!strcmp(type, blob_type)) {
> -				unsigned long size;
> -				if (oid_object_info(the_repository, oid, &size) == OBJ_BAD)
> -					xsnprintf(size_text, sizeof(size_text),
> -						  "BAD");
> -				else
> -					xsnprintf(size_text, sizeof(size_text),
> -						  "%"PRIuMAX, (uintmax_t)size);
> -			} else
> -				xsnprintf(size_text, sizeof(size_text), "-");
> -			printf("%06o %s %s %7s\t", mode, type,
> -			       find_unique_abbrev(oid, abbrev),
> -			       size_text);
> +	if (shown_bits & SHOW_MODE) {
> +		printf("%06o",mode);
SP before ','.
Show 11 quoted lines
> +		follow = 1;
> +	}
> +	if (shown_bits & SHOW_TYPE) {
> +		printf("%s%s", follow == 1 ? " " : "", type);
> +		follow = 1;
> +	}
> +	if (shown_bits & SHOW_OBJECT_NAME) {
> +		printf("%s%s", follow == 1 ? " " : "",
> +		       find_unique_abbrev(oid, abbrev));
> +		if (!(shown_bits ^ SHOW_OBJECT_NAME))
> +			printf("%c", line_termination);

Curious. I wonder if we can get rid of these two lines (and the line_termination bit in the SHOW_FILE_NAME part), and have an unconditional

	putchar(line_termination);
at the end of the function.

That way, we could in the future choose to introduce a feature to show only <mode, type, size> and nothing else, which may be useful for taking per-type stats.

We need to stop using write_name_quoted_relative() in SHOW_FILE_NAME part, because the helper insists that the name written by it must be at the end of the entry, if we go that route, but it may be a good change in the longer term.

Show 28 quoted lines
> +		follow = 1;
> +	}
> +	if (shown_bits & SHOW_SIZE) {
> +		char size_text[24];
> +		if (!strcmp(type, blob_type)) {
> +			unsigned long size;
> +			if (oid_object_info(the_repository, oid, &size) == OBJ_BAD)
> +				xsnprintf(size_text, sizeof(size_text), "BAD");
> +			else
> +				xsnprintf(size_text, sizeof(size_text),
> +					  "%"PRIuMAX, (uintmax_t)size);
>  		} else
> -			printf("%06o %s %s\t", mode, type,
> -			       find_unique_abbrev(oid, abbrev));
> +			xsnprintf(size_text, sizeof(size_text), "-");
> +		printf("%s%7s", follow == 1 ? " " : "", size_text);
> +		follow = 1;
> +	}
> +	if (shown_bits & SHOW_FILE_NAME) {
> +		if (follow)
> +			printf("\t");
> +		baselen = base->len;
> +		strbuf_addstr(base, pathname);
> +		write_name_quoted_relative(base->buf,
> +					   chomp_prefix ? ls_tree_prefix : NULL,
> +					   stdout, line_termination);
> +		strbuf_setlen(base, baselen);
>  	}

But the above nits aside, the updated organization of this function looks much cleaner than the original. Nicely reorganized.

Show 8 quoted lines
> -	baselen = base->len;
> -	strbuf_addstr(base, pathname);
> -	write_name_quoted_relative(base->buf,
> -				   chomp_prefix ? ls_tree_prefix : NULL,
> -				   stdout, line_termination);
> -	strbuf_setlen(base, baselen);
>  	return retval;
>  }
Thanks.
Previous: Teng LongNext: Teng Long
Message 41 of 55 in “support `--oid-only` in `ls-tree`”
  1. 0/3 support `--oid-only` in `ls-tree`Teng Long, Nov 15, 2021
  2. 1/3 ls-tree.c: support `--oid-only` option for "git-ls-tree"Teng Long, Nov 15, 2021
  3. Ævar Arnfjörð BjarmasonNov 15, 2021
  4. Teng LongNov 18, 2021
  5. Ævar Arnfjörð BjarmasonNov 18, 2021
  6. Jeff KingNov 15, 2021
  7. Jeff KingNov 15, 2021
  8. Teng LongNov 18, 2021
  9. 2/3 t3104: add related tests for `--oid-only` optionTeng Long, Nov 15, 2021
  10. Đoàn Trần Công DanhNov 15, 2021
  11. Teng LongNov 18, 2021
  12. 3/3 git-ls-tree.txt: description of the 'oid-only' optionTeng Long, Nov 15, 2021
  13. Ævar Arnfjörð BjarmasonNov 15, 2021
  14. Jeff KingNov 15, 2021
  15. Ævar Arnfjörð BjarmasonNov 15, 2021
  16. Teng LongNov 19, 2021
  17. Jeff KingNov 15, 2021
  18. 0/1 support `--oid-only` in `ls-tree`Teng Long, Nov 19, 2021
  19. 1/1 ls-tree.c: support `--oid-only` option for "git-ls-tree"Teng Long, Nov 19, 2021
  20. Ævar Arnfjörð BjarmasonNov 19, 2021
  21. Junio C HamanoNov 19, 2021
  22. Teng LongNov 22, 2021
  23. Ævar Arnfjörð BjarmasonNov 22, 2021
  24. 0/1 ls-tree.c: support `--oid-only` optionTeng Long, Nov 22, 2021
  25. 1/1 ls-tree.c: support `--oid-only` option for "git-ls-tree"Teng Long, Nov 22, 2021
  26. Peter BaumannNov 22, 2021
  27. Junio C HamanoNov 22, 2021
  28. Ævar Arnfjörð BjarmasonNov 23, 2021
  29. Junio C HamanoNov 23, 2021
  30. Ævar Arnfjörð BjarmasonNov 23, 2021
  31. Junio C HamanoNov 23, 2021
  32. Junio C HamanoNov 23, 2021
  33. Ævar Arnfjörð BjarmasonNov 23, 2021
  34. Đoàn Trần Công DanhNov 23, 2021
  35. 0/1 ls-tree.c: support `--oid-only` optionTeng Long, Nov 23, 2021
  36. 1/1 ls-tree.c: support `--oid-only` option for "git-ls-tree"Teng Long, Nov 23, 2021
  37. Junio C HamanoNov 23, 2021
  38. Teng LongDec 6, 2021
  39. 0/1 support `--object-only` option for "git-ls-tree"Teng Long, Dec 8, 2021
  40. 1/1 ls-tree.c: support `--object-only` option for "git-ls-tree"Teng Long, Dec 8, 2021
  41. Junio C HamanoDec 15, 2021
  42. Teng LongDec 16, 2021
  43. Junio C HamanoDec 16, 2021
  44. Ævar Arnfjörð BjarmasonDec 16, 2021
  45. 0/1 support `--object-only` option for "git-ls-tree"Teng Long, Dec 17, 2021
  46. 1/1 ls-tree.c: support `--object-only` option for "git-ls-tree"Teng Long, Dec 17, 2021
  47. Ævar Arnfjörð BjarmasonDec 17, 2021
  48. 0/7 ls-tree --formatÆvar Arnfjörð Bjarmason, Dec 17, 2021
  49. 1/7 ls-tree: remove commented-out codeÆvar Arnfjörð Bjarmason, Dec 17, 2021
  50. 2/7 ls-tree: add missing braces to "else" armsÆvar Arnfjörð Bjarmason, Dec 17, 2021
  51. 4/7 ls-tree: use "size_t", not "int" for "struct strbuf"'s "len"Ævar Arnfjörð Bjarmason, Dec 17, 2021
  52. 3/7 ls-tree: use "enum object_type", not {blob,tree,commit}_typeÆvar Arnfjörð Bjarmason, Dec 17, 2021
  53. 6/7 ls-tree: add a --format=<fmt> optionÆvar Arnfjörð Bjarmason, Dec 17, 2021
  54. 5/7 ls-tree: split up the "init" part of show_tree()Ævar Arnfjörð Bjarmason, Dec 17, 2021
  55. 7/7 ls-tree.c: support `--object-only` option for "git-ls-tree"Ævar Arnfjörð Bjarmason, Dec 17, 2021

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.