From: Junio C Hamano Date: Fri, 28 Aug 2015 19:32:17 +0000 (-0700) Subject: Merge branch 'cc/trailers-corner-case-fix' X-Git-Tag: v2.6.0-rc0~28 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/483c9b8602eb2f4261d135c4332c4c48fa7eb8f6?ds=inline;hp=-c Merge branch 'cc/trailers-corner-case-fix' "interpret-trailers" helper mistook a single-liner log message that has a colon as the end of existing trailer. * cc/trailers-corner-case-fix: trailer: retitle a test and correct an in-comment message trailer: ignore first line of message --- 483c9b8602eb2f4261d135c4332c4c48fa7eb8f6 diff --combined t/t7513-interpret-trailers.sh index bd0ab46750,8f1f55be25..9577b4effb --- a/t/t7513-interpret-trailers.sh +++ b/t/t7513-interpret-trailers.sh @@@ -93,12 -93,25 +93,25 @@@ test_expect_success 'with config optio Acked-by: Johan Reviewed-by: Peff EOF - echo "Acked-by: Johan" | + { echo; echo "Acked-by: Johan"; } | git -c "trailer.Acked-by.ifexists=addifdifferent" interpret-trailers \ --trailer "Reviewed-by: Peff" --trailer "Acked-by: Johan" >actual && test_cmp expected actual ' + test_expect_success 'with only a title in the message' ' + cat >expected <<-\EOF && + area: change + + Reviewed-by: Peff + Acked-by: Johan + EOF + echo "area: change" | + git interpret-trailers --trailer "Reviewed-by: Peff" \ + --trailer "Acked-by: Johan" >actual && + test_cmp expected actual + ' + test_expect_success 'with config setup' ' git config trailer.ack.key "Acked-by: " && cat >expected <<-\EOF && @@@ -213,7 -226,7 +226,7 @@@ test_expect_success 'with 2 files argum ' test_expect_success 'with message that has comments' ' - cat basic_message >>message_with_comments && + cat basic_message >message_with_comments && sed -e "s/ Z\$/ /" >>message_with_comments <<-\EOF && # comment @@@ -232,44 -245,12 +245,44 @@@ Reviewed-by: Johan Cc: Peff + # last comment + EOF cat basic_patch >>expected && git interpret-trailers --trim-empty --trailer "Cc: Peff" message_with_comments >actual && test_cmp expected actual ' +test_expect_success 'with message that has an old style conflict block' ' + cat basic_message >message_with_comments && + sed -e "s/ Z\$/ /" >>message_with_comments <<-\EOF && + # comment + + # other comment + Cc: Z + # yet another comment + Reviewed-by: Johan + Reviewed-by: Z + # last comment + + Conflicts: + + EOF + cat basic_message >expected && + cat >>expected <<-\EOF && + # comment + + Reviewed-by: Johan + Cc: Peff + # last comment + + Conflicts: + + EOF + git interpret-trailers --trim-empty --trailer "Cc: Peff" message_with_comments >actual && + test_cmp expected actual +' + test_expect_success 'with commit complex message and trailer args' ' cat complex_message_body >expected && sed -e "s/ Z\$/ /" >>expected <<-\EOF && diff --combined trailer.c index 4b14a567b4,a92ba53fa5..b8088687d4 --- a/trailer.c +++ b/trailer.c @@@ -1,7 -1,7 +1,7 @@@ #include "cache.h" #include "string-list.h" #include "run-command.h" -#include "string-list.h" +#include "commit.h" #include "trailer.h" /* * Copyright (c) 2013, 2014 Christian Couder @@@ -214,6 -214,16 +214,6 @@@ static struct trailer_item *remove_firs return item; } -static int read_from_command(struct child_process *cp, struct strbuf *buf) -{ - if (run_command(cp)) - return error("running trailer command '%s' failed", cp->argv[0]); - if (strbuf_read(buf, cp->out, 1024) < 1) - return error("reading from trailer command '%s' failed", cp->argv[0]); - strbuf_trim(buf); - return 0; -} - static const char *apply_command(const char *command, const char *arg) { struct strbuf cmd = STRBUF_INIT; @@@ -230,16 -240,14 +230,16 @@@ cp.argv = argv; cp.env = local_repo_env; cp.no_stdin = 1; - cp.out = -1; cp.use_shell = 1; - if (read_from_command(&cp, &buf)) { + if (capture_command(&cp, &buf, 1024)) { + error("running trailer command '%s' failed", cmd.buf); strbuf_release(&buf); result = xstrdup(""); - } else + } else { + strbuf_trim(&buf); result = strbuf_detach(&buf, NULL); + } strbuf_release(&cmd); return result; @@@ -740,8 -748,10 +740,10 @@@ static int find_trailer_start(struct st /* * Get the start of the trailers by looking starting from the end * for a line with only spaces before lines with one separator. + * The first line must not be analyzed as the others as it + * should be either the message title or a blank line. */ - for (start = count - 1; start >= 0; start--) { + for (start = count - 1; start >= 1; start--) { if (lines[start]->buf[0] == comment_line_char) continue; if (contains_only_spaces(lines[start]->buf)) { @@@ -760,22 -770,6 +762,22 @@@ return only_spaces ? count : 0; } +/* Get the index of the end of the trailers */ +static int find_trailer_end(struct strbuf **lines, int patch_start) +{ + struct strbuf sb = STRBUF_INIT; + int i, ignore_bytes; + + for (i = 0; i < patch_start; i++) + strbuf_addbuf(&sb, lines[i]); + ignore_bytes = ignore_non_trailer(&sb); + strbuf_release(&sb); + for (i = patch_start - 1; i >= 0 && ignore_bytes > 0; i--) + ignore_bytes -= lines[i]->len; + + return i + 1; +} + static int has_blank_line_before(struct strbuf **lines, int start) { for (;start >= 0; start--) { @@@ -798,15 -792,14 +800,15 @@@ static int process_input_file(struct st struct trailer_item **in_tok_last) { int count = 0; - int patch_start, trailer_start, i; + int patch_start, trailer_start, trailer_end, i; /* Get the line count */ while (lines[count]) count++; patch_start = find_patch_start(lines, count); - trailer_start = find_trailer_start(lines, patch_start); + trailer_end = find_trailer_end(lines, patch_start); + trailer_start = find_trailer_start(lines, trailer_end); /* Print lines before the trailers as is */ print_lines(lines, 0, trailer_start); @@@ -815,14 -808,14 +817,14 @@@ printf("\n"); /* Parse trailer lines */ - for (i = trailer_start; i < patch_start; i++) { + for (i = trailer_start; i < trailer_end; i++) { if (lines[i]->buf[0] != comment_line_char) { struct trailer_item *new = create_trailer_item(lines[i]->buf); add_trailer_item(in_tok_first, in_tok_last, new); } } - return patch_start; + return trailer_end; } static void free_all(struct trailer_item **first) @@@ -839,7 -832,7 +841,7 @@@ void process_trailers(const char *file struct trailer_item *in_tok_last = NULL; struct trailer_item *arg_tok_first; struct strbuf **lines; - int patch_start; + int trailer_end; /* Default config must be setup first */ git_config(git_trailer_default_config, NULL); @@@ -848,7 -841,7 +850,7 @@@ lines = read_input_file(file); /* Print the lines before the trailers */ - patch_start = process_input_file(lines, &in_tok_first, &in_tok_last); + trailer_end = process_input_file(lines, &in_tok_first, &in_tok_last); arg_tok_first = process_command_line_args(trailers); @@@ -859,7 -852,7 +861,7 @@@ free_all(&in_tok_first); /* Print the lines after the trailers as is */ - print_lines(lines, patch_start, INT_MAX); + print_lines(lines, trailer_end, INT_MAX); strbuf_list_free(lines); }