commit - ad7de8d907a8f1a02d6449c9795f79a11d74d1b5
commit + 0553a4e327ba2ad58f38556354f97c8029888f78
blob - c31cd3fda721b5e2d4da9cc906d189a82ed3cce9
blob + 6db8041962c3853a56ab07eb07ae195c6a807b9d
--- tog/tog.c
+++ tog/tog.c
}
static const struct got_error *
-draw_commit(struct got_commit_object *commit, struct got_object_id *id,
- struct got_repository *repo)
+draw_commit(struct got_commit_object *commit, struct got_object_id *id)
{
const struct got_error *err = NULL;
char *logmsg0 = NULL, *logmsg = NULL;
struct got_object_id *id;
struct got_commit_object *commit;
};
+TAILQ_HEAD(commit_queue, commit_queue_entry);
static const struct got_error *
-draw_commits(struct got_object *root_obj, struct got_object_id *root_id,
- struct got_repository *repo, int selected)
+fetch_commits(struct commit_queue *commits, struct got_object *root_obj,
+ struct got_object_id *root_id, struct got_repository *repo, int limit)
{
const struct got_error *err;
struct got_commit_object *root_commit;
- TAILQ_HEAD(, commit_queue_entry) commits;
struct commit_queue_entry *entry;
int ncommits = 0;
- TAILQ_INIT(&commits);
-
err = got_object_commit_open(&root_commit, repo, root_obj);
if (err)
return err;
return err;
}
entry->commit = root_commit;
- TAILQ_INSERT_HEAD(&commits, entry, entry);
+ TAILQ_INSERT_HEAD(commits, entry, entry);
- wclear(tog_log_view.window);
-
- while (!TAILQ_EMPTY(&commits) && ncommits < LINES) {
+ while (entry->commit->nparents > 0 && ncommits < limit) {
struct got_parent_id *pid;
struct got_object *obj;
struct got_commit_object *pcommit;
struct commit_queue_entry *pentry;
- entry = TAILQ_FIRST(&commits);
+ entry = TAILQ_LAST(commits, commit_queue);
- if (ncommits == selected)
- wstandout(tog_log_view.window);
- err = draw_commit(entry->commit, entry->id, repo);
- if (ncommits == selected)
- wstandend(tog_log_view.window);
- if (err)
- break;
- ncommits++;
-
- if (entry->commit->nparents == 0)
- break;
-
/* Follow the first parent (TODO: handle merge commits). */
pid = SIMPLEQ_FIRST(&entry->commit->parent_ids);
err = got_object_open(&obj, repo, pid->id);
break;
}
pentry->commit = pcommit;
- TAILQ_INSERT_TAIL(&commits, pentry, entry);
+ TAILQ_INSERT_TAIL(commits, pentry, entry);
+ ncommits++;
+ }
- TAILQ_REMOVE(&commits, entry, entry);
+ return err;
+}
+
+static void
+free_commits(struct commit_queue *commits)
+{
+ struct commit_queue_entry *entry;
+
+ while (!TAILQ_EMPTY(commits)) {
+ entry = TAILQ_FIRST(commits);
+ TAILQ_REMOVE(commits, entry, entry);
got_object_commit_close(entry->commit);
free(entry->id);
free(entry);
}
+}
- while (!TAILQ_EMPTY(&commits)) {
- entry = TAILQ_FIRST(&commits);
- TAILQ_REMOVE(&commits, entry, entry);
- got_object_commit_close(entry->commit);
- free(entry->id);
- free(entry);
+static const struct got_error *
+draw_commits(struct commit_queue *commits, int selected)
+{
+ const struct got_error *err = NULL;
+ struct commit_queue_entry *entry;
+ int ncommits = 0;
+
+ wclear(tog_log_view.window);
+
+ TAILQ_FOREACH(entry, commits, entry) {
+ if (ncommits == selected)
+ wstandout(tog_log_view.window);
+ err = draw_commit(entry->commit, entry->id);
+ if (ncommits == selected)
+ wstandend(tog_log_view.window);
+ if (err)
+ break;
+ ncommits++;
}
update_panels();
doupdate();
+
return err;
}
-
static const struct got_error *
show_log_view(struct got_object_id *start_id, struct got_repository *repo)
{
const struct got_error *err = NULL;
struct got_object *obj;
- int ch, done = 0, selected = 0;
+ int ch, done = 0, selected = 0, refetch_commits = 1;
struct got_object_id *id = start_id;
+ struct commit_queue commits;
if (tog_log_view.window == NULL) {
tog_log_view.window = newwin(0, 0, 0, 0);
goto done;
}
+ TAILQ_INIT(&commits);
do {
- err = draw_commits(obj, id, repo, selected);
+ if (refetch_commits) {
+ free_commits(&commits);
+ err = fetch_commits(&commits, obj, id, repo, LINES);
+ if (err)
+ return err;
+ refetch_commits = 0;
+ }
+
+ err = draw_commits(&commits, selected);
if (err)
return err;
nodelay(stdscr, TRUE);
} while (!done);
done:
+ free_commits(&commits);
got_object_close(obj);
return err;
}