diff options
author | Carlos Martín Nieto <cmn@dwim.me> | 2016-08-31 10:22:03 +0200 |
---|---|---|
committer | Carlos Martín Nieto <cmn@dwim.me> | 2016-08-31 10:34:35 +0200 |
commit | ee0c8b595fb70c5e156529f0e3def1f0aa184f9e (patch) | |
tree | 654e509684f1ff0a06754752fb141d4cf2acee9e | |
parent | ecef50f9305ea819b753add74389dab39ad51572 (diff) | |
download | libgit2-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.c | 35 |
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; } |