# git-rev-list --date-order ?

3 messages from 2006-02-16 to 2006-02-16. Participants: Paul Mackerras, Junio C Hamano.
Thread: https://gitlist.dev/t/3351

## Paul Mackerras, 2006-02-16 02:40

Subject: git-rev-list --date-order ?
Message-ID: <17395.58926.26670.23572@cargo.ozlabs.ibm.com>
URL: https://gitlist.dev/e/17395.58926.26670.23572%40cargo.ozlabs.ibm.com

```
Junio,

Gitk has a -d option that tells it to reorder the commits in
decreasing order of their commit time, subject to the constraint that
parents come after all of their children.  Currently it uses
git-rev-list --header --topo-order --parents and then reorders the
commits internally.

How hard would it be to add a --date-order flag to git-rev-list to
make it order the commits in decreasing commit time order, subject to
the constraint that parents come after their children?

If we had that then I could remove another chunk of code from gitk and
make it a bit faster.

Thanks,
Paul.

```

## Junio C Hamano, 2006-02-16 03:11

Subject: Re: git-rev-list --date-order ?
Message-ID: <7vpsloknfq.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vpsloknfq.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <17395.58926.26670.23572@cargo.ozlabs.ibm.com>

```
Paul Mackerras <paulus@samba.org> writes:

> Junio,
>
> Gitk has a -d option that tells it to reorder the commits in
> decreasing order of their commit time, subject to the constraint that
> parents come after all of their children.  Currently it uses
> git-rev-list --header --topo-order --parents and then reorders the
> commits internally.
>
> How hard would it be to add a --date-order flag to git-rev-list to
> make it order the commits in decreasing commit time order, subject to
> the constraint that parents come after their children?
>
> If we had that then I could remove another chunk of code from gitk and
> make it a bit faster.

It's been a while that I read the topo-order code, but I suspect
something like this?  I may be completely off the mark here.

--
diff --git a/commit.c b/commit.c
index 67e11d7..0d94e4d 100644
--- a/commit.c
+++ b/commit.c
@@ -630,7 +630,9 @@ void sort_in_topological_order(struct co
 		}
 		next=next->next;
 	}
+
 	/* process the list in topological order */
+	sort_by_date(&work);
 	while (work) {
 		struct commit * work_item = pop_commit(&work);
 		struct sort_node * work_node = (struct sort_node *)work_item->object.util;
@@ -648,7 +650,7 @@ void sort_in_topological_order(struct co
                                  */
 				pn->indegree--;
 				if (!pn->indegree) 
-					commit_list_insert(parent, &work);
+					insert_by_date(parent, &work);
 			}
 			parents=parents->next;
 		}

```

## Junio C Hamano, 2006-02-16 06:18

Subject: [PATCH] topo-order: make --date-order optional.
Message-ID: <7vbqx7keru.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vbqx7keru.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <17395.58926.26670.23572@cargo.ozlabs.ibm.com>

