@matheusbsbs / matheus-bagliano / commits / 180f48df69
Fork 0

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 <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jan 14, 2020 at 18:43 UTC 180f48df69d8e7a1a413d7c11907ecf975f09cf7
3 files changed +48
add-interactive.c
+12
@@ -52,6 +52,17 @@ void init_add_i_state(struct add_i_state *s, struct repository *r)
52 diff_get_color(s->use_color, DIFF_FILE_OLD));
53 init_color(r, s, "new", s->file_new_color,
54 diff_get_color(s->use_color, DIFF_FILE_NEW));
55 +
56 + FREE_AND_NULL(s->interactive_diff_filter);
57 + git_config_get_string("interactive.difffilter",
58 + &s->interactive_diff_filter);
59 +}
60 +
61 +void clear_add_i_state(struct add_i_state *s)
62 +{
63 + FREE_AND_NULL(s->interactive_diff_filter);
64 + memset(s, 0, sizeof(*s));
65 + s->use_color = -1;
66 }
67
68 /*
@@ -1149,6 +1160,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps)
1160 strbuf_release(&print_file_item_data.worktree);
1161 strbuf_release(&header);
1162 prefix_item_list_clear(&commands);
1163 + clear_add_i_state(&s);
1164
1165 return res;
1166 }
add-interactive.h
+3
@@ -15,9 +15,12 @@ struct add_i_state {
15 char context_color[COLOR_MAXLEN];
16 char file_old_color[COLOR_MAXLEN];
17 char file_new_color[COLOR_MAXLEN];
18 +
19 + char *interactive_diff_filter;
20 };
21
22 void init_add_i_state(struct add_i_state *s, struct repository *r);
23 +void clear_add_i_state(struct add_i_state *s);
24
25 struct repository;
26 struct pathspec;
add-patch.c
+33
@@ -398,6 +398,7 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
398
399 if (want_color_fd(1, -1)) {
400 struct child_process colored_cp = CHILD_PROCESS_INIT;
401 + const char *diff_filter = s->s.interactive_diff_filter;
402
403 setup_child_process(s, &colored_cp, NULL);
404 xsnprintf((char *)args.argv[color_arg_index], 8, "--color");
@@ -407,6 +408,24 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
408 argv_array_clear(&args);
409 if (res)
410 return error(_("could not parse colored diff"));
411 +
412 + if (diff_filter) {
413 + struct child_process filter_cp = CHILD_PROCESS_INIT;
414 +
415 + setup_child_process(s, &filter_cp,
416 + diff_filter, NULL);
417 + filter_cp.git_cmd = 0;
418 + filter_cp.use_shell = 1;
419 + strbuf_reset(&s->buf);
420 + if (pipe_command(&filter_cp,
421 + colored->buf, colored->len,
422 + &s->buf, colored->len,
423 + NULL, 0) < 0)
424 + return error(_("failed to run '%s'"),
425 + diff_filter);
426 + strbuf_swap(colored, &s->buf);
427 + }
428 +
429 strbuf_complete_line(colored);
430 colored_p = colored->buf;
431 colored_pend = colored_p + colored->len;
@@ -531,6 +550,9 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
550 colored_pend - colored_p);
551 if (colored_eol)
552 colored_p = colored_eol + 1;
553 + else if (p != pend)
554 + /* colored shorter than non-colored? */
555 + goto mismatched_output;
556 else
557 colored_p = colored_pend;
558
@@ -555,6 +577,15 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
577 */
578 hunk->splittable_into++;
579
580 + /* non-colored shorter than colored? */
581 + if (colored_p != colored_pend) {
582 +mismatched_output:
583 + error(_("mismatched output from interactive.diffFilter"));
584 + advise(_("Your filter must maintain a one-to-one correspondence\n"
585 + "between its input and output lines."));
586 + return -1;
587 + }
588 +
589 return 0;
590 }
591
@@ -1612,6 +1643,7 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
1643 parse_diff(&s, ps) < 0) {
1644 strbuf_release(&s.plain);
1645 strbuf_release(&s.colored);
1646 + clear_add_i_state(&s.s);
1647 return -1;
1648 }
1649
@@ -1630,5 +1662,6 @@ int run_add_p(struct repository *r, enum add_p_mode mode,
1662 strbuf_release(&s.buf);
1663 strbuf_release(&s.plain);
1664 strbuf_release(&s.colored);
1665 + clear_add_i_state(&s.s);
1666 return 0;
1667 }