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 public int getDepth() {
142 return depth;
143 }
144
145 public RevFlag getUnshallowFlag() {
146 return UNSHALLOW;
147 }
148
149 public RevFlag getReinterestingFlag() {
150 return REINTERESTING;
151 }
152 }
153
154 /** Subclass of ObjectWalk that performs depth filtering. */
155 public class ObjectWalk extends org.eclipse.jgit.revwalk.ObjectWalk implements DepthWalk {
156 private final int depth;
157
158 private final RevFlag UNSHALLOW;
159
160 private final RevFlag REINTERESTING;
161
162 /**
163 * @param repo Repository to walk
164 * @param depth Maximum depth to return
165 */
166 public ObjectWalk(Repository repo, int depth) {
167 super(repo);
168
169 this.depth = depth;
170 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
171 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
172 }
173
174 /**
175 * @param or Object Reader
176 * @param depth Maximum depth to return
177 */
178 public ObjectWalk(ObjectReader or, int depth) {
179 super(or);
180
181 this.depth = depth;
182 this.UNSHALLOW = newFlag("UNSHALLOW"); //$NON-NLS-1$
183 this.REINTERESTING = newFlag("REINTERESTING"); //$NON-NLS-1$
184 }
185
186 /**
187 * Mark a root commit (i.e., one whose depth should be considered 0.)
188 *
189 * @param o
190 * Commit to mark
191 * @throws IOException
192 * @throws IncorrectObjectTypeException
193 * @throws MissingObjectException
194 */
195 public void markRoot(RevObject o) throws MissingObjectException,
196 IncorrectObjectTypeException, IOException {
197 RevObject c = o;
198 while (c instanceof RevTag) {
199 c = ((RevTag) c).getObject();
200 parseHeaders(c);
201 }
202 if (c instanceof Commit)
203 ((Commit) c).depth = 0;
204 super.markStart(o);
205 }
206
207 /**
208 * Mark an element which used to be shallow in the client, but which
209 * should now be considered a full commit. Any ancestors of this commit
210 * should be included in the walk, even if they are the ancestor of an
211 * uninteresting commit.
212 *
213 * @param c
214 * Commit to mark
215 * @throws MissingObjectException
216 * @throws IncorrectObjectTypeException
217 * @throws IOException
218 */
219 public void markUnshallow(RevObject c) throws MissingObjectException,
220 IncorrectObjectTypeException, IOException {
221 if (c instanceof RevCommit)
222 c.add(UNSHALLOW);
223 super.markStart(c);
224 }
225
226 @Override
227 protected RevCommit createCommit(AnyObjectId id) {
228 return new Commit(id);
229 }
230
231 public int getDepth() {
232 return depth;
233 }
234
235 public RevFlag getUnshallowFlag() {
236 return UNSHALLOW;
237 }
238
239 public RevFlag getReinterestingFlag() {
240 return REINTERESTING;
241 }
242 }
243 }