Skip to content

Commit ca51699

Browse files
peffgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f174a25 commit ca51699

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

builtin/tag.c

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,45 @@ static int contains(struct commit *candidate, const struct commit_list *want)
8484
return contains_recurse(candidate, want);
8585
}
8686

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+
87120
static int show_reference(const char *refname, const unsigned char *sha1,
88121
int flag, void *cb_data)
89122
{
90123
struct tag_filter *filter = cb_data;
91124

92125
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-
99126
if (filter->with_commit) {
100127
struct commit *commit;
101128

@@ -111,33 +138,8 @@ static int show_reference(const char *refname, const unsigned char *sha1,
111138
return 0;
112139
}
113140
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);
139142
putchar('\n');
140-
free(buf);
141143
}
142144

143145
return 0;

0 commit comments

Comments
 (0)