Allow RevWalk's flag carrying behavior to be overridden
[egit/zawir.git] / org.spearce.jgit / src / org / spearce / jgit / revwalk / PendingGenerator.java
blobb71313132cd3badfc904a0ba62cced9446decf6e
1 /*
2 * Copyright (C) 2008 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org.spearce.jgit.revwalk;
19 import java.io.IOException;
21 import org.spearce.jgit.errors.IncorrectObjectTypeException;
22 import org.spearce.jgit.errors.MissingObjectException;
23 import org.spearce.jgit.errors.StopWalkException;
24 import org.spearce.jgit.revwalk.filter.RevFilter;
26 /**
27 * Default (and first pass) RevCommit Generator implementation for RevWalk.
28 * <p>
29 * This generator starts from a set of one or more commits and process them in
30 * descending (newest to oldest) commit time order. Commits automatically cause
31 * their parents to be enqueued for further processing, allowing the entire
32 * commit graph to be walked. A {@link RevFilter} may be used to select a subset
33 * of the commits and return them to the caller.
35 class PendingGenerator extends Generator {
36 private static final int PARSED = RevWalk.PARSED;
38 private static final int SEEN = RevWalk.SEEN;
40 private static final int UNINTERESTING = RevWalk.UNINTERESTING;
42 private final RevWalk walker;
44 private final AbstractRevQueue pending;
46 private final RevFilter filter;
48 private final int output;
50 boolean canDispose;
52 PendingGenerator(final RevWalk w, final AbstractRevQueue p,
53 final RevFilter f, final int out) {
54 walker = w;
55 pending = p;
56 filter = f;
57 output = out;
58 canDispose = true;
61 @Override
62 int outputType() {
63 if (pending instanceof DateRevQueue)
64 return output | SORT_COMMIT_TIME_DESC;
65 return output;
68 @Override
69 RevCommit next() throws MissingObjectException,
70 IncorrectObjectTypeException, IOException {
71 try {
72 for (;;) {
73 final RevCommit c = pending.next();
74 if (c == null) {
75 walker.curs.release();
76 return null;
79 final boolean produce;
80 if ((c.flags & UNINTERESTING) != 0)
81 produce = false;
82 else
83 produce = filter.include(walker, c);
85 for (final RevCommit p : c.parents) {
86 if ((p.flags & SEEN) != 0)
87 continue;
88 if ((p.flags & PARSED) == 0)
89 p.parse(walker);
90 p.flags |= SEEN;
91 pending.add(p);
93 walker.carryFlagsImpl(c);
95 if ((c.flags & UNINTERESTING) != 0) {
96 if (pending.everbodyHasFlag(UNINTERESTING))
97 throw StopWalkException.INSTANCE;
98 c.dispose();
99 continue;
102 if (produce)
103 return c;
104 else if (canDispose)
105 c.dispose();
107 } catch (StopWalkException swe) {
108 walker.curs.release();
109 pending.clear();
110 return null;