Allow specifying --dirstat cut-off percentage as a floating point number

Only the first digit after the decimal point is kept, as the dirstat
calculations all happen in permille.

Selftests verifying floating-point percentage input has been added.

Improved-by: Junio C Hamano <gitster@pobox.com>
Improved-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Johan Herland <johan@herland.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Johan Herland 2011-04-29 11:36:20 +02:00 committed by Junio C Hamano
parent 2d17495196
commit 712d2c7dd8
3 changed files with 81 additions and 11 deletions

26
diff.c
View File

@ -31,7 +31,7 @@ static const char *external_diff_cmd_cfg;
int diff_auto_refresh_index = 1; int diff_auto_refresh_index = 1;
static int diff_mnemonic_prefix; static int diff_mnemonic_prefix;
static int diff_no_prefix; static int diff_no_prefix;
static int diff_dirstat_percent_default = 3; static int diff_dirstat_permille_default = 30;
static struct diff_options default_diff_options; static struct diff_options default_diff_options;


static char diff_colors[][COLOR_MAXLEN] = { static char diff_colors[][COLOR_MAXLEN] = {
@ -85,8 +85,15 @@ static int parse_dirstat_params(struct diff_options *options, const char *params
DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE); DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
} else if (isdigit(*p)) { } else if (isdigit(*p)) {
char *end; char *end;
options->dirstat_percent = strtoul(p, &end, 10); options->dirstat_permille = strtoul(p, &end, 10) * 10;
p = end; p = end;
if (*p == '.' && isdigit(*++p)) {
/* only use first digit */
options->dirstat_permille += *p - '0';
/* .. and ignore any further digits */
while (isdigit(*++p))
; /* nothing */
}
} else } else
return error("Unknown --dirstat parameter '%s'", p); return error("Unknown --dirstat parameter '%s'", p);


@ -182,9 +189,9 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
} }


if (!strcmp(var, "diff.dirstat")) { if (!strcmp(var, "diff.dirstat")) {
default_diff_options.dirstat_percent = diff_dirstat_percent_default; default_diff_options.dirstat_permille = diff_dirstat_permille_default;
(void) parse_dirstat_params(&default_diff_options, value); (void) parse_dirstat_params(&default_diff_options, value);
diff_dirstat_percent_default = default_diff_options.dirstat_percent; diff_dirstat_permille_default = default_diff_options.dirstat_permille;
return 0; return 0;
} }


