Skip to content

Commit b18d702

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 af88cba commit b18d702

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
@@ -348,6 +348,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
348348

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

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

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

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

0 commit comments

Comments
 (0)