On Sat, Sep 5, 2015 at 10:52 AM, Rudy Matela <[email protected]> wrote:
>
> Allow -n and --sort=version:refname to be used together
> instead of failing with:
>
> fatal: --sort and -n are incompatible
>
> Signed-off-by: Rudy Matela <[email protected]>
Nice! I've been wondering about this one for a while. Especially since
implementing tag.sort configuration which made -n not work at all.
Note that it may be worth rebasing this on top of Karthik's part tag
to use ref-filter series, since I think there will be plenty of merge
conflicts there...
I also suggest adding some tests for this, as sort and -n didn't even
have a test before, but now we could add a test that shows it works.
> ---
> builtin/tag.c | 64
> ++++++++++++++++++++++++++++++++---------------------------
> 1 file changed, 35 insertions(+), 29 deletions(-)
>
> diff --git a/builtin/tag.c b/builtin/tag.c
> index cccca99..cdcb373 100644
> --- a/builtin/tag.c
> +++ b/builtin/tag.c
> @@ -176,13 +176,19 @@ static enum contains_result contains(struct commit
> *candidate,
> return contains_test(candidate, want);
> }
>
> -static void show_tag_lines(const struct object_id *oid, int lines)
> +static char *get_tag_lines(const struct object_id *oid, int lines)
> {
> int i;
> unsigned long size;
> enum object_type type;
> char *buf, *sp, *eol;
> size_t len;
> + struct strbuf sb;
> +
> + if (!lines)
> + return NULL;
> +
> + strbuf_init(&sb,0);
>
> buf = read_sha1_file(oid->hash, &type, &size);
> if (!buf)
> @@ -203,20 +209,21 @@ static void show_tag_lines(const struct object_id *oid,
> int lines)
> size = parse_signature(buf, size);
> for (i = 0, sp += 2; i < lines && sp < buf + size; i++) {
> if (i)
> - printf("\n ");
> + strbuf_addstr(&sb,"\n ");
> eol = memchr(sp, '\n', size - (sp - buf));
> len = eol ? eol - sp : size - (sp - buf);
> - fwrite(sp, len, 1, stdout);
> + strbuf_add(&sb, sp, len);
> if (!eol)
> break;
> sp = eol + 1;
> }
> free_return:
> free(buf);
> + return strbuf_detach(&sb, NULL);
> }
>
> -static int show_reference(const char *refname, const struct object_id *oid,
> - int flag, void *cb_data)
> +static int get_reference_and_tag_lines(const char *refname, const struct
> object_id *oid,
> + int flag, void *cb_data)
> {
> struct tag_filter *filter = cb_data;
>
> @@ -234,16 +241,8 @@ static int show_reference(const char *refname, const
> struct object_id *oid,
> if (points_at.nr && !match_points_at(refname, oid->hash))
> return 0;
>
> - if (!filter->lines) {
> - if (filter->sort)
> - string_list_append(&filter->tags, refname);
> - else
> - printf("%s\n", refname);
> - return 0;
> - }
> - printf("%-15s ", refname);
> - show_tag_lines(oid, filter->lines);
> - putchar('\n');
> + string_list_append(&filter->tags, refname)->util =
> + get_tag_lines(oid, filter->lines);
> }
>
> return 0;
> @@ -260,6 +259,7 @@ static int list_tags(const char **patterns, int lines,
> struct commit_list *with_commit, int sort)
> {
> struct tag_filter filter;
> + int i;
>
> filter.patterns = patterns;
> filter.lines = lines;
> @@ -268,20 +268,28 @@ static int list_tags(const char **patterns, int lines,
> memset(&filter.tags, 0, sizeof(filter.tags));
> filter.tags.strdup_strings = 1;
>
> - for_each_tag_ref(show_reference, (void *)&filter);
> - if (sort) {
> - int i;
> - if ((sort & SORT_MASK) == VERCMP_SORT)
> - qsort(filter.tags.items, filter.tags.nr,
> - sizeof(struct string_list_item),
> sort_by_version);
> - if (sort & REVERSE_SORT)
> - for (i = filter.tags.nr - 1; i >= 0; i--)
> + for_each_tag_ref(get_reference_and_tag_lines, (void *)&filter);
> + if ((sort & SORT_MASK) == VERCMP_SORT)
> + qsort(filter.tags.items, filter.tags.nr,
> + sizeof(struct string_list_item), sort_by_version);
Nice. So we store the items and sort by the lines.
> + if (sort & REVERSE_SORT)
> + for (i = filter.tags.nr - 1; i >= 0; i--)
> + if (lines)
> + printf("%-15s %s\n",
> + filter.tags.items[i].string,
> + (char*)filter.tags.items[i].util);
> + else
> printf("%s\n", filter.tags.items[i].string);
> - else
> - for (i = 0; i < filter.tags.nr; i++)
> + else
> + for (i = 0; i < filter.tags.nr; i++)
> + if (lines)
> + printf("%-15s %s\n",
> + filter.tags.items[i].string,
> + (char*)filter.tags.items[i].util);
I see we print them here (or above depending on whether we reverse sort or not..
Nice! I would maybe suggest if we can rename util to something else so
it is more clear? Maybe I am not understanding why it has to be named
such.
> + else
> printf("%s\n", filter.tags.items[i].string);
> - string_list_clear(&filter.tags, 0);
> - }
> + string_list_clear(&filter.tags, 1);
> +
> return 0;
> }
>
> @@ -665,8 +673,6 @@ int cmd_tag(int argc, const char **argv, const char
> *prefix)
> copts.padding = 2;
> run_column_filter(colopts, &copts);
> }
> - if (lines != -1 && tag_sort)
> - die(_("--sort and -n are incompatible"));
> ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit,
> tag_sort);
> if (column_active(colopts))
> stop_column_filter();
> --
> 2.5.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html