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

Re: [PATCH 3/6] Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-file

From
Junio C Hamano <gitster@pobox.com>
Date
Apr 26, 2011, 16:36 UTC
Message-ID
<7vy62xezqy.fsf@alter.siamese.dyndns.org>
In-Reply-To
<1303776102-9085-4-git-send-email-johan@herland.net>
Johan Herland <johan@herland.net> writes:
Show 17 quoted lines
> Instead of having multiple interconnected dirstat-related options, teach
> the --dirstat option itself to accept all behavior modifiers as arguments.
>
> - Preserve the current --dirstat=<limit> (where <limit> is an integer
>   specifying a cut-off percentage)
> - Add --dirstat=cumulative, replacing --cumulative
> - Add --dirstat=files, replacing --dirstat-by-file
> - Also add --dirstat=changes and --dirstat=noncumulative for specifying the
>   current default behavior. These allow the user to reset other --dirstat
>   arguments (e.g. 'cumulative' and 'files') occuring earlier on the command
>   line.
>
> Allow multiple arguments to be separated by commas, e.g.:
>   --dirstat=files,10,cumulative
>
> Update the documentation accordingly, and add testcases verifying the
> behavior of the new syntax.

The above description is unclear if the version of git will error out when given --cumulative or --dirstat-by-file. I can sort of guess by lack of removed lines from the documentation, but please do not make readers guess.

Also a miniscule style nitpick: could you indent your bulletted-list just a bit (one space indent is just fine)?

Show 20 quoted lines
> diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
> index 7e4bd42..b6b1448 100644
> --- a/Documentation/diff-options.txt
> +++ b/Documentation/diff-options.txt
> @@ -66,19 +66,40 @@ endif::git-format-patch[]
>  	number of modified files, as well as number of added and deleted
>  	lines.
>  
> ---dirstat[=<limit>]::
> -	Output the distribution of relative amount of changes (number of lines added or
> -	removed) for each sub-directory. Directories with changes below
> -	a cut-off percent (3% by default) are not shown. The cut-off percent
> -	can be set with `--dirstat=<limit>`. Changes in a child directory are not
> -	counted for the parent directory, unless `--cumulative` is used.
> +--dirstat[=<arg1,arg2,...>]::
> +	Output the distribution of relative amount of changes for each
> +	sub-directory. The behavior of `--dirstat` can be customized by
> +	passing it a comma separated list of arguments. The defaults
> +	are controlled by the `diff.dirstat` configuration variable (see
> +	linkgit:git-config[1]). The following arguments are available:

These "arguments" feel more like "options" (or "parameters"), no? Your code in diff.c also calls it "opt". The second line of the proposed log message has the same issue.

Show 7 quoted lines
> +--
> +`changes`;;
> +	Compute the dirstat numbers by counting the lines that have been
> +	removed from the source, or added to the destination. This ignores
> +	the amount of pure code movements within a file.  In other words,
> +	rearranging lines in a file is not counted as much as other changes.
> +	This is the default `--dirstat` behavior.
"default behavior when no option is given"?
Show 5 quoted lines
> +`files`;;
> +	Compute the dirstat numbers by counting the number of files changed.
> +	Each changed file counts equally in the dirstat analysis. This is
> +	the computationally cheapest `--dirstat` behavior, since it does
> +	not look at the file contents at all.
s/not look/not have to look/?
Show 5 quoted lines
> +`cumulative`;;
> +	Count changes in a child directory for the parent directory as well.
> +	Note that when using `cumulative`, the sum of the percentages
> +	reported may exceed 100%. The default (non-cumulative) behavior can
> +	be specified with the `noncumulative` argument.

So the later one wins? I.e. --dirstat=cumulative,noncumulative from the command line (which seems silly), or more importantly with

    [alias]
    	dstat = diff --dirstat=cumulative
and you can say "git dstat --dirstat=noncumulative A..B"?
Show 8 quoted lines
> diff --git a/diff.c b/diff.c
> index cfbfa92..08aaa47 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -3144,6 +3144,72 @@ static int stat_opt(struct diff_options *options, const char **av)
>  	return argcount;
>  }
>  
/*
 * Document what the return value from this function means here.
 */
