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;