summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-08-31 10:22:03 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2016-08-31 10:34:35 +0200
commitee0c8b595fb70c5e156529f0e3def1f0aa184f9e (patch)
tree654e509684f1ff0a06754752fb141d4cf2acee9e
parentecef50f9305ea819b753add74389dab39ad51572 (diff)
downloadlibgit2-ee0c8b595fb70c5e156529f0e3def1f0aa184f9e.tar.gz
revwalk: mark all incoming uninteresting commits' parents
Failing to do so can mean the priority queue never gets around to the unintersting commits that are older than the rest of the history.
-rw-r--r--src/revwalk.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/revwalk.c b/src/revwalk.c
index 1bd5b7e0a..5bccb5c3a 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -425,6 +425,38 @@ static int contains(git_pqueue *list, git_commit_list_node *node)
return 0;
}
+static void mark_parents_uninteresting(git_commit_list_node *commit)
+{
+ unsigned short i;
+ git_commit_list *parents = NULL;
+
+ for (i = 0; i < commit->out_degree; i++)
+ git_commit_list_insert(commit->parents[i], &parents);
+
+
+ while (parents) {
+ git_commit_list_node *commit = git_commit_list_pop(&parents);
+
+ while (commit) {
+ if (commit->uninteresting)
+ break;
+
+ commit->uninteresting = 1;
+ /*
+ * If we've reached this commit some other way
+ * already, we need to mark its parents uninteresting
+ * as well.
+ */
+ if (!commit->parents)
+ break;
+
+ for (i = 0; i < commit->out_degree; i++)
+ git_commit_list_insert(commit->parents[i], &parents);
+ commit = commit->parents[0];
+ }
+ }
+}
+
static int premark_uninteresting(git_revwalk *walk)
{
int error = 0;
@@ -440,6 +472,9 @@ static int premark_uninteresting(git_revwalk *walk)
if ((error = git_commit_list_parse(walk, list->item)) < 0)
goto cleanup;
+ if (list->item->uninteresting)
+ mark_parents_uninteresting(list->item);
+
if ((error = git_pqueue_insert(&q, list->item)) < 0)
goto cleanup;
}