"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Christian Weisgerber <naddy@mips.inka.de>
Subject:
tog: add option for topological sorting in log view
To:
gameoftrees@openbsd.org
Date:
Fri, 29 Mar 2024 17:42:31 +0100

Download raw body.

Thread
 tog: add log -t option to enable topological sorting of commits
 
 Copied from "got log".

OK?
Keybinding to follow in a second diff.
 
diff e789f02b267046e82b75e50ea5239a477e7e1d75 919c86456dcc8803783cc58539fd98c51f2eec98
commit - e789f02b267046e82b75e50ea5239a477e7e1d75
commit + 919c86456dcc8803783cc58539fd98c51f2eec98
blob - d8658727083f485410ad107da6f6be22bc730f01
blob + aaebb8ead9f89ebb9cdd5beec214a128914cebe2
--- tog/tog.1
+++ tog/tog.1
@@ -132,7 +132,7 @@ are as follows:
 .Bl -tag -width blame
 .It Xo
 .Cm log
-.Op Fl b
+.Op Fl bt
 .Op Fl c Ar commit
 .Op Fl r Ar repository-path
 .Op Ar path
@@ -329,6 +329,13 @@ working directory.
 If this directory is a
 .Xr got 1
 work tree, use the repository path associated with this work tree.
+.It Fl t
+Display commits in topological order.
+This option has no effect without the
+.Fl b 
+option because a linear history is sorted in topological order by definition.
+Topological sorting is disabled by default because the present implementation
+requires that commit history is fully traversed before any output can be shown.
 .El
 .It Xo
 .Cm diff
blob - 49be7dc0e431407602c4dba0ac7030028d5a567e
blob + 9e08d315873250cfffa04b27d0a49cb92dcbf259
--- tog/tog.c
+++ tog/tog.c
@@ -395,6 +395,7 @@ struct tog_log_view_state {
 	char *in_repo_path;
 	char *head_ref_name;
 	int log_branches;
+	int toposort;
 	struct got_repository *repo;
 	struct got_object_id *start_id;
 	sig_atomic_t quit;
@@ -734,7 +735,7 @@ static const struct got_error *search_next_view_match(
 
 static const struct got_error *open_log_view(struct tog_view *,
     struct got_object_id *, struct got_repository *,
-    const char *, const char *, int, struct got_worktree *);
+    const char *, const char *, int, int, struct got_worktree *);
 static const struct got_error * show_log_view(struct tog_view *);
 static const struct got_error *input_log_view(struct tog_view **,
     struct tog_view *, int);
@@ -2161,7 +2162,7 @@ usage_log(void)
 {
 	endwin();
 	fprintf(stderr,
-	    "usage: %s log [-b] [-c commit] [-r repository-path] [path]\n",
+	    "usage: %s log [-bt] [-c commit] [-r repository-path] [path]\n",
 	    getprogname());
 	exit(1);
 }
@@ -3795,7 +3796,7 @@ search_next_log_view(struct tog_view *view)
 static const struct got_error *
 open_log_view(struct tog_view *view, struct got_object_id *start_id,
     struct got_repository *repo, const char *head_ref_name,
-    const char *in_repo_path, int log_branches,
+    const char *in_repo_path, int log_branches, int toposort,
     struct got_worktree *worktree)
 {
 	const struct got_error *err = NULL;
@@ -3836,6 +3837,7 @@ open_log_view(struct tog_view *view, struct got_object
 		goto done;
 	}
 	s->log_branches = log_branches;
+	s->toposort = toposort;
 	s->use_committer = 1;
 
 	STAILQ_INIT(&s->colors);
@@ -3874,8 +3876,13 @@ open_log_view(struct tog_view *view, struct got_object
 	    !s->log_branches);
 	if (err)
 		goto done;
-	err = got_commit_graph_bfsort(thread_graph, s->start_id,
-	    s->repo, NULL, NULL);
+	if (s->log_branches && s->toposort) {
+		err = got_commit_graph_toposort(thread_graph, s->start_id,
+		    s->repo, NULL, NULL);
+	} else {
+		err = got_commit_graph_bfsort(thread_graph, s->start_id,
+		    s->repo, NULL, NULL);
+	}
 	if (err)
 		goto done;
 
@@ -4330,8 +4337,13 @@ input_log_view(struct tog_view **new_view, struct tog_
 		    s->in_repo_path, !s->log_branches);
 		if (err)
 			return err;
-		err = got_commit_graph_bfsort(s->thread_args.graph,
-		    s->start_id, s->repo, NULL, NULL);
+		if (s->log_branches && s->toposort) {
+			err = got_commit_graph_toposort(s->thread_args.graph,
+			    s->start_id, s->repo, NULL, NULL);
+		} else {
+			err = got_commit_graph_bfsort(s->thread_args.graph,
+			    s->start_id, s->repo, NULL, NULL);
+		}
 		if (err)
 			return err;
 		free_commits(&s->real_commits);
@@ -4527,11 +4539,11 @@ cmd_log(int argc, char *argv[])
 	char *keyword_idstr = NULL, *start_commit = NULL, *label = NULL;
 	struct got_reference *ref = NULL;
 	const char *head_ref_name = NULL;
-	int ch, log_branches = 0;
+	int ch, log_branches = 0, toposort = 0;
 	struct tog_view *view;
 	int *pack_fds = NULL;
 
-	while ((ch = getopt(argc, argv, "bc:r:")) != -1) {
+	while ((ch = getopt(argc, argv, "bc:r:t")) != -1) {
 		switch (ch) {
 		case 'b':
 			log_branches = 1;
@@ -4545,6 +4557,9 @@ cmd_log(int argc, char *argv[])
 				return got_error_from_errno2("realpath",
 				    optarg);
 			break;
+		case 't':
+			toposort = 1;
+			break;
 		default:
 			usage_log();
 			/* NOTREACHED */
@@ -4643,7 +4658,7 @@ cmd_log(int argc, char *argv[])
 	}
 
 	error = open_log_view(view, start_id, repo, head_ref_name,
-	    in_repo_path, log_branches, worktree);
+	    in_repo_path, log_branches, toposort, worktree);
 	if (error)
 		goto done;
 
@@ -6906,7 +6921,7 @@ log_annotated_line(struct tog_view **new_view, int beg
 	if (log_view == NULL)
 		return got_error_from_errno("view_open");
 
-	err = open_log_view(log_view, id, repo, GOT_REF_HEAD, "", 0, NULL);
+	err = open_log_view(log_view, id, repo, GOT_REF_HEAD, "", 0, 0, NULL);
 	if (err)
 		view_close(log_view);
 	else
@@ -7708,7 +7723,7 @@ log_selected_tree_entry(struct tog_view **new_view, in
 		return err;
 
 	err = open_log_view(log_view, s->commit_id, s->repo, s->head_ref_name,
-	    path, 0, NULL);
+	    path, 0, 0, NULL);
 	if (err)
 		view_close(log_view);
 	else
@@ -8568,7 +8583,7 @@ log_ref_entry(struct tog_view **new_view, int begin_y,
 	}
 
 	err = open_log_view(log_view, commit_id, repo,
-	    got_ref_get_name(re->ref), "", 0, NULL);
+	    got_ref_get_name(re->ref), "", 0, 0, NULL);
 done:
 	if (err)
 		view_close(log_view);

-- 
Christian "naddy" Weisgerber                          naddy@mips.inka.de