commit dbc6a6b63b4f1e83c808f7ba4bc97e6ecee4d8ab from: Stefan Sperling date: Thu Jul 12 17:05:28 2018 UTC allow going back to previously blamed commits in tog blame commit - 245d91c1c0386bee2aeef42b4feae9cd4c01584b commit + dbc6a6b63b4f1e83c808f7ba4bc97e6ecee4d8ab blob - 16aa7b925adeefc4dbd6703da310ba7a98900ff4 blob + e59ee13190becb39193c375dab2908862dc51743 --- include/got_object.h +++ include/got_object.h @@ -40,6 +40,10 @@ struct got_object_qid { SIMPLEQ_HEAD(got_object_id_queue, got_object_qid); +const struct got_error *got_object_qid_alloc(struct got_object_qid **, + struct got_object_id *); +void got_object_qid_free(struct got_object_qid *); + struct got_commit_object { struct got_object_id *tree_id; unsigned int nparents; blob - 8bc417f477f5c5bb085172a3adf35471edc7f006 blob + 5b910150d744fa402d462bbd7cd1c1462155aa3f --- lib/object.c +++ lib/object.c @@ -474,6 +474,33 @@ done: } const struct got_error * +got_object_qid_alloc(struct got_object_qid **qid, struct got_object_id *id) +{ + const struct got_error *err = NULL; + + *qid = calloc(1, sizeof(**qid)); + if (*qid == NULL) + return got_error_from_errno(); + + (*qid)->id = got_object_id_dup(id); + if ((*qid)->id == NULL) { + err = got_error_from_errno(); + free(*qid); + *qid = NULL; + return err; + } + + return NULL; +} + +void +got_object_qid_free(struct got_object_qid *qid) +{ + free(qid->id); + free(qid); +} + +const struct got_error * got_object_commit_add_parent(struct got_commit_object *commit, const char *id_str) { blob - 13d27686b8f39ffc90f8e47b85293f8b2088d8f5 blob + 624b5bc632f99eed653b437584a9e045ab91f7a7 --- tog/tog.c +++ tog/tog.c @@ -1476,18 +1476,20 @@ show_blame_view(const char *path, struct got_object_id pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct tog_blame blame; int blame_running = 0; - struct got_object_id *blamed_commit_id = NULL; + struct got_object_id_queue blamed_commits; + struct got_object_qid *blamed_commit = NULL; + + SIMPLEQ_INIT(&blamed_commits); if (pthread_mutex_init(&mutex, NULL) != 0) { err = got_error_from_errno(); goto done; } - blamed_commit_id = got_object_id_dup(commit_id); - if (blamed_commit_id == NULL) { - err = got_error_from_errno(); + err = got_object_qid_alloc(&blamed_commit, commit_id); + if (err) goto done; - } + SIMPLEQ_INSERT_HEAD(&blamed_commits, blamed_commit, entry); if (tog_blame_view.window == NULL) { tog_blame_view.window = newwin(0, 0, 0, 0); @@ -1505,7 +1507,7 @@ show_blame_view(const char *path, struct got_object_id memset(&blame, 0, sizeof(blame)); err = run_blame(&blame, &mutex, &blame_complete, &first_displayed_line, &last_displayed_line, - &selected_line, &done, path, blamed_commit_id, repo); + &selected_line, &done, path, blamed_commit->id, repo); if (err) return err; @@ -1514,7 +1516,7 @@ show_blame_view(const char *path, struct got_object_id err = got_error_from_errno(); goto done; } - err = draw_blame(tog_blame_view.window, blamed_commit_id, + err = draw_blame(tog_blame_view.window, blamed_commit->id, blame.f, path, blame.lines, blame.nlines, blame_complete, selected_line, &first_displayed_line, &last_displayed_line, &eof, LINES); @@ -1565,7 +1567,7 @@ show_blame_view(const char *path, struct got_object_id id = get_selected_commit_id(blame.lines, first_displayed_line, selected_line); if (id == NULL || got_object_id_cmp(id, - blamed_commit_id) == 0) + blamed_commit->id) == 0) break; err = open_selected_commit(&pobj, &obj, blame.lines, first_displayed_line, @@ -1588,16 +1590,52 @@ show_blame_view(const char *path, struct got_object_id } if (thread_err) break; - free(blamed_commit_id); - blamed_commit_id = got_object_get_id(obj); - if (blamed_commit_id == NULL) { + id = got_object_get_id(obj); + if (id == NULL) { err = got_error_from_errno(); break; } + err = got_object_qid_alloc(&blamed_commit, id); + free(id); + if (err) + goto done; + SIMPLEQ_INSERT_HEAD(&blamed_commits, + blamed_commit, entry); err = run_blame(&blame, &mutex, &blame_complete, &first_displayed_line, &last_displayed_line, &selected_line, - &done, path, blamed_commit_id, repo); + &done, path, blamed_commit->id, repo); + if (err) + break; + blame_running = 1; + break; + } + case 'B': { + struct got_object_qid *first; + first = SIMPLEQ_FIRST(&blamed_commits); + if (!got_object_id_cmp(first->id, commit_id)) + break; + done = 1; + if (pthread_mutex_unlock(&mutex) != 0) { + err = got_error_from_errno(); + goto done; + } + thread_err = stop_blame(&blame); + blame_running = 0; + done = 0; + if (pthread_mutex_lock(&mutex) != 0) { + err = got_error_from_errno(); + goto done; + } + if (thread_err) + break; + SIMPLEQ_REMOVE_HEAD(&blamed_commits, entry); + got_object_qid_free(blamed_commit); + blamed_commit = SIMPLEQ_FIRST(&blamed_commits); + err = run_blame(&blame, &mutex, + &blame_complete, &first_displayed_line, + &last_displayed_line, &selected_line, + &done, path, blamed_commit->id, repo); if (err) break; blame_running = 1; @@ -1650,7 +1688,11 @@ done: got_object_close(pobj); if (blame_running) thread_err = stop_blame(&blame); - free(blamed_commit_id); + while (!SIMPLEQ_EMPTY(&blamed_commits)) { + blamed_commit = SIMPLEQ_FIRST(&blamed_commits); + SIMPLEQ_REMOVE_HEAD(&blamed_commits, entry); + got_object_qid_free(blamed_commit); + } return thread_err ? thread_err : err; }