commit cd0acaa77f0415b3788c97a19f4419b6bf20ece8 from: Stefan Sperling date: Sun May 20 10:37:25 2018 UTC allow switching from log view to diff view in tog commit - 4ed7e80c99d049eb6f7c4d432e28a22908da4ca2 commit + cd0acaa77f0415b3788c97a19f4419b6bf20ece8 blob - c9ec771e35f0f82b5f4685972ff2bcb68251d934 blob + f0adc78ea7549c48ef078033c86f8e80e13d9db3 --- lib/diff.c +++ lib/diff.c @@ -448,13 +448,16 @@ got_diff_objects_as_blobs(struct got_object *obj1, str const struct got_error *err; struct got_blob_object *blob1 = NULL, *blob2 = NULL; - err = got_object_blob_open(&blob1, repo, obj1, 8192); - if (err) - goto done; - err = got_object_blob_open(&blob2, repo, obj2, 8192); - if (err) - goto done; - + if (obj1) { + err = got_object_blob_open(&blob1, repo, obj1, 8192); + if (err) + goto done; + } + if (obj2) { + err = got_object_blob_open(&blob2, repo, obj2, 8192); + if (err) + goto done; + } err = got_diff_blob(blob1, blob2, NULL, NULL, outfile); done: if (blob1) @@ -471,13 +474,16 @@ got_diff_objects_as_trees(struct got_object *obj1, str const struct got_error *err; struct got_tree_object *tree1 = NULL, *tree2 = NULL; - err = got_object_tree_open(&tree1, repo, obj1); - if (err) - goto done; - err = got_object_tree_open(&tree2, repo, obj2); - if (err) - goto done; - + if (obj1) { + err = got_object_tree_open(&tree1, repo, obj1); + if (err) + goto done; + } + if (obj2) { + err = got_object_tree_open(&tree2, repo, obj2); + if (err) + goto done; + } err = got_diff_tree(tree1, tree2, repo, outfile); done: if (tree1) @@ -495,20 +501,22 @@ got_diff_objects_as_commits(struct got_object *obj1, s struct got_commit_object *commit1 = NULL, *commit2 = NULL; struct got_object *tree_obj1 = NULL, *tree_obj2 = NULL; - err = got_object_commit_open(&commit1, repo, obj1); - if (err) - goto done; - err = got_object_commit_open(&commit2, repo, obj2); - if (err) - goto done; - - err = got_object_open(&tree_obj1, repo, commit1->tree_id); - if (err) - goto done; - err = got_object_open(&tree_obj2, repo, commit2->tree_id); - if (err) - goto done; - + if (obj1) { + err = got_object_commit_open(&commit1, repo, obj1); + if (err) + goto done; + err = got_object_open(&tree_obj1, repo, commit1->tree_id); + if (err) + goto done; + } + if (obj2) { + err = got_object_commit_open(&commit2, repo, obj2); + if (err) + goto done; + err = got_object_open(&tree_obj2, repo, commit2->tree_id); + if (err) + goto done; + } err = got_diff_objects_as_trees(tree_obj1, tree_obj2, repo, outfile); done: if (tree_obj1) blob - 963fa3b98d18b61808cffcafab168256052e568b blob + 54fc8c0350942b78eb2201519557d38ac35ffca1 --- tog/tog.c +++ tog/tog.c @@ -73,6 +73,12 @@ static struct tog_view { WINDOW *window; PANEL *panel; } tog_log_view, tog_diff_view; + +static const struct got_error * +show_diff_view(struct got_object *, struct got_object *, + struct got_repository *); +static const struct got_error * +show_log_view(struct got_object_id *, struct got_repository *); __dead static void usage_log(void) @@ -436,8 +442,8 @@ fetch_commits(struct commit_queue_entry **start_entry, } static const struct got_error * -draw_commits(struct commit_queue_entry **last, struct commit_queue_entry *first, - int selected, int limit) +draw_commits(struct commit_queue_entry **last, struct commit_queue_entry **selected, + struct commit_queue_entry *first, int selected_idx, int limit) { const struct got_error *err = NULL; struct commit_queue_entry *entry; @@ -450,10 +456,12 @@ draw_commits(struct commit_queue_entry **last, struct while (entry) { if (ncommits == limit) break; - if (ncommits == selected) + if (ncommits == selected_idx) { wstandout(tog_log_view.window); + *selected = entry; + } err = draw_commit(entry->commit, entry->id); - if (ncommits == selected) + if (ncommits == selected_idx) wstandend(tog_log_view.window); if (err) break; @@ -547,6 +555,32 @@ num_parents(struct commit_queue_entry *entry) } return nparents; +} + +static const struct got_error * +show_commit(struct commit_queue_entry *entry, struct got_repository *repo) +{ + const struct got_error *err; + struct got_object *obj1 = NULL, *obj2 = NULL; + + err = got_object_open(&obj2, repo, entry->id); + if (err) + return err; + + entry = TAILQ_NEXT(entry, entry); + if (entry) { + err = got_object_open(&obj1, repo, entry->id); + if (err) + goto done; + } + + err = show_diff_view(obj1, obj2, repo); +done: + if (obj1) + got_object_close(obj1); + if (obj2) + got_object_close(obj2); + return err; } static const struct got_error * @@ -558,6 +592,7 @@ show_log_view(struct got_object_id *start_id, struct g struct commit_queue commits; struct commit_queue_entry *first_displayed_entry = NULL; struct commit_queue_entry *last_displayed_entry = NULL; + struct commit_queue_entry *selected_entry = NULL; id = got_object_id_dup(start_id); if (id == NULL) @@ -573,15 +608,16 @@ show_log_view(struct got_object_id *start_id, struct g tog_log_view.panel = new_panel(tog_log_view.window); if (tog_log_view.panel == NULL) return got_error_from_errno(); - } + } else + show_panel(tog_log_view.panel); TAILQ_INIT(&commits); err = fetch_commits(&first_displayed_entry, id, &commits, LINES, repo); if (err) goto done; while (!done) { - err = draw_commits(&last_displayed_entry, first_displayed_entry, - selected, LINES); + err = draw_commits(&last_displayed_entry, &selected_entry, + first_displayed_entry, selected, LINES); if (err) goto done; @@ -646,6 +682,13 @@ show_log_view(struct got_object_id *start_id, struct g case KEY_RESIZE: if (selected > LINES) selected = LINES - 1; + break; + case KEY_ENTER: + case '\r': + err = show_commit(selected_entry, repo); + if (err) + break; + show_panel(tog_log_view.panel); break; default: break; @@ -783,14 +826,15 @@ show_diff_view(struct got_object *obj1, struct got_obj int ch, done = 0, first_displayed_line = 1, last_displayed_line = LINES; int eof; - if (got_object_get_type(obj1) != got_object_get_type(obj2)) + if (obj1 != NULL && obj2 != NULL && + got_object_get_type(obj1) != got_object_get_type(obj2)) return got_error(GOT_ERR_OBJ_TYPE); f = got_opentemp(); if (f == NULL) return got_error_from_errno(); - switch (got_object_get_type(obj1)) { + switch (got_object_get_type(obj1 ? obj1 : obj2)) { case GOT_OBJ_TYPE_BLOB: err = got_diff_objects_as_blobs(obj1, obj2, repo, f); break;