tag: fix output of "tag -n" when errors occur

When "git tag" is instructed to print lines from annotated tags via "-n", it first prints the tag name, then attempts to parse and print the lines of the tag object, and then finally adds a trailing newline. If an error occurs, we return early from the function and never print the newline, screwing up the output for the next tag. Let's factor the line-printing into its own function so we can manage the early returns better, and make sure that we always terminate the line. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Feb 6, 2012 at 03:13 UTC ca51699961664890fdaabd276af539e6b3514053
1 file changed +34 -32
builtin/tag.c
+34 -32
@@ -84,18 +84,45 @@ static int contains(struct commit *candidate, const struct commit_list *want)
84 return contains_recurse(candidate, want);
85 }
86
87 +static void show_tag_lines(const unsigned char *sha1, int lines)
88 +{
89 + int i;
90 + unsigned long size;
91 + enum object_type type;
92 + char *buf, *sp, *eol;
93 + size_t len;
94 +
95 + buf = read_sha1_file(sha1, &type, &size);
96 + if (!buf || !size)
97 + return;
98 +
99 + /* skip header */
100 + sp = strstr(buf, "\n\n");
101 + if (!sp) {
102 + free(buf);
103 + return;
104 + }
105 + /* only take up to "lines" lines, and strip the signature */
106 + size = parse_signature(buf, size);
107 + for (i = 0, sp += 2; i < lines && sp < buf + size; i++) {
108 + if (i)
109 + printf("\n ");
110 + eol = memchr(sp, '\n', size - (sp - buf));
111 + len = eol ? eol - sp : size - (sp - buf);
112 + fwrite(sp, len, 1, stdout);
113 + if (!eol)
114 + break;
115 + sp = eol + 1;
116 + }
117 + free(buf);
118 +}
119 +
120 static int show_reference(const char *refname, const unsigned char *sha1,
121 int flag, void *cb_data)
122 {
123 struct tag_filter *filter = cb_data;
124
125 if (match_pattern(filter->patterns, refname)) {
93 - int i;
94 - unsigned long size;
95 - enum object_type type;
96 - char *buf, *sp, *eol;
97 - size_t len;
98 -
126 if (filter->with_commit) {
127 struct commit *commit;
128
@@ -111,33 +138,8 @@ static int show_reference(const char *refname, const unsigned char *sha1,
138 return 0;
139 }
140 printf("%-15s ", refname);
114 -
115 - buf = read_sha1_file(sha1, &type, &size);
116 - if (!buf || !size)
117 - return 0;
118 -
119 - /* skip header */
120 - sp = strstr(buf, "\n\n");
121 - if (!sp) {
122 - free(buf);
123 - return 0;
124 - }
125 - /* only take up to "lines" lines, and strip the signature */
126 - size = parse_signature(buf, size);
127 - for (i = 0, sp += 2;
128 - i < filter->lines && sp < buf + size;
129 - i++) {
130 - if (i)
131 - printf("\n ");
132 - eol = memchr(sp, '\n', size - (sp - buf));
133 - len = eol ? eol - sp : size - (sp - buf);
134 - fwrite(sp, len, 1, stdout);
135 - if (!eol)
136 - break;
137 - sp = eol + 1;
138 - }
141 + show_tag_lines(sha1, filter->lines);
142 putchar('\n');
140 - free(buf);
143 }
144
145 return 0;