```
This adds --date-order to rev-list; it is similar to topo order
in the sense that no parent comes before all of its children,
but otherwise things are still ordered in the commit timestamp
order.

The same flag is also added to show-branch.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * Paul, this supersedes the previous one, which made topo-order
   behave date-order unconditionally.

   The thing is, topological ordering code has a nice property
   that the equally eligible ones are pushed into a LIFO, which
   keeps single strand of pearls together and as good as the
   merge order for practical purposes.  Doing date-order breaks
   it.  Since we would want both, there is a new option as you
   originally wanted.

   I've tested it to see that it passes the tests, but that is
   not saying much ;-).

 commit.c      |   13 ++++++++++---
 commit.h      |    4 +++-
 rev-list.c    |   11 ++++++++++-
 rev-parse.c   |    1 +
 show-branch.c |    9 +++++----
 5 files changed, 29 insertions(+), 9 deletions(-)

4c8725f16abff4be4812d0d07a663250bef3ef0e
diff --git a/commit.c b/commit.c
index 67e11d7..c550a00 100644
--- a/commit.c
+++ b/commit.c
@@ -571,7 +571,7 @@ int count_parents(struct commit * commit
 /*
  * Performs an in-place topological sort on the list supplied.
  */
-void sort_in_topological_order(struct commit_list ** list)
+void sort_in_topological_order(struct commit_list ** list, int lifo)
 {
 	struct commit_list * next = *list;
 	struct commit_list * work = NULL, **insert;
@@ -630,7 +630,10 @@ void sort_in_topological_order(struct co
 		}
 		next=next->next;
 	}
+
 	/* process the list in topological order */
+	if (!lifo)
+		sort_by_date(&work);
 	while (work) {
 		struct commit * work_item = pop_commit(&work);
 		struct sort_node * work_node = (struct sort_node *)work_item->object.util;
@@ -647,8 +650,12 @@ void sort_in_topological_order(struct co
                                  * guaranteeing topological order.
                                  */
 				pn->indegree--;
-				if (!pn->indegree) 
-					commit_list_insert(parent, &work);
+				if (!pn->indegree) {
+					if (!lifo)
+						insert_by_date(parent, &work);
+					else
+						commit_list_insert(parent, &work);
+				}
 			}
 			parents=parents->next;
 		}
diff --git a/commit.h b/commit.h
index 986b22d..70a7c75 100644
--- a/commit.h
+++ b/commit.h
@@ -72,6 +72,8 @@ int count_parents(struct commit * commit
  * Post-conditions: 
  *   invariant of resulting list is:
  *      a reachable from b => ord(b) < ord(a)
+ *   in addition, when lifo == 0, commits on parallel tracks are
+ *   sorted in the dates order.
  */
-void sort_in_topological_order(struct commit_list ** list);
+void sort_in_topological_order(struct commit_list ** list, int lifo);
 #endif /* COMMIT_H */
diff --git a/rev-list.c b/rev-list.c
index 63391fc..f2d1105 100644
--- a/rev-list.c
+++ b/rev-list.c
@@ -27,6 +27,7 @@ static const char rev_list_usage[] =
 "  ordering output:\n"
 "    --merge-order [ --show-breaks ]\n"
 "    --topo-order\n"
+"    --date-order\n"
 "  formatting output:\n"
 "    --parents\n"
 "    --objects\n"
@@ -56,6 +57,7 @@ static int merge_order = 0;
 static int show_breaks = 0;
 static int stop_traversal = 0;
 static int topo_order = 0;
+static int lifo = 1;
 static int no_merges = 0;
 static const char **paths = NULL;
 static int remove_empty_trees = 0;
@@ -856,6 +858,13 @@ int main(int argc, const char **argv)
 		}
 		if (!strcmp(arg, "--topo-order")) {
 		        topo_order = 1;
+			lifo = 1;
+		        limited = 1;
+			continue;
+		}
+		if (!strcmp(arg, "--date-order")) {
+		        topo_order = 1;
+			lifo = 0;
 		        limited = 1;
 			continue;
 		}
@@ -940,7 +949,7 @@ int main(int argc, const char **argv)
 	        if (limited)
 			list = limit_list(list);
 		if (topo_order)
-			sort_in_topological_order(&list);
+			sort_in_topological_order(&list, lifo);
 		show_commit_list(list);
 	} else {
 #ifndef NO_OPENSSL
diff --git a/rev-parse.c b/rev-parse.c
index b82f294..9161fae 100644
--- a/rev-parse.c
+++ b/rev-parse.c
@@ -48,6 +48,7 @@ static int is_rev_argument(const char *a
 		"--show-breaks",
 		"--sparse",
 		"--topo-order",
+		"--date-order",
 		"--unpacked",
 		NULL
 	};
diff --git a/show-branch.c b/show-branch.c
index 511fd3b..5a86ae2 100644
--- a/show-branch.c
+++ b/show-branch.c
@@ -535,6 +535,7 @@ int main(int ac, char **av)
 	int num_rev, i, extra = 0;
 	int all_heads = 0, all_tags = 0;
 	int all_mask, all_revs;
+	int lifo = 1;
 	char head_path[128];
 	const char *head_path_p;
 	int head_path_len;
@@ -544,7 +545,6 @@ int main(int ac, char **av)
 	int no_name = 0;
 	int sha1_name = 0;
 	int shown_merge_point = 0;
-	int topo_order = 0;
 	int with_current_branch = 0;
 	int head_at = -1;
 
@@ -586,7 +586,9 @@ int main(int ac, char **av)
 		else if (!strcmp(arg, "--independent"))
 			independent = 1;
 		else if (!strcmp(arg, "--topo-order"))
-			topo_order = 1;
+			lifo = 1;
+		else if (!strcmp(arg, "--date-order"))
+			lifo = 0;
 		else
 			usage(show_branch_usage);
 		ac--; av++;
@@ -710,8 +712,7 @@ int main(int ac, char **av)
 		exit(0);
 
 	/* Sort topologically */
-	if (topo_order)
-		sort_in_topological_order(&seen);
+	sort_in_topological_order(&seen, lifo);
 
 	/* Give names to commits */
 	if (!sha1_name && !no_name)
-- 
1.2.1.gbf0a

```
