1 /*
2 * Copyright (C) 2010, Garmin International
3 * Copyright (C) 2010, Matt Fischer <matt.fischer@garmin.com>
4 * and other copyright owners as documented in the project's IP log.
5 *
6 * This program and the accompanying materials are made available
7 * under the terms of the Eclipse Distribution License v1.0 which
8 * accompanies this distribution, is reproduced below, and is
9 * available at http://www.eclipse.org/org/documents/edl-v10.php
10 *
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or
14 * without modification, are permitted provided that the following
15 * conditions are met:
16 *
17 * - Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials provided
23 * with the distribution.
24 *
25 * - Neither the name of the Eclipse Foundation, Inc. nor the
26 * names of its contributors may be used to endorse or promote
27 * products derived from this software without specific prior
28 * written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
31 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
32 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
35 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
37 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
42 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */
44
45 package org.eclipse.jgit.revwalk;
46
47 import java.io.IOException;
48
49 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
50 import org.eclipse.jgit.errors.MissingObjectException;
51 import org.eclipse.jgit.lib.AnyObjectId;
52 import org.eclipse.jgit.lib.ObjectReader;
53 import org.eclipse.jgit.lib.Repository;
54
55 /** Interface for revision walkers that perform depth filtering. */
56 public interface DepthWalk {
57 /** @return Depth to filter to. */
58 public int getDepth();
59
60 /** @return flag marking commits that should become unshallow. */
61 public RevFlag getUnshallowFlag();
62
63 /** @return flag marking commits that are interesting again. */
64 public RevFlag getReinterestingFlag();
65
66 /** RevCommit with a depth (in commits) from a root. */
67 public static class Commit extends RevCommit {
68 /** Depth of this commit in the graph, via shortest path. */
69 int depth;
70
71 /** @return depth of this commit, as found by the shortest path. */
72 public int getDepth() {
73 return depth;
74 }
75
76 /**
77 * Initialize a new commit.
78 *
79 * @param id
80 * object name for the commit.
81 */
82 protected Commit(AnyObjectId id) {
83 super(id);
84 depth = -1;
85 }
86 }
87
88 /** Subclass of RevWalk that performs depth filtering. */
89 public class RevWalk extends org.eclipse.jgit.revwalk.RevWalk implements DepthWalk {
90 private final int depth;
91
92 private final RevFlag UNSHALLOW;
93
94 private final RevFlag REINTERESTING;
95
96 /**
97 * @param repo Repository to walk
98 * @param depth Maximum depth to return
99 */
100 public RevWalk(Repository repo, int depth) {
101 super(repo);
102
103 this.depth = depth;
104 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
105 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
106 }
107
108 /**
109 * @param or ObjectReader to use
110 * @param depth Maximum depth to return
111 */
112 public RevWalk(ObjectReader or, int depth) {
113 super(or);
114
115 this.depth = depth;
116 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
117 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
118 }
119
120 /**
121 * Mark a root commit (i.e., one whose depth should be considered 0.)
122 *
123 * @param c
124 * Commit to mark
125 * @throws IOException
126 * @throws IncorrectObjectTypeException
127 * @throws MissingObjectException
128 */
129 public void markRoot(RevCommit c) throws MissingObjectException,
130 IncorrectObjectTypeException, IOException {
131 if (c instanceof Commit)
132 ((Commit) c).depth = 0;
133 super.markStart(c);
134 }
135
136 @Override
137 protected RevCommit createCommit(AnyObjectId id) {
138 return new Commit(id);
139 }
140
141 @Override
142 public int getDepth() {
143 return depth;
144 }
145
146 @Override
147 public RevFlag getUnshallowFlag() {
148 return UNSHALLOW;
149 }
150
151 @Override
152 public RevFlag getReinterestingFlag() {
153 return REINTERESTING;
154 }
155
156 /**
157 * @since 4.5
158 */
159 @Override
160 public ObjectWalk toObjectWalkWithSameObjects() {
161 ObjectWalk ow = new ObjectWalk(reader, depth);
162 ow.objects = objects;
163 ow.freeFlags = freeFlags;
164 return ow;
165 }
166 }
167
168 /** Subclass of ObjectWalk that performs depth filtering. */
169 public class ObjectWalk extends org.eclipse.jgit.revwalk.ObjectWalk implements DepthWalk {
170 private final int depth;
171
172 private final RevFlag UNSHALLOW;
173
174 private final RevFlag REINTERESTING;
175
176 /**
177 * @param repo Repository to walk
178 * @param depth Maximum depth to return
179 */
180 public ObjectWalk(Repository repo, int depth) {
181 super(repo);
182
183 this.depth = depth;
184 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
185 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
186 }
187
188 /**
189 * @param or Object Reader
190 * @param depth Maximum depth to return
191 */
192 public ObjectWalk(ObjectReader or, int depth) {
193 super(or);
194
195 this.depth = depth;
196 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
197 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
198 }
199
200 /**
201 * Mark a root commit (i.e., one whose depth should be considered 0.)
202 *
203 * @param o
204 * Commit to mark
205 * @throws IOException
206 * @throws IncorrectObjectTypeException
207 * @throws MissingObjectException
208 */
209 public void markRoot(RevObject o) throws MissingObjectException,
210 IncorrectObjectTypeException, IOException {
211 RevObject c = o;
212 while (c instanceof RevTag) {
213 c = ((RevTag) c).getObject();
214 parseHeaders(c);
215 }
216 if (c instanceof Commit)
217 ((Commit) c).depth = 0;
218 super.markStart(o);
219 }
220
221 /**
222 * Mark an element which used to be shallow in the client, but which
223 * should now be considered a full commit. Any ancestors of this commit
224 * should be included in the walk, even if they are the ancestor of an
225 * uninteresting commit.
226 *
227 * @param c
228 * Commit to mark
229 * @throws MissingObjectException
230 * @throws IncorrectObjectTypeException
231 * @throws IOException
232 */
233 public void markUnshallow(RevObject c) throws MissingObjectException,
234 IncorrectObjectTypeException, IOException {
235 if (c instanceof RevCommit)
236 c.add(UNSHALLOW);
237 super.markStart(c);
238 }
239
240 @Override
241 protected RevCommit createCommit(AnyObjectId id) {
242 return new Commit(id);
243 }
244
245 @Override
246 public int getDepth() {
247 return depth;
248 }
249
250 @Override
251 public RevFlag getUnshallowFlag() {
252 return UNSHALLOW;
253 }
254
255 @Override
256 public RevFlag getReinterestingFlag() {
257 return REINTERESTING;
258 }
259 }
260 }