1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.pgm;
12
13 import java.text.MessageFormat;
14 import java.util.ArrayList;
15 import java.util.EnumSet;
16 import java.util.List;
17
18 import org.eclipse.jgit.diff.DiffConfig;
19 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
20 import org.eclipse.jgit.lib.Constants;
21 import org.eclipse.jgit.lib.ObjectId;
22 import org.eclipse.jgit.lib.Ref;
23 import org.eclipse.jgit.pgm.internal.CLIText;
24 import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
25 import org.eclipse.jgit.revwalk.FollowFilter;
26 import org.eclipse.jgit.revwalk.ObjectWalk;
27 import org.eclipse.jgit.revwalk.RevCommit;
28 import org.eclipse.jgit.revwalk.RevFlag;
29 import org.eclipse.jgit.revwalk.RevObject;
30 import org.eclipse.jgit.revwalk.RevSort;
31 import org.eclipse.jgit.revwalk.RevWalk;
32 import org.eclipse.jgit.revwalk.filter.AndRevFilter;
33 import org.eclipse.jgit.revwalk.filter.AuthorRevFilter;
34 import org.eclipse.jgit.revwalk.filter.CommitterRevFilter;
35 import org.eclipse.jgit.revwalk.filter.MessageRevFilter;
36 import org.eclipse.jgit.revwalk.filter.RevFilter;
37 import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
38 import org.eclipse.jgit.treewalk.filter.TreeFilter;
39 import org.kohsuke.args4j.Argument;
40 import org.kohsuke.args4j.Option;
41
42 abstract class RevWalkTextBuiltin extends TextBuiltin {
43 RevWalk walk;
44
45 @Option(name = "--objects")
46 boolean objects = false;
47
48 @Option(name = "--parents")
49 boolean parents = false;
50
51 @Option(name = "--total-count")
52 boolean count = false;
53
54 @Option(name = "--all")
55 boolean all = false;
56
57 char[] outbuffer = new char[Constants.OBJECT_ID_LENGTH * 2];
58
59 private final EnumSet<RevSort> sorting = EnumSet.noneOf(RevSort.class);
60
61 private void enableRevSort(RevSort type, boolean on) {
62 if (on)
63 sorting.add(type);
64 else
65 sorting.remove(type);
66 }
67
68 @Option(name = "--date-order")
69 void enableDateOrder(boolean on) {
70 enableRevSort(RevSort.COMMIT_TIME_DESC, on);
71 }
72
73 @Option(name = "--topo-order")
74 void enableTopoOrder(boolean on) {
75 enableRevSort(RevSort.TOPO, on);
76 }
77
78 @Option(name = "--reverse")
79 void enableReverse(boolean on) {
80 enableRevSort(RevSort.REVERSE, on);
81 }
82
83 @Option(name = "--boundary")
84 void enableBoundary(boolean on) {
85 enableRevSort(RevSort.BOUNDARY, on);
86 }
87
88 @Option(name = "--follow", metaVar = "metaVar_path")
89 private String followPath;
90
91 @Argument(index = 0, metaVar = "metaVar_commitish")
92 private List<RevCommit> commits = new ArrayList<>();
93
94 @Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
95 protected TreeFilter pathFilter = TreeFilter.ALL;
96
97 private final List<RevFilter> revLimiter = new ArrayList<>();
98
99 @Option(name = "--author")
100 void addAuthorRevFilter(String who) {
101 revLimiter.add(AuthorRevFilter.create(who));
102 }
103
104 @Option(name = "--committer")
105 void addCommitterRevFilter(String who) {
106 revLimiter.add(CommitterRevFilter.create(who));
107 }
108
109 @Option(name = "--grep")
110 void addCMessageRevFilter(String msg) {
111 revLimiter.add(MessageRevFilter.create(msg));
112 }
113
114 @Option(name = "--max-count", aliases = "-n", metaVar = "metaVar_n")
115 private int maxCount = -1;
116
117
118 @Override
119 protected void run() throws Exception {
120 walk = createWalk();
121 for (RevSort s : sorting)
122 walk.sort(s, true);
123
124 if (pathFilter == TreeFilter.ALL) {
125 if (followPath != null)
126 walk.setTreeFilter(FollowFilter.create(followPath,
127 db.getConfig().get(DiffConfig.KEY)));
128 } else if (pathFilter != TreeFilter.ALL) {
129 walk.setTreeFilter(AndTreeFilter.create(pathFilter,
130 TreeFilter.ANY_DIFF));
131 }
132
133 if (revLimiter.size() == 1)
134 walk.setRevFilter(revLimiter.get(0));
135 else if (revLimiter.size() > 1)
136 walk.setRevFilter(AndRevFilter.create(revLimiter));
137
138 if (all) {
139 for (Ref a : db.getRefDatabase().getRefs()) {
140 ObjectId oid = a.getPeeledObjectId();
141 if (oid == null)
142 oid = a.getObjectId();
143 try {
144 commits.add(walk.parseCommit(oid));
145 } catch (IncorrectObjectTypeException e) {
146
147 }
148 }
149 }
150
151 if (commits.isEmpty()) {
152 final ObjectId head = db.resolve(Constants.HEAD);
153 if (head == null)
154 throw die(MessageFormat.format(CLIText.get().cannotResolve, Constants.HEAD));
155 commits.add(walk.parseCommit(head));
156 }
157 for (RevCommit c : commits) {
158 final RevCommit real = argWalk == walk ? c : walk.parseCommit(c);
159 if (c.has(RevFlag.UNINTERESTING))
160 walk.markUninteresting(real);
161 else
162 walk.markStart(real);
163 }
164
165 final long start = System.currentTimeMillis();
166 final int n = walkLoop();
167 if (count) {
168 final long end = System.currentTimeMillis();
169 errw.print(n);
170 errw.print(' ');
171 errw.println(MessageFormat.format(
172 CLIText.get().timeInMilliSeconds,
173 Long.valueOf(end - start)));
174 }
175 }
176
177
178
179
180
181
182 protected RevWalk createWalk() {
183 RevWalk result;
184 if (objects)
185 result = new ObjectWalk(db);
186 else if (argWalk != null)
187 result = argWalk;
188 else
189 result = argWalk = new RevWalk(db);
190 result.setRewriteParents(false);
191 return result;
192 }
193
194
195
196
197
198
199
200
201 protected int walkLoop() throws Exception {
202 int n = 0;
203 for (RevCommit c : walk) {
204 if (++n > maxCount && maxCount >= 0)
205 break;
206 show(c);
207 }
208 if (walk instanceof ObjectWalk) {
209 final ObjectWalk../../../../org/eclipse/jgit/revwalk/ObjectWalk.html#ObjectWalk">ObjectWalk ow = (ObjectWalk) walk;
210 for (;;) {
211 final RevObject obj = ow.nextObject();
212 if (obj == null)
213 break;
214 show(ow, obj);
215 }
216 }
217 return n;
218 }
219
220
221
222
223
224
225
226
227
228
229
230 protected abstract void show(RevCommit c) throws Exception;
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245 protected void show(final ObjectWalk objectWalk,
246 final RevObject currentObject) throws Exception {
247
248 }
249 }