summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/revwalk.c73
1 files changed, 36 insertions, 37 deletions
diff --git a/src/revwalk.c b/src/revwalk.c
index 727bcd7a1..f5fdc4932 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -268,18 +268,16 @@ static int commit_parse(git_revwalk *walk, commit_object *commit)
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to parse commit");
}
-static commit_object *interesting(commit_list *list)
+static int interesting(git_pqueue *list)
{
- while (list) {
- commit_object *commit = list->item;
- list = list->next;
- if (commit->flags & STALE)
- continue;
-
- return commit;
+ unsigned int i;
+ for (i = 1; i < git_pqueue_size(list); i++) {
+ commit_object *commit = list->d[i];
+ if ((commit->flags & STALE) == 0)
+ return 1;
}
- return NULL;
+ return 0;
}
static int merge_bases_many(commit_list **out, git_revwalk *walk, commit_object *one, git_vector *twos)
@@ -287,44 +285,45 @@ static int merge_bases_many(commit_list **out, git_revwalk *walk, commit_object
int error;
unsigned int i;
commit_object *two;
- commit_list *list = NULL, *result = NULL;
+ commit_list *result = NULL, *tmp = NULL;
+ git_pqueue list;
/* if the commit is repeated, we have a our merge base already */
git_vector_foreach(twos, i, two) {
if (one == two)
- return commit_list_insert(one, out) ? GIT_SUCCESS : GIT_ENOMEM;
+ return commit_list_insert(one, out) ? 0 : -1;
}
- if ((error = commit_parse(walk, one)) < GIT_SUCCESS)
- return error;
+ if (git_pqueue_init(&list, twos->length * 2, commit_time_cmp) < 0)
+ return -1;
+
+ if (commit_parse(walk, one) < 0)
+ return -1;
one->flags |= PARENT1;
- if (commit_list_insert(one, &list) == NULL)
- return GIT_ENOMEM;
+ if (git_pqueue_insert(&list, one) < 0)
+ return -1;
git_vector_foreach(twos, i, two) {
commit_parse(walk, two);
two->flags |= PARENT2;
- if (commit_list_insert_by_date(two, &list) == NULL)
- return GIT_ENOMEM;
+ if (git_pqueue_insert(&list, two) < 0)
+ return -1;
}
/* as long as there are non-STALE commits */
- while (interesting(list)) {
- commit_object *commit = list->item;
- commit_list *next;
+ while (interesting(&list)) {
+ commit_object *commit;
int flags;
- next = list->next;
- git__free(list);
- list = next;
+ commit = git_pqueue_pop(&list);
flags = commit->flags & (PARENT1 | PARENT2 | STALE);
if (flags == (PARENT1 | PARENT2)) {
if (!(commit->flags & RESULT)) {
commit->flags |= RESULT;
- if (commit_list_insert_by_date(commit, &result) == NULL)
- return GIT_ENOMEM;
+ if (commit_list_insert(commit, &result) == NULL)
+ return -1;
}
/* we mark the parents of a merge stale */
flags |= STALE;
@@ -339,29 +338,29 @@ static int merge_bases_many(commit_list **out, git_revwalk *walk, commit_object
return error;
p->flags |= flags;
- if (commit_list_insert_by_date(p, &list) == NULL)
- return GIT_ENOMEM;
+ if (git_pqueue_insert(&list, p) < 0)
+ return -1;
}
}
- commit_list_free(&list);
+ git_pqueue_free(&list);
/* filter out any stale commits in the results */
- list = result;
+ tmp = result;
result = NULL;
- while (list) {
- struct commit_list *next = list->next;
- if (!(list->item->flags & STALE))
- if (commit_list_insert_by_date(list->item, &result) == NULL)
- return GIT_ENOMEM;
+ while (tmp) {
+ struct commit_list *next = tmp->next;
+ if (!(tmp->item->flags & STALE))
+ if (commit_list_insert_by_date(tmp->item, &result) == NULL)
+ return -1;
- free(list);
- list = next;
+ git__free(tmp);
+ tmp = next;
}
*out = result;
- return GIT_SUCCESS;
+ return 0;
}
int git_merge_base(git_oid *out, git_repository *repo, git_oid *one, git_oid *two)