#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 <chriscool@tuxfamily.org>
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;
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;
*/
static int find_trailer_start(struct strbuf **lines, int count)
{
- int start, only_spaces = 1;
+ int start, end_of_title, only_spaces = 1;
+
+ /* The first paragraph is the title and cannot be trailers */
+ for (start = 0; start < count; start++) {
+ if (lines[start]->buf[0] == comment_line_char)
+ continue;
+ if (contains_only_spaces(lines[start]->buf))
+ break;
+ }
+ end_of_title = start;
/*
* 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 >= 1; start--) {
+ for (start = count - 1; start >= end_of_title; start--) {
if (lines[start]->buf[0] == comment_line_char)
continue;
if (contains_only_spaces(lines[start]->buf)) {
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--) {
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);
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)
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);
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);
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);
}