}
}
-static char *pprint_rename(const char *a, const char *b)
+static void pprint_rename(struct strbuf *name, const char *a, const char *b)
{
const char *old = a;
const char *new = b;
- struct strbuf name = STRBUF_INIT;
int pfx_length, sfx_length;
int pfx_adjust_for_slash;
int len_a = strlen(a);
int qlen_b = quote_c_style(b, NULL, NULL, 0);
if (qlen_a || qlen_b) {
- quote_c_style(a, &name, NULL, 0);
- strbuf_addstr(&name, " => ");
- quote_c_style(b, &name, NULL, 0);
- return strbuf_detach(&name, NULL);
+ quote_c_style(a, name, NULL, 0);
+ strbuf_addstr(name, " => ");
+ quote_c_style(b, name, NULL, 0);
+ return;
}
/* Find common prefix */
if (b_midlen < 0)
b_midlen = 0;
- strbuf_grow(&name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
+ strbuf_grow(name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
if (pfx_length + sfx_length) {
- strbuf_add(&name, a, pfx_length);
- strbuf_addch(&name, '{');
+ strbuf_add(name, a, pfx_length);
+ strbuf_addch(name, '{');
}
- strbuf_add(&name, a + pfx_length, a_midlen);
- strbuf_addstr(&name, " => ");
- strbuf_add(&name, b + pfx_length, b_midlen);
+ strbuf_add(name, a + pfx_length, a_midlen);
+ strbuf_addstr(name, " => ");
+ strbuf_add(name, b + pfx_length, b_midlen);
if (pfx_length + sfx_length) {
- strbuf_addch(&name, '}');
- strbuf_add(&name, a + len_a - sfx_length, sfx_length);
+ strbuf_addch(name, '}');
+ strbuf_add(name, a + len_a - sfx_length, sfx_length);
}
- return strbuf_detach(&name, NULL);
}
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;
static void fill_print_name(struct diffstat_file *file)
{
- char *pname;
+ struct strbuf pname = STRBUF_INIT;
if (file->print_name)
return;
- if (!file->is_renamed) {
- struct strbuf buf = STRBUF_INIT;
- if (quote_c_style(file->name, &buf, NULL, 0)) {
- pname = strbuf_detach(&buf, NULL);
- } else {
- pname = file->name;
- strbuf_release(&buf);
- }
- } else {
- pname = pprint_rename(file->from_name, file->name);
- }
- file->print_name = pname;
+ if (file->is_renamed)
+ pprint_rename(&pname, file->from_name, file->name);
+ 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);
}
static void print_stat_summary_inserts_deletes(struct diff_options *options,
int i;
for (i = 0; i < diffstat->nr; i++) {
struct diffstat_file *f = diffstat->files[i];
- if (f->name != f->print_name)
- free(f->print_name);
+ free(f->print_name);
free(f->name);
free(f->from_name);
free(f);
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,
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;
options->output_format |= DIFF_FORMAT_NUMSTAT;
else if (!strcmp(arg, "--shortstat"))
options->output_format |= DIFF_FORMAT_SHORTSTAT;
- else if (!strcmp(arg, "-X") || !strcmp(arg, "--dirstat"))
- return parse_dirstat_opt(options, "");
- else if (skip_prefix(arg, "-X", &arg))
- return parse_dirstat_opt(options, arg);
- else if (skip_prefix(arg, "--dirstat=", &arg))
+ else if (skip_prefix(arg, "-X", &arg) ||
+ skip_to_optional_arg(arg, "--dirstat", &arg))
return parse_dirstat_opt(options, arg);
else if (!strcmp(arg, "--cumulative"))
return parse_dirstat_opt(options, "cumulative");
- else if (!strcmp(arg, "--dirstat-by-file"))
- return parse_dirstat_opt(options, "files");
- else if (skip_prefix(arg, "--dirstat-by-file=", &arg)) {
+ else if (skip_to_optional_arg(arg, "--dirstat-by-file", &arg)) {
parse_dirstat_opt(options, "files");
return parse_dirstat_opt(options, arg);
}
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") || starts_with(arg, "--break-rewrites=") ||
- !strcmp(arg, "--break-rewrites")) {
+ else if (starts_with(arg, "-B") ||
+ skip_to_optional_arg(arg, "--break-rewrites", NULL)) {
if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
return error("invalid argument to -B: %s", arg+2);
}
- else if (starts_with(arg, "-M") || starts_with(arg, "--find-renames=") ||
- !strcmp(arg, "--find-renames")) {
+ else if (starts_with(arg, "-M") ||
+ skip_to_optional_arg(arg, "--find-renames", NULL)) {
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return error("invalid argument to -M: %s", arg+2);
options->detect_rename = DIFF_DETECT_RENAME;
else if (!strcmp(arg, "-D") || !strcmp(arg, "--irreversible-delete")) {
options->irreversible_delete = 1;
}
- else if (starts_with(arg, "-C") || starts_with(arg, "--find-copies=") ||
- !strcmp(arg, "--find-copies")) {
+ else if (starts_with(arg, "-C") ||
+ skip_to_optional_arg(arg, "--find-copies", NULL)) {
if (options->detect_rename == DIFF_DETECT_COPY)
options->flags.find_copies_harder = 1;
if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
options->flags.rename_empty = 1;
else if (!strcmp(arg, "--no-rename-empty"))
options->flags.rename_empty = 0;
- else if (!strcmp(arg, "--relative"))
+ else if (skip_to_optional_arg_default(arg, "--relative", &arg, NULL)) {
options->flags.relative_name = 1;
- else if (skip_prefix(arg, "--relative=", &arg)) {
- options->flags.relative_name = 1;
- options->prefix = arg;
+ if (arg)
+ options->prefix = arg;
}
/* xdiff options */
else if (!strcmp(arg, "--no-follow")) {
options->flags.follow_renames = 0;
options->flags.default_follow_renames = 0;
- } else if (!strcmp(arg, "--color"))
- options->use_color = 1;
- else if (skip_prefix(arg, "--color=", &arg)) {
+ } else if (skip_to_optional_arg_default(arg, "--color", &arg, "always")) {
int value = git_config_colorbool(NULL, arg);
if (value < 0)
return error("option `color' expects \"always\", \"auto\", or \"never\"");
if (cm < 0)
die("bad --color-moved argument: %s", arg);
options->color_moved = cm;
- } else if (!strcmp(arg, "--color-words")) {
+ } else if (skip_to_optional_arg_default(arg, "--color-words", &options->word_regex, NULL)) {
options->use_color = 1;
options->word_diff = DIFF_WORDS_COLOR;
}
- else if (skip_prefix(arg, "--color-words=", &arg)) {
- options->use_color = 1;
- options->word_diff = DIFF_WORDS_COLOR;
- options->word_regex = arg;
- }
else if (!strcmp(arg, "--word-diff")) {
if (options->word_diff == DIFF_WORDS_NONE)
options->word_diff = DIFF_WORDS_PLAIN;
options->flags.textconv_set_via_cmdline = 1;
} else if (!strcmp(arg, "--no-textconv"))
options->flags.allow_textconv = 0;
- else if (!strcmp(arg, "--ignore-submodules")) {
- options->flags.override_submodule_config = 1;
- handle_ignore_submodules_arg(options, "all");
- } else if (skip_prefix(arg, "--ignore-submodules=", &arg)) {
+ else if (skip_to_optional_arg_default(arg, "--ignore-submodules", &arg, "all")) {
options->flags.override_submodule_config = 1;
handle_ignore_submodules_arg(options, arg);
- } else if (!strcmp(arg, "--submodule"))
- options->submodule_format = DIFF_SUBMODULE_LOG;
- else if (skip_prefix(arg, "--submodule=", &arg))
+ } else if (skip_to_optional_arg_default(arg, "--submodule", &arg, "log"))
return parse_submodule_opt(options, arg);
else if (skip_prefix(arg, "--ws-error-highlight=", &arg))
return parse_ws_error_highlight_opt(options, arg);
struct diff_filepair *p)
{
struct strbuf sb = STRBUF_INIT;
- char *names = pprint_rename(p->one->path, p->two->path);
+ struct strbuf names = STRBUF_INIT;
+
+ pprint_rename(&names, p->one->path, p->two->path);
strbuf_addf(&sb, " %s %s (%d%%)\n",
- renamecopy, names, similarity_index(p));
- free(names);
+ renamecopy, names.buf, similarity_index(p));
+ strbuf_release(&names);
emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
sb.buf, sb.len, 0);
show_mode_change(opt, p, 0);