Skip to content

Commit e9bd93a

Browse files
committed
built-in add -p: support interactive.diffFilter
The Perl version supports post-processing the colored diff (that is generated in addition to the uncolored diff, intended to offer a prettier user experience) by a command configured via that config setting, and now the built-in version does that, too. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent d858409 commit e9bd93a

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

add-interactive.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ int init_add_i_state(struct repository *r, struct add_i_state *s)
5656
strlcpy(s->file_new_color,
5757
diff_get_color(s->use_color, DIFF_FILE_NEW), COLOR_MAXLEN);
5858

59+
free(s->interactive_diff_filter);
60+
if (git_config_get_string("interactive.difffilter",
61+
&s->interactive_diff_filter))
62+
s->interactive_diff_filter = NULL;
5963

6064
return 0;
6165
}

add-interactive.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ struct add_i_state {
1515
char context_color[COLOR_MAXLEN];
1616
char file_old_color[COLOR_MAXLEN];
1717
char file_new_color[COLOR_MAXLEN];
18+
19+
char *interactive_diff_filter;
1820
};
1921

2022
int init_add_i_state(struct repository *r, struct add_i_state *s);
@@ -27,6 +29,7 @@ enum color_add_i {
2729
COLOR_RESET,
2830
};
2931
const char *get_add_i_color(enum color_add_i ix);
32+
const char *get_interactive_diff_filter(void);
3033

3134
struct repository;
3235
struct pathspec;

add-patch.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
347347

348348
if (want_color_fd(1, -1)) {
349349
struct child_process colored_cp = CHILD_PROCESS_INIT;
350+
const char *diff_filter = s->s.interactive_diff_filter;
350351

351352
setup_child_process(&colored_cp, s, NULL);
352353
xsnprintf((char *)args.argv[color_arg_index], 8, "--color");
@@ -356,6 +357,24 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
356357
argv_array_clear(&args);
357358
if (res)
358359
return error(_("could not parse colored diff"));
360+
361+
if (diff_filter) {
362+
struct child_process filter_cp = CHILD_PROCESS_INIT;
363+
364+
setup_child_process(&filter_cp, s,
365+
diff_filter, NULL);
366+
filter_cp.git_cmd = 0;
367+
filter_cp.use_shell = 1;
368+
strbuf_reset(&s->buf);
369+
if (pipe_command(&filter_cp,
370+
colored->buf, colored->len,
371+
&s->buf, colored->len,
372+
NULL, 0) < 0)
373+
return error(_("failed to run '%s'"),
374+
diff_filter);
375+
strbuf_swap(colored, &s->buf);
376+
}
377+
359378
strbuf_complete_line(colored);
360379
colored_p = colored->buf;
361380
colored_pend = colored_p + colored->len;
@@ -457,6 +476,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
457476
colored_pend - colored_p);
458477
if (colored_eol)
459478
colored_p = colored_eol + 1;
479+
else if (p != pend)
480+
/* colored shorter than non-colored? */
481+
goto mismatched_output;
460482
else
461483
colored_p = colored_pend;
462484

@@ -478,6 +500,15 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
478500
*/
479501
hunk->splittable_into++;
480502

503+
/* non-colored shorter than colored? */
504+
if (colored_p != colored_pend) {
505+
mismatched_output:
506+
error(_("mismatched output from interactive.diffFilter"));
507+
advise(_("Your filter must maintain a one-to-one correspondence\n"
508+
"between its input and output lines."));
509+
return -1;
510+
}
511+
481512
return 0;
482513
}
483514

0 commit comments

Comments
 (0)