diff: add --compact-summary
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index c0b75de45f7b1f0b60eea11807e637f238247487..95124c0e7c2a0da04199c51d5c2393167ce695a3 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2129,6 +2129,7 @@ struct diffstat_t {
                char *from_name;
                char *name;
                char *print_name;
+               const char *comments;
                unsigned is_unmerged:1;
                unsigned is_binary:1;
                unsigned is_renamed:1;
@@ -2205,6 +2206,9 @@ static void fill_print_name(struct diffstat_file *file)
        else
                quote_c_style(file->name, &pname, NULL, 0);
 
+       if (file->comments)
+               strbuf_addf(&pname, " (%s)", file->comments);
+
        file->print_name = strbuf_detach(&pname, NULL);
 }
 
@@ -3239,6 +3243,32 @@ static void builtin_diff(const char *name_a,
        return;
 }
 
+static char *get_compact_summary(const struct diff_filepair *p, int is_renamed)
+{
+       if (!is_renamed) {
+               if (p->status == DIFF_STATUS_ADDED) {
+                       if (S_ISLNK(p->two->mode))
+                               return "new +l";
+                       else if ((p->two->mode & 0777) == 0755)
+                               return "new +x";
+                       else
+                               return "new";
+               } else if (p->status == DIFF_STATUS_DELETED)
+                       return "gone";
+       }
+       if (S_ISLNK(p->one->mode) && !S_ISLNK(p->two->mode))
+               return "mode -l";
+       else if (!S_ISLNK(p->one->mode) && S_ISLNK(p->two->mode))
+               return "mode +l";
+       else if ((p->one->mode & 0777) == 0644 &&
+                (p->two->mode & 0777) == 0755)
+               return "mode +x";
+       else if ((p->one->mode & 0777) == 0755 &&
+                (p->two->mode & 0777) == 0644)
+               return "mode -x";
+       return NULL;
+}
+
 static void builtin_diffstat(const char *name_a, const char *name_b,
                             struct diff_filespec *one,
                             struct diff_filespec *two,
@@ -3258,6 +3288,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
 
        data = diffstat_add(diffstat, name_a, name_b);
        data->is_interesting = p->status != DIFF_STATUS_UNKNOWN;
+       if (o->flags.stat_with_summary)
+               data->comments = get_compact_summary(p, data->is_renamed);
 
        if (!one || !two) {
                data->is_unmerged = 1;
@@ -4528,6 +4560,11 @@ int diff_opt_parse(struct diff_options *options,
        else if (starts_with(arg, "--stat"))
                /* --stat, --stat-width, --stat-name-width, or --stat-count */
                return stat_opt(options, av);
+       else if (!strcmp(arg, "--compact-summary")) {
+                options->flags.stat_with_summary = 1;
+                options->output_format |= DIFF_FORMAT_DIFFSTAT;
+       } else if (!strcmp(arg, "--no-compact-summary"))
+                options->flags.stat_with_summary = 0;
 
        /* renames options */
        else if (starts_with(arg, "-B") ||