From: "Marc-André Lureau" <marcandre.lureau@gmail.com>
To: git@vger.kernel.org
Subject: [PATCH/RFC 5/6] builtin-tag: add sort by date -D
Date: Sun, 22 Feb 2009 20:06:45 +0200 [thread overview]
Message-ID: <e29894ca0902221006j3d602553x15807b41698f51a1@mail.gmail.com> (raw)
Signed-off-by: Marc-Andre Lureau <marcandre.lureau@gmail.com>
---
builtin-tag.c | 162 +++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 129 insertions(+), 33 deletions(-)
diff --git a/builtin-tag.c b/builtin-tag.c
index 01e7374..8ff9d03 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -16,7 +16,7 @@
static const char * const git_tag_usage[] = {
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
"git tag -d <tagname>...",
- "git tag -l [-n[<num>]] [<pattern>]",
+ "git tag -l [-n[<num>] -D] [<pattern>]",
"git tag -v <tagname>...",
NULL
};
@@ -27,21 +27,108 @@ struct tag_filter {
const char *pattern;
int lines;
struct commit_list *with_commit;
+ int sort;
+ struct object_list *sorted_tags;
};
+struct light_tag {
+ struct object object;
+ struct object *tagged;
+ char *refname;
+};
+
+#define OBJ_LIGHT_TAG (OBJ_MAX + 1)
#define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
+static unsigned long object_date(struct object *object)
+{
+ if (object->type == OBJ_TAG)
+ return ((struct tag*)object)->date;
+ else if (object->type == OBJ_COMMIT)
+ return ((struct commit*)object)->date;
+ else if (object->type == OBJ_TREE)
+ return 0;
+ else if (object->type == OBJ_BLOB)
+ return 0;
+ else if (object->type == OBJ_LIGHT_TAG)
+ return object_date(((struct light_tag*)object)->tagged);
+
+ return 0;
+}
+
+static struct object_list *object_list_insert_by_date(struct object
*item, struct object_list **list)
+{
+ struct object_list **pp = list;
+ struct object_list *p;
+ unsigned long item_date;
+ unsigned long p_date;
+
+ if (!item->parsed)
+ return NULL;
+
+ while ((p = *pp) != NULL) {
+ p_date = object_date(p->item);
+ item_date = object_date(item);
+
+ if (p_date > item_date)
+ break;
+
+ pp = &p->next;
+ }
+ return object_list_insert(item, pp);
+}
+
+static void pretty_print_tag(const struct object *object, int lines)
+{
+ int i;
+ char *sp, *eol;
+ size_t len;
+
+ if (!lines) {
+ if (object->type == OBJ_TAG)
+ printf("%s\n", ((struct tag*)object)->tag);
+ else if (object->type == OBJ_LIGHT_TAG)
+ printf("%s\n", ((struct light_tag*)object)->refname);
+ /* other not implemented */
+ return;
+ }
+
+ if (object->type == OBJ_TAG) {
+ struct tag *tag;
+
+ tag = (struct tag*)object;
+ printf("%-15s ", tag->tag);
+
+ /* skip header */
+ sp = strstr(tag->buffer, "\n\n");
+ if (!sp)
+ return;
+
+ /* only take up to "lines" lines, and strip the signature */
+ for (i = 0, sp += 2;
+ i < lines && sp < tag->buffer + tag->size &&
+ prefixcmp(sp, PGP_SIGNATURE "\n");
+ i++) {
+ if (i)
+ printf("\n ");
+ eol = memchr(sp, '\n', tag->size - (sp - tag->buffer));
+ len = eol ? eol - sp : tag->size - (sp - tag->buffer);
+ fwrite(sp, len, 1, stdout);
+ if (!eol)
+ break;
+ sp = eol + 1;
+ }
+ putchar('\n');
+ }
+}
+
static int show_reference(const char *refname, const unsigned char *sha1,
int flag, void *cb_data)
{
struct tag_filter *filter = cb_data;
+ struct object *object;
if (!fnmatch(filter->pattern, refname, 0)) {
- int i;
- unsigned long size;
- enum object_type type;
- char *buf, *sp, *eol;
- size_t len;
if (filter->with_commit) {
struct commit *commit;
@@ -53,45 +140,43 @@ static int show_reference(const char *refname,
const unsigned char *sha1,
return 0;
}
- if (!filter->lines) {
+ if (!filter->lines && !filter->sort) {
printf("%s\n", refname);
return 0;
}
- printf("%-15s ", refname);
- buf = read_sha1_file(sha1, &type, &size);
- if (!buf || !size)
+ object = parse_object(sha1);
+ if (!object)
return 0;
- /* skip header */
- sp = strstr(buf, "\n\n");
- if (!sp) {
- free(buf);
- return 0;
+ if (object->type != OBJ_TAG) {
+ struct light_tag *light_tag;
+ struct object *o;
+
+ o = xmalloc(sizeof(struct light_tag));
+ light_tag = (struct light_tag*)o;
+ o->parsed = 1;
+ o->used = 0;
+ o->type = OBJ_LIGHT_TAG;
+ o->flags = 0;
+ light_tag->tagged = object;
+ light_tag->refname = xstrdup(refname);
+ object = o;
}
- /* only take up to "lines" lines, and strip the signature */
- for (i = 0, sp += 2;
- i < filter->lines && sp < buf + size &&
- prefixcmp(sp, PGP_SIGNATURE "\n");
- i++) {
- if (i)
- printf("\n ");
- eol = memchr(sp, '\n', size - (sp - buf));
- len = eol ? eol - sp : size - (sp - buf);
- fwrite(sp, len, 1, stdout);
- if (!eol)
- break;
- sp = eol + 1;
+
+ if (filter->sort) {
+ object_list_insert_by_date(object, &filter->sorted_tags);
+ return 0;
}
- putchar('\n');
- free(buf);
+
+ pretty_print_tag(object, filter->lines);
}
return 0;
}
static int list_tags(const char *pattern, int lines,
- struct commit_list *with_commit)
+ struct commit_list *with_commit, int sort)
{
struct tag_filter filter;
@@ -101,9 +186,19 @@ static int list_tags(const char *pattern, int lines,
filter.pattern = pattern;
filter.lines = lines;
filter.with_commit = with_commit;
+ filter.sort = sort;
+ filter.sorted_tags = NULL;
for_each_tag_ref(show_reference, (void *) &filter);
+ if (filter.sort) {
+ struct object_list *l;
+ for (l = filter.sorted_tags; l; l = l->next) {
+ pretty_print_tag(l->item, lines);
+ }
+ /* free_object_list(filter.sorted_tags); */
+ }
+
return 0;
}
@@ -370,12 +465,13 @@ int cmd_tag(int argc, const char **argv, const
char *prefix)
struct ref_lock *lock;
int annotate = 0, sign = 0, force = 0, lines = -1,
- list = 0, delete = 0, verify = 0;
+ list = 0, delete = 0, verify = 0, sort = 0;
const char *msgfile = NULL, *keyid = NULL;
struct msg_arg msg = { 0, STRBUF_INIT };
struct commit_list *with_commit = NULL;
struct option options[] = {
OPT_BOOLEAN('l', NULL, &list, "list tag names"),
+ OPT_BOOLEAN('D', NULL, &sort, "sort tag by date"),
{ OPTION_INTEGER, 'n', NULL, &lines, NULL,
"print n lines of each tag message",
PARSE_OPT_OPTARG, NULL, 1 },
@@ -425,7 +521,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
usage_with_options(git_tag_usage, options);
if (list)
return list_tags(argv[0], lines == -1 ? 0 : lines,
- with_commit);
+ with_commit, sort);
if (lines != -1)
die("-n option is only allowed with -l.");
if (with_commit)
--
1.6.2.rc1.28.g05ef4.dirty
next reply other threads:[~2009-02-22 18:08 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-22 18:06 Marc-André Lureau [this message]
2009-02-22 18:33 ` [PATCH/RFC 5/6] builtin-tag: add sort by date -D Junio C Hamano
2009-02-22 18:38 ` Felipe Contreras
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=e29894ca0902221006j3d602553x15807b41698f51a1@mail.gmail.com \
--to=marcandre.lureau@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).