From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH] tag: support --sort=version
Date: Wed, 19 Feb 2014 20:39:27 +0700 [thread overview]
Message-ID: <1392817167-29802-1-git-send-email-pclouds@gmail.com> (raw)
--sort=version sorts tags as versions. GNU extension's strverscmp is
used and no real compat implementation is provided so this is Linux only.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
I didn't know that coreutils' sort is simply a wrapper of strverscmp.
With that GNU extension, implementing --sort is easy. Mac and Windows
are welcome to reimplement strverscmp (of rip it off glibc).
Documentation/git-tag.txt | 4 ++++
builtin/tag.c | 49 ++++++++++++++++++++++++++++++++++++++++++-----
git-compat-util.h | 7 +++++++
3 files changed, 55 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 404257d..fc23dc0 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -95,6 +95,10 @@ OPTIONS
using fnmatch(3)). Multiple patterns may be given; if any of
them matches, the tag is shown.
+--sort=<type>::
+ Sort in a specific order. Supported type is "version". Prepend
+ "-" to revert sort order.
+
--column[=<options>]::
--no-column::
Display tag listing in columns. See configuration variable
diff --git a/builtin/tag.c b/builtin/tag.c
index 74d3780..db3567b 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -30,6 +30,8 @@ static const char * const git_tag_usage[] = {
struct tag_filter {
const char **patterns;
int lines;
+ int version_sort;
+ struct string_list tags;
struct commit_list *with_commit;
};
@@ -166,7 +168,10 @@ static int show_reference(const char *refname, const unsigned char *sha1,
return 0;
if (!filter->lines) {
- printf("%s\n", refname);
+ if (filter->version_sort)
+ string_list_append(&filter->tags, refname);
+ else
+ printf("%s\n", refname);
return 0;
}
printf("%-15s ", refname);
@@ -177,17 +182,38 @@ 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 strverscmp(a->string, b->string);
+}
+
static int list_tags(const char **patterns, int lines,
- struct commit_list *with_commit)
+ struct commit_list *with_commit, int version_sort)
{
struct tag_filter filter;
filter.patterns = patterns;
filter.lines = lines;
+ filter.version_sort = version_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 (version_sort) {
+ int i;
+ qsort(filter.tags.items, filter.tags.nr,
+ sizeof(struct string_list_item), sort_by_version);
+ if (version_sort > 0)
+ for (i = 0; i < filter.tags.nr; i++)
+ printf("%s\n", filter.tags.items[i].string);
+ else
+ for (i = filter.tags.nr - 1; i >= 0; i--)
+ printf("%s\n", filter.tags.items[i].string);
+ string_list_clear(&filter.tags, 0);
+ }
return 0;
}
@@ -437,7 +463,8 @@ 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, version_sort = 0;
+ const char *sort = NULL;
const char *msgfile = NULL, *keyid = NULL;
struct msg_arg msg = { 0, STRBUF_INIT };
struct commit_list *with_commit = NULL;
@@ -462,6 +489,7 @@ 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")),
+ OPT_STRING(0, "sort", &sort, N_("type"), N_("sort tags")),
OPT_GROUP(N_("Tag listing options")),
{
@@ -509,7 +537,18 @@ 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 (sort) {
+ if (!strcmp(sort, "version"))
+ version_sort = 1;
+ else if (!strcmp(sort, "-version"))
+ version_sort = -1;
+ else
+ die(_("unsupported sort type %s"), sort);
+ }
+ if (lines != -1 && version_sort)
+ die(_("--sort and -l are incompatible"));
+ ret = list_tags(argv, lines == -1 ? 0 : lines, with_commit,
+ version_sort);
if (column_active(colopts))
stop_column_filter();
return ret;
diff --git a/git-compat-util.h b/git-compat-util.h
index cbd86c3..22089e9 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -721,4 +721,11 @@ void warn_on_inaccessible(const char *path);
/* Get the passwd entry for the UID of the current process. */
struct passwd *xgetpwuid_self(void);
+#ifndef __GNU_LIBRARY__
+static inline int strverscmp(const char *s1, const char *s2)
+{
+ die("strverscmp() not supported");
+}
+#endif
+
#endif
--
1.9.0.40.gaa8c3ea
next reply other threads:[~2014-02-19 13:39 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-19 13:39 Nguyễn Thái Ngọc Duy [this message]
2014-02-19 14:09 ` [PATCH] tag: support --sort=version Jeff King
2014-02-19 14:19 ` Duy Nguyen
2014-02-20 20:43 ` Jeff King
2014-02-21 11:58 ` Duy Nguyen
2014-02-21 17:48 ` Junio C Hamano
2014-02-22 7:59 ` Jeff King
2014-02-22 9:07 ` Duy Nguyen
2014-02-19 18:43 ` Eric Sunshine
2014-02-22 3:29 ` [PATCH v2] tag: support --sort=<spec> Nguyễn Thái Ngọc Duy
2014-02-22 8:04 ` Jeff King
2014-02-24 16:39 ` Junio C Hamano
2014-02-24 23:30 ` Duy Nguyen
2014-02-24 23:33 ` Jeff King
2014-02-25 12:22 ` [PATCH v3] " Nguyễn Thái Ngọc Duy
2014-02-25 17:42 ` Junio C Hamano
2014-02-26 9:05 ` Jeff King
2014-02-26 11:03 ` Duy Nguyen
2014-02-26 11:08 ` Jeff King
2014-02-26 11:11 ` Duy Nguyen
2014-02-26 11:17 ` Jeff King
2014-02-26 11:31 ` Duy Nguyen
2014-02-27 12:56 ` [PATCH v4] " Nguyễn Thái Ngọc Duy
2014-02-27 13:11 ` Jeff King
2014-02-27 13:23 ` Duy Nguyen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1392817167-29802-1-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).