@ -1498,7 +1505,7 @@ struct dirstat_file {


struct dirstat_dir { struct dirstat_dir {
struct dirstat_file *files; struct dirstat_file *files;
int alloc, nr, percent, cumulative; int alloc, nr, permille, cumulative;
}; };


static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir, static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir,
@ -1547,10 +1554,9 @@ static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir,
if (baselen && sources != 1) { if (baselen && sources != 1) {
if (this_dir) { if (this_dir) {
int permille = this_dir * 1000 / changed; int permille = this_dir * 1000 / changed;
int percent = permille / 10; if (permille >= dir->permille) {
if (percent >= dir->percent) {
fprintf(opt->file, "%s%4d.%01d%% %.*s\n", line_prefix, fprintf(opt->file, "%s%4d.%01d%% %.*s\n", line_prefix,
percent, permille % 10, baselen, base); permille / 10, permille % 10, baselen, base);
if (!dir->cumulative) if (!dir->cumulative)
return 0; return 0;
} }
@ -1576,7 +1582,7 @@ static void show_dirstat(struct diff_options *options)
dir.files = NULL; dir.files = NULL;
dir.alloc = 0; dir.alloc = 0;
dir.nr = 0; dir.nr = 0;
dir.percent = options->dirstat_percent; dir.permille = options->dirstat_permille;
dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE); dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE);


changed = 0; changed = 0;
@ -2934,7 +2940,7 @@ void diff_setup(struct diff_options *options)
options->line_termination = '\n'; options->line_termination = '\n';
options->break_opt = -1; options->break_opt = -1;
options->rename_limit = -1; options->rename_limit = -1;
options->dirstat_percent = diff_dirstat_percent_default; options->dirstat_permille = diff_dirstat_permille_default;
options->context = 3; options->context = 3;


options->change = diff_change; options->change = diff_change;

2
diff.h
View File

@ -114,7 +114,7 @@ struct diff_options {
int needed_rename_limit; int needed_rename_limit;
int degraded_cc_to_c; int degraded_cc_to_c;
int show_rename_progress; int show_rename_progress;
int dirstat_percent; int dirstat_permille;
int setup; int setup;
int abbrev; int abbrev;
const char *prefix; const char *prefix;

View File

@ -775,4 +775,68 @@ test_expect_success 'diff.dirstat=10,cumulative,files' '
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
' '


cat <<EOF >expect_diff_dirstat
27.2% dst/copy/
27.2% dst/move/
54.5% dst/
27.2% src/move/
EOF

cat <<EOF >expect_diff_dirstat_M
42.8% dst/copy/
28.5% dst/move/
71.4% dst/
EOF

cat <<EOF >expect_diff_dirstat_CC
33.3% dst/copy/
33.3% dst/move/
66.6% dst/
EOF

test_expect_success '--dirstat=files,cumulative,16.7' '
git diff --dirstat=files,cumulative,16.7 HEAD^..HEAD >actual_diff_dirstat &&
test_cmp expect_diff_dirstat actual_diff_dirstat &&
git diff --dirstat=files,cumulative,16.7 -M HEAD^..HEAD >actual_diff_dirstat_M &&
test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
git diff --dirstat=files,cumulative,16.7 -C -C HEAD^..HEAD >actual_diff_dirstat_CC &&
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
'

test_expect_success 'diff.dirstat=16.7,cumulative,files' '
git -c diff.dirstat=16.7,cumulative,files diff --dirstat HEAD^..HEAD >actual_diff_dirstat &&
test_cmp expect_diff_dirstat actual_diff_dirstat &&
git -c diff.dirstat=16.7,cumulative,files diff --dirstat -M HEAD^..HEAD >actual_diff_dirstat_M &&
test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
git -c diff.dirstat=16.7,cumulative,files diff --dirstat -C -C HEAD^..HEAD >actual_diff_dirstat_CC &&
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
'

test_expect_success 'diff.dirstat=16.70,cumulative,files' '
git -c diff.dirstat=16.70,cumulative,files diff --dirstat HEAD^..HEAD >actual_diff_dirstat &&
test_cmp expect_diff_dirstat actual_diff_dirstat &&
git -c diff.dirstat=16.70,cumulative,files diff --dirstat -M HEAD^..HEAD >actual_diff_dirstat_M &&
test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
git -c diff.dirstat=16.70,cumulative,files diff --dirstat -C -C HEAD^..HEAD >actual_diff_dirstat_CC &&
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
'

test_expect_success '--dirstat=files,cumulative,27.2' '
git diff --dirstat=files,cumulative,27.2 HEAD^..HEAD >actual_diff_dirstat &&
test_cmp expect_diff_dirstat actual_diff_dirstat &&
git diff --dirstat=files,cumulative,27.2 -M HEAD^..HEAD >actual_diff_dirstat_M &&
test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
git diff --dirstat=files,cumulative,27.2 -C -C HEAD^..HEAD >actual_diff_dirstat_CC &&
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
'

test_expect_success '--dirstat=files,cumulative,27.09' '
git diff --dirstat=files,cumulative,27.09 HEAD^..HEAD >actual_diff_dirstat &&
test_cmp expect_diff_dirstat actual_diff_dirstat &&
git diff --dirstat=files,cumulative,27.09 -M HEAD^..HEAD >actual_diff_dirstat_M &&
test_cmp expect_diff_dirstat_M actual_diff_dirstat_M &&
git diff --dirstat=files,cumulative,27.09 -C -C HEAD^..HEAD >actual_diff_dirstat_CC &&
test_cmp expect_diff_dirstat_CC actual_diff_dirstat_CC
'

test_done test_done