From: Christian Weisgerber Subject: tog: add option for topological sorting in log view To: gameoftrees@openbsd.org Date: Fri, 29 Mar 2024 17:42:31 +0100 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