commit 3bfadbd404f3e18e73d69ad6da6c0dbc8de67097 from: Stefan Sperling via: Thomas Adam date: Sat Nov 20 22:47:47 2021 UTC allow sorting references by timestamp in tog commit - 24f136e0f955e179395f9d081b45fbea32f02325 commit + 3bfadbd404f3e18e73d69ad6da6c0dbc8de67097 blob - 68b2f6d1475f5712480e40831e50f33b82c92d8f blob + 4d09d7c4a12a94eda1bbde6bb098bfced7ca8ac6 --- lib/reference.c +++ lib/reference.c @@ -765,6 +765,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; } @@ -774,44 +819,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 - 34a3a30489e4fe3063794bef7d79c9355cd4948f blob + 1c3d853f2b51d2bb75f62836b8dac88680acea7a --- tog/tog.c +++ tog/tog.c @@ -137,11 +137,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; @@ -447,7 +449,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; @@ -2596,7 +2598,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, @@ -2803,7 +2805,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; } @@ -3924,7 +3926,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; @@ -4852,7 +4854,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; @@ -5705,7 +5707,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; @@ -6239,6 +6241,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': @@ -6336,7 +6347,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); @@ -6420,7 +6431,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; @@ -6545,7 +6556,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 ?