With --color-words, following example will show deleted word "bar" at another line. (<r> represents red) $ git diff - foo bar + foo $ git diff --color-words foo <r>bar</r> This is caused by the unsymmetrical handling of LF in the plus and minus buffer in fn_out_diff_words_aux. Assume "trailing minus (or plus) word" represents the last word (with real LF following it) in a line of the minus (or plus) buffer. Following is original unsymmetrical handling rules where LF represents a LF will be shown there. - trailing minus word, [plus word, ...], LF, non plus word - trailing plus word, LF, any word The second rule causes any word following the trailing plus word will be shown in a different line. This patch tries to implement the symmetrical handling rules: - trailing minus word, [plus word, ...], LF, non plus word - trailing plus word, [minus word, ...], LF, non minus word Signed-off-by: Ping Yin <pkufranky@xxxxxxxxx> --- diff.c | 21 ++++++++++++++------- 1 files changed, 14 insertions(+), 7 deletions(-) diff --git a/diff.c b/diff.c index 05f7c35..c7a0d77 100644 --- a/diff.c +++ b/diff.c @@ -409,6 +409,7 @@ static void print_word(FILE *file, struct diff_words_buffer *buffer, int len, in static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len) { struct diff_words_data *diff_words; + char lastchar_minus; struct diff_words_buffer *dwb_minus, *dwb_plus; FILE *outfile; @@ -417,10 +418,11 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len) dwb_plus = &(diff_words->plus); outfile = diff_words->file; - if (dwp_minus->suppressed_newline) { - if (line[0] != '+') - putc('\n', outfile); - dwp_minus->suppressed_newline = 0; + if ((dwb_minus->suppressed_newline && line[0] != '+') || + (dwb_plus->suppressed_newline && line[0] != '-')) { + putc('\n', outfile); + dwb_minus->suppressed_newline = 0; + dwb_plus->suppressed_newline = 0; } len--; @@ -429,11 +431,14 @@ static void fn_out_diff_words_aux(void *priv, char *line, unsigned long len) print_word(outfile, dwb_minus, len, DIFF_FILE_OLD, 1); break; case '+': - print_word(outfile, dwb_plus, len, DIFF_FILE_NEW, 0); + print_word(outfile, dwb_plus, len, DIFF_FILE_NEW, 1); break; case ' ': - print_word(outfile, dwb_plus, len, DIFF_PLAIN, 0); + lastchar_minus = dwb_minus->text.ptr[dwb_minus->current + len - 1]; + print_word(outfile, dwb_plus, len, DIFF_PLAIN, 1); dwb_minus->current += len; + if (lastchar_minus == '\n') + dwb_minus->suppressed_newline = 1; break; } } @@ -474,9 +479,11 @@ static void diff_words_show(struct diff_words_data *diff_words) free(plus.ptr); diff_words->minus.text.size = diff_words->plus.text.size = 0; - if (diff_words->minus.suppressed_newline) { + if (diff_words->minus.suppressed_newline || + diff_words->plus.suppressed_newline) { putc('\n', diff_words->file); diff_words->minus.suppressed_newline = 0; + diff_words->plus.suppressed_newline = 0; } } -- 1.5.5.1.121.g26b3 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html