> +static int dirstat_opt(struct diff_options *options, const char **av)
Do you have to pass "const char **av", or just "const char *arg"?
Show 19 quoted lines
> +{
> +	const char *p, *arg = av[0];
> +	char *mangled = NULL;
> +	char sep = '=';
> +
> +	if (!strcmp(arg, "--cumulative")) /* deprecated */
> +		/* handle '--cumulative' like '--dirstat=cumulative' */
> +		p = "=cumulative";
> +	else if (!strcmp(arg, "--dirstat-by-file") ||
> +		 !prefixcmp(arg, "--dirstat-by-file=")) { /* deprecated */
> +		/* handle '--dirstat-by-file=*' like '--dirstat=files,*' */
> +		mangled = xstrdup(arg + 2);
> +		memcpy(mangled, "--dirstat=files", 15);
> +		if (mangled[15]) {
> +			assert(mangled[15] == '=');
> +			mangled[15] = ',';
> +		}
> +		arg = mangled;
> +		p = mangled + 9;

I understand you wanted to reuse the while() loop below, but I do not think it is worth it. Isn't it easier to read if you handled the above cases in their if/else body and return?

	if (--cumulative) {
		options->output_format |= DIFF_FORMAT_DIRSTAT;
        	DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
                return 1;
	}
        if (--dirstat-by-file) {
		options->output_format |= DIFF_FORMAT_DIRSTAT;
		DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
		return 1;
	}
	...

Even better, probably they can be left to diff_opt_parse() without calling this function, as you are deprecating them and do not have to allow them to take the opt1,opt2,... form of parameter.

Show 12 quoted lines
> +	}
> +	else if (!prefixcmp(arg, "-X"))
> +		p = arg + 2;
> +	else if (!prefixcmp(arg, "--dirstat"))
> +		p = arg + 9;
> +	else
> +		return 0;
> +
> +	options->output_format |= DIFF_FORMAT_DIRSTAT;
> +
> +	while (*p) {
> +		if (*p != sep)
What happens to "diff -X3 A..B"?
> +			die("Missing argument separator ('%c'), at index %lu of '%s'",
> +			    sep, p - arg, arg);

Don't you need to cast (p-arg) for %lu from ptrdiff type here? It probably is more common to say s/index/char/;

> +		sep = ',';
> +		++p;

We tend to write postincrement when there is no strong reason to do otherwise.

Show 22 quoted lines
> +		if (!prefixcmp(p, "changes")) {
> +			p += 7;
> +			DIFF_OPT_CLR(options, DIRSTAT_BY_FILE);
> +		}
> +		else if (!prefixcmp(p, "files")) {
> +			p += 5;
> +			DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
> +		}
> +		else if (!prefixcmp(p, "noncumulative")) {
> +			p += 13;
> +			DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
> +		}
> +		else if (!prefixcmp(p, "cumulative")) {
> +			p += 10;
> +			DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
> +		}
> +		else if (isdigit(*p)) {
> +			char *end;
> +			options->dirstat_percent = strtoul(p, &end, 10);
> +			assert(end > p);
> +			p = end;
> +		}
That's a senseless assert(), isn't it?

You already know the first letter is a digit, so assert(p < end) will always be true. You may want to check that this particular option is all digit by checking (*end == '\0' || *end == ',') but that is done at the beginning of this loop anyway, so I don't think there is anything to check here.

> +		else
> +			die("Unknown --dirstat argument '%s'", p);
The function parses dirstat_OPT, but this says argument?
Previous: Johan HerlandNext: Johan Herland
Message 33 of 91 in “BUG? in --dirstat when rearranging lines in a file”
  1. Johan HerlandApr 7, 2011
  2. Linus TorvaldsApr 7, 2011
  3. Junio C HamanoApr 7, 2011
  4. Linus TorvaldsApr 7, 2011
  5. Johan HerlandApr 8, 2011
  6. 1/3 --dirstat: Document shortcomings compared to --stat or regular diffJohan Herland, Apr 8, 2011
  7. Junio C HamanoApr 8, 2011
  8. 2/3 --dirstat-by-file: Make it faster and more correctJohan Herland, Apr 8, 2011
  9. 3/3 Teach --dirstat to not completely ignore rearranged linesJohan Herland, Apr 8, 2011
  10. Linus TorvaldsApr 8, 2011
  11. Junio C HamanoApr 8, 2011
  12. 0/3 --dirstat fixesJohan Herland, Apr 10, 2011
  13. 1/3 --dirstat: Describe non-obvious differences relative to --stat or regular diffJohan Herland, Apr 10, 2011
  14. 2/3 --dirstat-by-file: Make it faster and more correctJohan Herland, Apr 10, 2011
  15. Junio C HamanoApr 11, 2011
  16. 3/3 Teach --dirstat to not completely ignore rearranged lines within a fileJohan Herland, Apr 10, 2011
  17. Junio C HamanoApr 11, 2011
  18. Johan HerlandApr 11, 2011
  19. Junio C HamanoApr 11, 2011
  20. Johan HerlandApr 12, 2011
  21. 4/3 --dirstat: In case of renames, use target filename instead of source filenameJohan Herland, Apr 12, 2011
  22. Linus TorvaldsApr 12, 2011
  23. 5/3 Alternative --dirstat implementation, based on diffstat analysisJohan Herland, Apr 12, 2011
  24. Linus TorvaldsApr 12, 2011
  25. Linus TorvaldsApr 12, 2011
  26. Johan HerlandApr 12, 2011
  27. Linus TorvaldsApr 12, 2011
  28. Junio C HamanoApr 12, 2011
  29. 0/6 --dirstat fixes, part 2Johan Herland, Apr 26, 2011
  30. 1/6 Add several testcases for --dirstat and friendsJohan Herland, Apr 26, 2011
  31. 2/6 Make --dirstat=0 output directories that contribute < 0.1% of changesJohan Herland, Apr 26, 2011
  32. 3/6 Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-fileJohan Herland, Apr 26, 2011
  33. Junio C HamanoApr 26, 2011
  34. Johan HerlandApr 27, 2011
  35. Junio C HamanoApr 27, 2011
  36. Junio C HamanoApr 27, 2011
  37. Junio C HamanoApr 27, 2011
  38. 4/6 Add config variable for specifying default --dirstat behaviorJohan Herland, Apr 26, 2011
  39. Junio C HamanoApr 26, 2011
  40. Johan HerlandApr 27, 2011
  41. 5/6 Use floating point for --dirstat percentagesJohan Herland, Apr 26, 2011
  42. Junio C HamanoApr 26, 2011
  43. Johan HerlandApr 27, 2011
  44. Junio C HamanoApr 27, 2011
  45. Linus TorvaldsApr 27, 2011
  46. Junio C HamanoApr 27, 2011
  47. 6/6 New --dirstat=lines mode, doing dirstat analysis based on diffstatJohan Herland, Apr 26, 2011
  48. Junio C HamanoApr 26, 2011
  49. Johan HerlandApr 27, 2011
  50. Linus TorvaldsApr 26, 2011
  51. 0/6 --dirstat fixes, part 2Johan Herland, Apr 27, 2011
  52. 1/6 Add several testcases for --dirstat and friendsJohan Herland, Apr 27, 2011
  53. 2/6 Make --dirstat=0 output directories that contribute < 0.1% of changesJohan Herland, Apr 27, 2011
  54. 3/6 Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-fileJohan Herland, Apr 27, 2011
  55. 4/6 Add config variable for specifying default --dirstat behaviorJohan Herland, Apr 27, 2011
  56. 5/6 Use floating point for --dirstat percentagesJohan Herland, Apr 27, 2011
  57. Linus TorvaldsApr 27, 2011
  58. 6/6 New --dirstat=lines mode, doing dirstat analysis based on diffstatJohan Herland, Apr 27, 2011
  59. 0/6 --dirstat fixes, part 2Johan Herland, Apr 27, 2011
  60. 1/6 Add several testcases for --dirstat and friendsJohan Herland, Apr 27, 2011
  61. 2/6 Make --dirstat=0 output directories that contribute < 0.1% of changesJohan Herland, Apr 27, 2011
  62. 3/6 Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-fileJohan Herland, Apr 27, 2011
  63. 4/6 Add config variable for specifying default --dirstat behaviorJohan Herland, Apr 27, 2011
  64. 5/6 Allow specifying --dirstat cut-off percentage as a floating point numberJohan Herland, Apr 27, 2011
  65. Linus TorvaldsApr 27, 2011
  66. 5/6 Allow specifying --dirstat cut-off percentage as a floating point numberJohan Herland, Apr 27, 2011
  67. 6/6 New --dirstat=lines mode, doing dirstat analysis based on diffstatJohan Herland, Apr 27, 2011
  68. 0/7 --dirstat fixes, part 2Johan Herland, Apr 28, 2011
  69. 1/7 Add several testcases for --dirstat and friendsJohan Herland, Apr 28, 2011
  70. 2/7 Make --dirstat=0 output directories that contribute < 0.1% of changesJohan Herland, Apr 28, 2011
  71. 3/7 Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-fileJohan Herland, Apr 28, 2011
  72. 4/7 Add config variable for specifying default --dirstat behaviorJohan Herland, Apr 28, 2011
  73. 5/7 Allow specifying --dirstat cut-off percentage as a floating point numberJohan Herland, Apr 28, 2011
  74. 6/7 New --dirstat=lines mode, doing dirstat analysis based on diffstatJohan Herland, Apr 28, 2011
  75. 7/7 Improve error handling when parsing dirstat parametersJohan Herland, Apr 28, 2011
  76. Junio C HamanoApr 28, 2011
  77. Junio C HamanoApr 28, 2011
  78. Johan HerlandApr 28, 2011
  79. Johan HerlandApr 28, 2011
  80. Junio C HamanoApr 29, 2011
  81. 0/8 --dirstat fixes, part 2Johan Herland, Apr 29, 2011
  82. 1/8 Add several testcases for --dirstat and friendsJohan Herland, Apr 29, 2011
  83. 2/8 Make --dirstat=0 output directories that contribute < 0.1% of changesJohan Herland, Apr 29, 2011
  84. 3/8 Refactor --dirstat parsing; deprecate --cumulative and --dirstat-by-fileJohan Herland, Apr 29, 2011
  85. 4/8 Add config variable for specifying default --dirstat behaviorJohan Herland, Apr 29, 2011
  86. 5/8 Allow specifying --dirstat cut-off percentage as a floating point numberJohan Herland, Apr 29, 2011
  87. 6/8 New --dirstat=lines mode, doing dirstat analysis based on diffstatJohan Herland, Apr 29, 2011
  88. 7/8 Improve error handling when parsing dirstat parametersJohan Herland, Apr 29, 2011
  89. 8/8 Mark dirstat error messages for translationJohan Herland, Apr 29, 2011
  90. Junio C HamanoApr 12, 2011
  91. Linus TorvaldsApr 10, 2011

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.