Merge branch 'nd/tag-version-sort'
Allow v1.9.0 sorted before v1.10.0 in "git tag --list" output. * nd/tag-version-sort: tag: support --sort=<spec>
This commit is contained in:
@ -27,9 +27,16 @@ static const char * const git_tag_usage[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
#define STRCMP_SORT 0 /* must be zero */
|
||||
#define VERCMP_SORT 1
|
||||
#define SORT_MASK 0x7fff
|
||||
#define REVERSE_SORT 0x8000
|
||||
|
||||
struct tag_filter {
|
||||
const char **patterns;
|
||||
int lines;
|
||||
int sort;
|
||||
struct string_list tags;
|
||||
struct commit_list *with_commit;
|
||||
};
|
||||
|
||||
@ -166,7 +173,10 @@ static int show_reference(const char *refname, const unsigned char *sha1,
|
||||
return 0;
|
||||
|
||||
if (!filter->lines) {
|
||||
printf("%s\n", refname);
|
||||
if (filter->sort)
|
||||
string_list_append(&filter->tags, refname);
|
||||
else
|
||||
printf("%s\n", refname);
|
||||
return 0;
|
||||
}
|
||||
printf("%-15s ", refname);
|
||||
@ -177,17 +187,39 @@ static int show_reference(const char *refname, const unsigned char *sha1,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sort_by_version(const void *a_, const void *b_)
|
||||
{
|
||||
const struct string_list_item *a = a_;
|
||||
const struct string_list_item *b = b_;
|
||||
return versioncmp(a->string, b->string);
|
||||
}
|
||||
|
||||
static int list_tags(const char **patterns, int lines,
|
||||
struct commit_list *with_commit)
|
||||
struct commit_list *with_commit, int sort)
|
||||
{
|
||||
struct tag_filter filter;
|
||||
|
||||
filter.patterns = patterns;
|
||||
filter.lines = lines;
|
||||
filter.sort = sort;
|
||||
filter.with_commit = with_commit;
|
||||
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--)
|
||||
printf("%s\n", filter.tags.items[i].string);
|
||||
else
|
||||
for (i = 0; i < filter.tags.nr; i++)
|
||||
printf("%s\n", filter.tags.items[i].string);
|
||||
string_list_clear(&filter.tags, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -427,6 +459,29 @@ static int parse_opt_points_at(const struct option *opt __attribute__((unused)),
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_opt_sort(const struct option *opt, const char *arg, int unset)
|
||||
{
|
||||
int *sort = opt->value;
|
||||
int flags = 0;
|
||||
|
||||
if (*arg == '-') {
|
||||
flags |= REVERSE_SORT;
|
||||
arg++;
|
||||
}
|
||||
if (starts_with(arg, "version:")) {
|
||||
*sort = VERCMP_SORT;
|
||||
arg += 8;
|
||||
} else if (starts_with(arg, "v:")) {
|
||||
*sort = VERCMP_SORT;
|
||||
arg += 2;
|
||||
} else
|
||||
*sort = STRCMP_SORT;
|
||||
if (strcmp(arg, "refname"))
|
||||
die(_("unsupported sort specification %s"), arg);
|
||||
*sort |= flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
@ -437,7 +492,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
struct create_tag_options opt;
|
||||
char *cleanup_arg = NULL;
|
||||
int annotate = 0, force = 0, lines = -1;
|
||||
int cmdmode = 0;
|
||||
int cmdmode = 0, sort = 0;
|
||||
const char *msgfile = NULL, *keyid = NULL;
|
||||
struct msg_arg msg = { 0, STRBUF_INIT };
|
||||
struct commit_list *with_commit = NULL;
|
||||
@ -462,6 +517,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
N_("use another key to sign the tag")),
|
||||
OPT__FORCE(&force, N_("replace the tag if exists")),
|
||||
OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
|
||||
{
|
||||
OPTION_CALLBACK, 0, "sort", &sort, N_("type"), N_("sort tags"),
|
||||
PARSE_OPT_NONEG, parse_opt_sort
|
||||
},
|
||||
|
||||
OPT_GROUP(N_("Tag listing options")),
|
||||
{
|
||||
@ -515,7 +574,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||
copts.padding = 2;
|
||||
run_column_filter(colopts, &copts);
|
||||
}
|
||||
ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit);
|
||||
if (lines != -1 && sort)
|
||||
die(_("--sort and -n are incompatible"));
|
||||
ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit, sort);
|
||||
if (column_active(colopts))
|
||||
stop_column_filter();
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user