static int ahead_behind(git_commit_list_node *one, git_commit_list_node *two, size_t *ahead, size_t *behind) { git_commit_list_node *commit; git_pqueue pq; int i; *ahead = 0; *behind = 0; if (git_pqueue_init(&pq, 2, git_commit_list_time_cmp) < 0) return -1; if (git_pqueue_insert(&pq, one) < 0) goto on_error; if (git_pqueue_insert(&pq, two) < 0) goto on_error; while ((commit = git_pqueue_pop(&pq)) != NULL) { if (commit->flags & RESULT || (commit->flags & (PARENT1 | PARENT2)) == (PARENT1 | PARENT2)) continue; else if (commit->flags & PARENT1) (*behind)++; else if (commit->flags & PARENT2) (*ahead)++; for (i = 0; i < commit->out_degree; i++) { git_commit_list_node *p = commit->parents[i]; if (git_pqueue_insert(&pq, p) < 0) return -1; } commit->flags |= RESULT; } git_pqueue_free(&pq); return 0; on_error: git_pqueue_free(&pq); return -1; }
void git_revwalk_free(git_revwalk *walk) { if (walk == NULL) return; git_revwalk_reset(walk); git_odb_free(walk->odb); git_oidmap_free(walk->commits); git_pool_clear(&walk->commit_pool); git_pqueue_free(&walk->iterator_time); git__free(walk); }
static int premark_uninteresting(git_revwalk *walk) { int error = 0; unsigned short i; git_pqueue q; git_commit_list *list; git_commit_list_node *commit, *parent; if ((error = git_pqueue_init(&q, 0, 8, git_commit_list_time_cmp)) < 0) return error; for (list = walk->user_input; list; list = list->next) { if ((error = git_commit_list_parse(walk, list->item)) < 0) goto cleanup; if ((error = git_pqueue_insert(&q, list->item)) < 0) goto cleanup; } while (interesting(&q)) { commit = git_pqueue_pop(&q); for (i = 0; i < commit->out_degree; i++) { parent = commit->parents[i]; if ((error = git_commit_list_parse(walk, parent)) < 0) goto cleanup; if (commit->uninteresting) parent->uninteresting = 1; if (contains(&q, parent)) continue; if ((error = git_pqueue_insert(&q, parent)) < 0) goto cleanup; } } cleanup: git_pqueue_free(&q); return error; }