Download raw body.
implement sort by date in tog ref
On Tue, Nov 16, 2021 at 03:43:21PM +0100, Stefan Sperling wrote: > I tend to get lost between changes that are stacked on top of each > other sometimes. Often, each change in the stack will have a branch > reference pointing at it so I can keep track of things more easily. > > However, finding the top of this stack (i.e. the most recently modified > branc) is not trivial with our current UI. It essentially requires > jumping between references and comparing their commit date manually. > > This patch adds an easy way: Press 's' in the tog ref view and all > references will be sorted by their commit timestamp. In the weird > case where a ref does not point at a commit or tag we use the last > modification time of the on-disk reference file as a fallback. > > ok? I have committed this patch along with some follow-up fixes and tweaks. > Perhaps later we could add new options to allow 'got ref -l' and > 'got branch -l' to sort by date as well? > > diff f8306a31050978f1e7ff99ae008c68c4edf0678f c272759fa2c91227825d4eba4d9df8e784a56b25 > blob - 23650d4ec25dae858e6e634a02dd5735b0ac0b9d > blob + 3d4dadc8459f1d8ea2df85a31273afae7074548f > --- lib/reference.c > +++ lib/reference.c > @@ -769,50 +769,76 @@ done: > return err; > } > > +static const struct got_error * > +get_committer_time(struct got_reference *ref, struct got_repository *repo) > +{ > + const struct got_error *err = NULL; > + int obj_type; > + struct got_commit_object *commit = NULL; > + struct got_tag_object *tag = NULL; > + struct got_object_id *id = NULL; > + > + err = got_ref_resolve(&id, repo, ref); > + if (err) > + return err; > + > + err = got_object_get_type(&obj_type, repo, id); > + if (err) > + goto done; > + > + switch (obj_type) { > + case GOT_OBJ_TYPE_COMMIT: > + err = got_object_open_as_commit(&commit, repo, id); > + if (err) > + goto done; > + ref->committer_time = > + got_object_commit_get_committer_time(commit); > + break; > + case GOT_OBJ_TYPE_TAG: > + err = got_object_open_as_tag(&tag, repo, id); > + if (err) > + goto done; > + ref->committer_time = got_object_tag_get_tagger_time(tag); > + break; > + default: > + /* best effort for other object types */ > + ref->committer_time = got_ref_get_mtime(ref); > + break; > + } > +done: > + free(id); > + if (commit) > + got_object_commit_close(commit); > + if (tag) > + got_object_tag_close(tag); > + return err; > +} > + > const struct got_error * > got_ref_cmp_by_commit_timestamp_descending(void *arg, int *cmp, > struct got_reference *ref1, struct got_reference *ref2) > { > const struct got_error *err; > struct got_repository *repo = arg; > - struct got_object_id *id1 = NULL, *id2 = NULL; > - struct got_commit_object *commit1 = NULL, *commit2 = NULL; > > *cmp = 0; > > if (ref1->committer_time == 0) { > - err = got_ref_resolve(&id1, repo, ref1); > + err = get_committer_time(ref1, repo); > if (err) > return err; > - err = got_object_open_as_commit(&commit1, repo, id1); > - if (err) > - goto done; > - ref1->committer_time = > - got_object_commit_get_committer_time(commit1); > } > - > if (ref2->committer_time == 0) { > - err = got_ref_resolve(&id2, repo, ref2); > + err = get_committer_time(ref2, repo); > if (err) > return err; > - err = got_object_open_as_commit(&commit2, repo, id2); > - if (err) > - goto done; > - ref2->committer_time = > - got_object_commit_get_committer_time(commit2); > } > > if (ref1->committer_time < ref2->committer_time) > *cmp = 1; > else if (ref2->committer_time < ref1->committer_time) > *cmp = -1; > -done: > - free(id1); > - free(id2); > - if (commit1) > - got_object_commit_close(commit1); > - if (commit2) > - got_object_commit_close(commit2); > + > return err; > } > > blob - 0e414ba8af3db6bb003ec9b35d7e1510d7c18632 > blob + 838d2ac721da6d2d566440db6d4fe96c55d79cec > --- tog/tog.1 > +++ tog/tog.1 > @@ -452,6 +452,8 @@ view showing the tree resolved via the currently selec > Show object IDs for all non-symbolic references displayed in the > .Cm ref > view. > +.It Cm s > +Toggle display order of references between sort by name and sort by timestamp. > .It Cm / > Prompt for a search pattern and start searching for matching references. > The search pattern is an extended regular expression which is matched > blob - 74c66761f4e9c5685b0a4c978e74ba94fe3579ca > blob + deb6c22c2d7e0b2eb805d71560f1aff83c2315cc > --- tog/tog.c > +++ tog/tog.c > @@ -129,11 +129,13 @@ static struct got_reflist_head tog_refs = TAILQ_HEAD_I > static struct got_reflist_object_id_map *tog_refs_idmap; > > static const struct got_error * > -tog_load_refs(struct got_repository *repo) > +tog_load_refs(struct got_repository *repo, int sort_by_date) > { > const struct got_error *err; > > - err = got_ref_list(&tog_refs, repo, NULL, got_ref_cmp_by_name, NULL); > + err = got_ref_list(&tog_refs, repo, NULL, sort_by_date ? > + got_ref_cmp_by_commit_timestamp_descending : got_ref_cmp_by_name, > + repo); > if (err) > return err; > > @@ -439,7 +441,7 @@ struct tog_ref_view_state { > struct tog_reflist_entry *first_displayed_entry; > struct tog_reflist_entry *last_displayed_entry; > struct tog_reflist_entry *selected_entry; > - int nrefs, ndisplayed, selected, show_ids; > + int nrefs, ndisplayed, selected, show_ids, sort_by_date; > struct got_repository *repo; > struct tog_reflist_entry *matched_entry; > struct tog_colors colors; > @@ -2586,7 +2588,7 @@ input_log_view(struct tog_view **new_view, struct tog_ > if (err) > return err; > tog_free_refs(); > - err = tog_load_refs(s->repo); > + err = tog_load_refs(s->repo, 0); > if (err) > return err; > err = got_commit_graph_open(&s->thread_args.graph, > @@ -2793,7 +2795,7 @@ cmd_log(int argc, char *argv[]) > > /* already loaded by tog_log_with_path()? */ > if (TAILQ_EMPTY(&tog_refs)) { > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > } > @@ -3914,7 +3916,7 @@ cmd_diff(int argc, char *argv[]) > if (error) > goto done; > > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > > @@ -4842,7 +4844,7 @@ cmd_blame(int argc, char *argv[]) > if (error) > goto done; > > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > > @@ -5695,7 +5697,7 @@ cmd_tree(int argc, char *argv[]) > if (error) > goto done; > > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > > @@ -6230,6 +6232,15 @@ input_ref_view(struct tog_view **new_view, struct tog_ > case 'i': > s->show_ids = !s->show_ids; > break; > + case 's': > + s->sort_by_date = !s->sort_by_date; > + tog_free_refs(); > + err = tog_load_refs(s->repo, s->sort_by_date); > + if (err) > + break; > + ref_view_free_refs(s); > + err = ref_view_load_refs(s); > + break; > case KEY_ENTER: > case '\r': > if (!s->selected_entry) > @@ -6326,7 +6337,7 @@ input_ref_view(struct tog_view **new_view, struct tog_ > break; > case CTRL('l'): > tog_free_refs(); > - err = tog_load_refs(s->repo); > + err = tog_load_refs(s->repo, s->sort_by_date); > if (err) > break; > ref_view_free_refs(s); > @@ -6410,7 +6421,7 @@ cmd_ref(int argc, char *argv[]) > if (error) > goto done; > > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > > @@ -6535,7 +6546,7 @@ tog_log_with_path(int argc, char *argv[]) > if (error) > goto done; > > - error = tog_load_refs(repo); > + error = tog_load_refs(repo, 0); > if (error) > goto done; > error = got_repo_match_object_id(&commit_id, NULL, worktree ? > >
implement sort by date in tog ref