From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Elliott Cable <me@ell.io>, Jeff King <peff@peff.net>
Subject: [PATCH v2 4/4] log: --author-date-order
Date: Sun, 9 Jun 2013 16:24:37 -0700 [thread overview]
Message-ID: <1370820277-30158-5-git-send-email-gitster@pobox.com> (raw)
In-Reply-To: <1370820277-30158-1-git-send-email-gitster@pobox.com>
Sometimes people would want to view the commits in parallel
histories in the order of author dates, not committer dates.
Teach "topo-order" sort machinery to do so, using a commit-info slab
to record the author dates of each commit, and commit-queue to sort
them.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Documentation/rev-list-options.txt | 4 +++
commit.c | 59 ++++++++++++++++++++++++++++++++++++++
commit.h | 3 +-
revision.c | 3 ++
4 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 3bdbf5e..8302402 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -617,6 +617,10 @@ By default, the commits are shown in reverse chronological order.
Show no parents before all of its children are shown, but
otherwise show commits in the commit timestamp order.
+--author-date-order::
+ Show no parents before all of its children are shown, but
+ otherwise show commits in the author timestamp order.
+
--topo-order::
Show no parents before all of its children are shown, and
avoid showing commits on multiple lines of history
diff --git a/commit.c b/commit.c
index cc6d385..f3a2f09 100644
--- a/commit.c
+++ b/commit.c
@@ -510,6 +510,53 @@ struct commit *pop_commit(struct commit_list **stack)
/* count number of children that have not been emitted */
define_commit_slab(indegree_slab, int);
+/* record author-date for each commit object */
+define_commit_slab(author_date_slab, unsigned long);
+
+static void record_author_date(struct author_date_slab *author_date,
+ struct commit *commit)
+{
+ const char *buf, *line_end;
+ struct ident_split ident;
+ char *date_end;
+ unsigned long date;
+
+ for (buf = commit->buffer; buf; buf = line_end + 1) {
+ line_end = strchrnul(buf, '\n');
+ if (prefixcmp(buf, "author ")) {
+ if (!line_end[0] || line_end[1] == '\n')
+ return; /* end of header */
+ continue;
+ }
+ if (split_ident_line(&ident,
+ buf + strlen("author "),
+ line_end - (buf + strlen("author "))) ||
+ !ident.date_begin || !ident.date_end)
+ return; /* malformed "author" line */
+ break;
+ }
+
+ date = strtoul(ident.date_begin, &date_end, 10);
+ if (date_end != ident.date_end)
+ return; /* malformed date */
+ *(author_date_slab_at(author_date, commit)) = date;
+}
+
+static int compare_commits_by_author_date(struct commit *a, struct commit *b,
+ void *cb_data)
+{
+ struct author_date_slab *author_date = cb_data;
+ unsigned long a_date = *(author_date_slab_at(author_date, a));
+ unsigned long b_date = *(author_date_slab_at(author_date, b));
+
+ /* newer commits with larger date first */
+ if (a_date < b_date)
+ return 1;
+ else if (a_date > b_date)
+ return -1;
+ return 0;
+}
+
static int compare_commits_by_commit_date(struct commit *a, struct commit *b, void *unused)
{
/* newer commits with larger date first */
@@ -530,6 +577,7 @@ void sort_in_topological_order(struct commit_list **list, enum rev_sort_order so
struct indegree_slab indegree;
struct commit_queue queue;
struct commit *commit;
+ struct author_date_slab author_date;
if (!orig)
return;
@@ -537,6 +585,7 @@ void sort_in_topological_order(struct commit_list **list, enum rev_sort_order so
init_indegree_slab(&indegree);
memset(&queue, '\0', sizeof(queue));
+
switch (sort_order) {
default: /* REV_SORT_IN_GRAPH_ORDER */
queue.compare = NULL;
@@ -544,12 +593,20 @@ void sort_in_topological_order(struct commit_list **list, enum rev_sort_order so
case REV_SORT_BY_COMMIT_DATE:
queue.compare = compare_commits_by_commit_date;
break;
+ case REV_SORT_BY_AUTHOR_DATE:
+ init_author_date_slab(&author_date);
+ queue.compare = compare_commits_by_author_date;
+ queue.cb_data = &author_date;
+ break;
}
/* Mark them and clear the indegree */
for (next = orig; next; next = next->next) {
struct commit *commit = next->item;
*(indegree_slab_at(&indegree, commit)) = 1;
+ /* also record the author dates, if needed */
+ if (sort_order == REV_SORT_BY_AUTHOR_DATE)
+ record_author_date(&author_date, commit);
}
/* update the indegree */
@@ -620,6 +677,8 @@ void sort_in_topological_order(struct commit_list **list, enum rev_sort_order so
clear_indegree_slab(&indegree);
clear_commit_queue(&queue);
+ if (sort_order == REV_SORT_BY_AUTHOR_DATE)
+ clear_author_date_slab(&author_date);
}
/* merge-base stuff */
diff --git a/commit.h b/commit.h
index 247e474..e43dfd0 100644
--- a/commit.h
+++ b/commit.h
@@ -142,7 +142,8 @@ void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark);
enum rev_sort_order {
REV_SORT_IN_GRAPH_ORDER = 0,
- REV_SORT_BY_COMMIT_DATE
+ REV_SORT_BY_COMMIT_DATE,
+ REV_SORT_BY_AUTHOR_DATE
};
/*
diff --git a/revision.c b/revision.c
index 966ebbc..12d9b64 100644
--- a/revision.c
+++ b/revision.c
@@ -1393,6 +1393,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
} else if (!strcmp(arg, "--date-order")) {
revs->sort_order = REV_SORT_BY_COMMIT_DATE;
revs->topo_order = 1;
+ } else if (!strcmp(arg, "--author-date-order")) {
+ revs->sort_order = REV_SORT_BY_AUTHOR_DATE;
+ revs->topo_order = 1;
} else if (!prefixcmp(arg, "--early-output")) {
int count = 100;
switch (arg[14]) {
--
1.8.3-451-gb703ddf
next prev parent reply other threads:[~2013-06-09 23:24 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-04 18:08 [PATCH/RFC] add --authorship-order flag to git log / rev-list elliottcable
2013-06-04 18:08 ` [PATCH/RFC] rev-list: add --authorship-order alternative ordering elliottcable
2013-06-04 19:14 ` Junio C Hamano
2013-06-04 21:20 ` Junio C Hamano
2013-06-06 19:03 ` Elliott Cable
2013-06-06 19:29 ` Junio C Hamano
2013-06-06 19:32 ` Elliott Cable
2013-06-06 19:40 ` Junio C Hamano
2013-06-06 22:48 ` Junio C Hamano
2013-06-06 23:25 ` [PATCH] toposort: rename "lifo" field Junio C Hamano
2013-06-07 1:25 ` Junio C Hamano
2013-06-07 5:11 ` [PATCH 0/3] Preparing for --date-order=author Junio C Hamano
2013-06-07 5:11 ` [PATCH 1/3] toposort: rename "lifo" field Junio C Hamano
2013-06-07 5:18 ` Eric Sunshine
2013-06-07 5:21 ` Junio C Hamano
2013-06-07 5:11 ` [PATCH 2/3] commit-queue: LIFO or priority queue of commits Junio C Hamano
2013-06-07 5:29 ` Eric Sunshine
2013-06-07 5:11 ` [PATCH 3/3] sort-in-topological-order: use commit-queue Junio C Hamano
2013-06-09 23:24 ` [PATCH v2 0/4] log --author-date-order Junio C Hamano
2013-06-09 23:24 ` [PATCH v2 1/4] toposort: rename "lifo" field Junio C Hamano
2013-06-10 2:12 ` Eric Sunshine
2013-06-10 5:05 ` Jeff King
2013-06-09 23:24 ` [PATCH v2 2/4] commit-queue: LIFO or priority queue of commits Junio C Hamano
2013-06-10 5:25 ` Jeff King
2013-06-10 7:21 ` Junio C Hamano
2013-06-10 18:15 ` Jeff King
2013-06-10 18:56 ` Junio C Hamano
2013-06-10 18:59 ` Jeff King
2013-06-10 23:23 ` Junio C Hamano
2013-06-11 6:36 ` Jeff King
2013-06-11 17:02 ` Junio C Hamano
2013-06-11 22:19 ` [PATCH v3 0/4] log --author-date-order Junio C Hamano
2013-06-11 22:19 ` [PATCH v3 1/4] toposort: rename "lifo" field Junio C Hamano
2013-06-11 22:19 ` [PATCH v3 2/4] prio-queue: priority queue of pointers to structs Junio C Hamano
2013-06-11 22:19 ` [PATCH v3 3/4] sort-in-topological-order: use prio-queue Junio C Hamano
2013-06-11 22:19 ` [PATCH v3 4/4] log: --author-date-order Junio C Hamano
2013-06-09 23:24 ` [PATCH v2 3/4] sort-in-topological-order: use commit-queue Junio C Hamano
2013-06-09 23:37 ` Junio C Hamano
2013-06-10 5:31 ` Jeff King
2013-06-10 7:27 ` Junio C Hamano
2013-06-10 18:24 ` Jeff King
2013-06-09 23:24 ` Junio C Hamano [this message]
2013-06-10 5:50 ` [PATCH v2 4/4] log: --author-date-order Jeff King
2013-06-10 7:39 ` Junio C Hamano
2013-06-10 18:49 ` Jeff King
2013-06-20 19:36 ` Junio C Hamano
2013-06-20 20:16 ` Jeff King
2013-06-07 5:09 ` [PATCH] toposort: rename "lifo" field Eric Sunshine
2013-06-04 21:22 ` [PATCH/RFC] rev-list: add --authorship-order alternative ordering Jeff King
2013-06-04 18:53 ` [PATCH/RFC] add --authorship-order flag to git log / rev-list Junio C Hamano
2013-06-06 18:06 ` Elliott Cable
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=1370820277-30158-5-git-send-email-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=me@ell.io \
--cc=peff@peff.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.