Allow specifying --dirstat cut-off percentage as a floating point number
authorJohan Herland <johan@herland.net>
Fri, 29 Apr 2011 09:36:20 +0000 (11:36 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 29 Apr 2011 18:20:11 +0000 (11:20 -0700)
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>
diff.c
diff.h
t/t4047-diff-dirstat.sh

diff --git a/diff.c b/diff.c
index c78f7d5218def3d0546b636069107bc349d2c884..70464d9d642b316ffb8ab0365591dad8ca78f276 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -31,7 +31,7 @@ static const char *external_diff_cmd_cfg;
 int diff_auto_refresh_index = 1;
 static int diff_mnemonic_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 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);
                } else if (isdigit(*p)) {
                        char *end;
-                       options->dirstat_percent = strtoul(p, &end, 10);
+                       options->dirstat_permille = strtoul(p, &end, 10) * 10;
                        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
                        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")) {
-               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);
-               diff_dirstat_percent_default = default_diff_options.dirstat_percent;
+               diff_dirstat_permille_default = default_diff_options.dirstat_permille;
                return 0;
        }
 
@@ -1498,7 +1505,7 @@ struct dirstat_file {
 
 struct dirstat_dir {
        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,
@@ -1547,10 +1554,9 @@ static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir,
        if (baselen && sources != 1) {
                if (this_dir) {
                        int permille = this_dir * 1000 / changed;
-                       int percent = permille / 10;
-                       if (percent >= dir->percent) {
+                       if (permille >= dir->permille) {
                                fprintf(opt->file, "%s%4d.%01d%% %.*s\n", line_prefix,
-                                       percent, permille % 10, baselen, base);
+                                       permille / 10, permille % 10, baselen, base);
                                if (!dir->cumulative)
                                        return 0;
                        }
@@ -1576,7 +1582,7 @@ static void show_dirstat(struct diff_options *options)
        dir.files = NULL;
        dir.alloc = 0;
        dir.nr = 0;
-       dir.percent = options->dirstat_percent;
+       dir.permille = options->dirstat_permille;
        dir.cumulative = DIFF_OPT_TST(options, DIRSTAT_CUMULATIVE);
 
        changed = 0;
@@ -2934,7 +2940,7 @@ void diff_setup(struct diff_options *options)
        options->line_termination = '\n';
        options->break_opt = -1;
        options->rename_limit = -1;
-       options->dirstat_percent = diff_dirstat_percent_default;
+       options->dirstat_permille = diff_dirstat_permille_default;
        options->context = 3;
 
        options->change = diff_change;
diff --git a/diff.h b/diff.h
index 6fe1597785761b0e6961910214a129a2dde5197f..90f491e9e7d9ba279ab2e172c132f36d2582f283 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -114,7 +114,7 @@ struct diff_options {
        int needed_rename_limit;
        int degraded_cc_to_c;
        int show_rename_progress;
-       int dirstat_percent;
+       int dirstat_permille;
        int setup;
        int abbrev;
        const char *prefix;
index c1b3697bf70b39401a6650ed96d18849e99b6af3..4b25e10030c3b5f1dc222e30cfdf56e81845ec33 100755 (executable)
@@ -775,4 +775,68 @@ test_expect_success 'diff.dirstat=10,cumulative,files' '
        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