commit 7f66531d28466880142708210643464d65b9b63b from: Stefan Sperling date: Tue Nov 16 14:33:26 2021 UTC allow sorting references by timestamp in tog commit - 0e039681388d7ec1f832edcbb108ac28db95ae1e commit + 7f66531d28466880142708210643464d65b9b63b blob - 23650d4ec25dae858e6e634a02dd5735b0ac0b9d blob + 3d4dadc8459f1d8ea2df85a31273afae7074548f --- lib/reference.c +++ lib/reference.c @@ -766,6 +766,51 @@ done: got_object_commit_close(commit1); if (commit2) got_object_commit_close(commit2); + 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; } @@ -775,44 +820,25 @@ got_ref_cmp_by_commit_timestamp_descending(void *arg, { 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); + if (ref2->committer_time == 0) { + 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; @@ -6229,6 +6231,15 @@ input_ref_view(struct tog_view **new_view, struct tog_ switch (ch) { 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': @@ -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 ?