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 if (parents) {
133 walk.setRewriteParents(true);
134 }
135
136 if (revLimiter.size() == 1)
137 walk.setRevFilter(revLimiter.get(0));
138 else if (revLimiter.size() > 1)
139 walk.setRevFilter(AndRevFilter.create(revLimiter));
140
141 if (all) {
142 for (Ref a : db.getRefDatabase().getRefs()) {
143 ObjectId oid = a.getPeeledObjectId();
144 if (oid == null)
145 oid = a.getObjectId();
146 try {
147 commits.add(walk.parseCommit(oid));
148 } catch (IncorrectObjectTypeException e) {
149
150 }
151 }
152 }
153
154 if (commits.isEmpty()) {
155 final ObjectId head = db.resolve(Constants.HEAD);
156 if (head == null)
157 throw die(MessageFormat.format(CLIText.get().cannotResolve, Constants.HEAD));
158 commits.add(walk.parseCommit(head));
159 }
160 for (RevCommit c : commits) {
161 final RevCommit real = argWalk == walk ? c : walk.parseCommit(c);
162 if (c.has(RevFlag.UNINTERESTING))
163 walk.markUninteresting(real);
164 else
165 walk.markStart(real);
166 }
167
168 final long start = System.currentTimeMillis();
169 final int n = walkLoop();
170 if (count) {
171 final long end = System.currentTimeMillis();
172 errw.print(n);
173 errw.print(' ');
174 errw.println(MessageFormat.format(
175 CLIText.get().timeInMilliSeconds,
176 Long.valueOf(end - start)));
177 }
178 }
179
180
181
182
183
184
185 protected RevWalk createWalk() {
186 RevWalk result;
187 if (objects)
188 result = new ObjectWalk(db);
189 else if (argWalk != null)
190 result = argWalk;
191 else
192 result = argWalk = new RevWalk(db);
193 result.setRewriteParents(false);
194 return result;
195 }
196
197
198
199
200
201
202
203
204 protected int walkLoop() throws Exception {
205 int n = 0;
206 for (RevCommit c : walk) {
207 if (++n > maxCount && maxCount >= 0)
208 break;
209 show(c);
210 }
211 if (walk instanceof ObjectWalk) {
212 final ObjectWalk ow = (ObjectWalk) walk;
213 for (;;) {
214 final RevObject obj = ow.nextObject();
215 if (obj == null)
216 break;
217 show(ow, obj);
218 }
219 }
220 return n;
221 }
222
223
224
225
226
227
228
229
230
231
232
233 protected abstract void show(RevCommit c) throws Exception;
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248 protected void show(final ObjectWalk objectWalk,
249 final RevObject currentObject) throws Exception {
250
251 }
252 }