View Javadoc
1   /*
2    * Copyright (C) 2012, Marc Strapetz <marc.strapetz@syntevo.com>
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.revwalk;
45  
46  import static org.junit.Assert.assertNull;
47  
48  import java.io.File;
49  import java.io.IOException;
50  
51  import org.eclipse.jgit.junit.JGitTestUtil;
52  import org.eclipse.jgit.lib.ObjectId;
53  import org.junit.Test;
54  
55  public class RevWalkShallowTest extends RevWalkTestCase {
56  
57  	// Accessing ==============================================================
58  
59  	@Test
60  	public void testDepth1() throws Exception {
61  		RevCommit[] commits = setupLinearChain();
62  
63  		createShallowFile(commits[3]);
64  		updateCommits(commits);
65  
66  		rw.markStart(commits[3]);
67  		assertCommit(commits[3], rw.next());
68  		assertNull(rw.next());
69  	}
70  
71  	@Test
72  	public void testDepth2() throws Exception {
73  		RevCommit[] commits = setupLinearChain();
74  
75  		createShallowFile(commits[2]);
76  		updateCommits(commits);
77  
78  		rw.markStart(commits[3]);
79  		assertCommit(commits[3], rw.next());
80  		assertCommit(commits[2], rw.next());
81  		assertNull(rw.next());
82  	}
83  
84  	@Test
85  	public void testDepth3() throws Exception {
86  		RevCommit[] commits = setupLinearChain();
87  
88  		createShallowFile(commits[1]);
89  		updateCommits(commits);
90  
91  		rw.markStart(commits[3]);
92  		assertCommit(commits[3], rw.next());
93  		assertCommit(commits[2], rw.next());
94  		assertCommit(commits[1], rw.next());
95  		assertNull(rw.next());
96  	}
97  
98  	@Test
99  	public void testObjectDirectorySnapshot() throws Exception {
100 		RevCommit[] commits = setupLinearChain();
101 
102 		createShallowFile(commits[3]);
103 		updateCommits(commits);
104 
105 		markStart(commits[3]);
106 		assertCommit(commits[3], rw.next());
107 		assertNull(rw.next());
108 
109 		createShallowFile(commits[2]);
110 		updateCommits(commits);
111 
112 		markStart(commits[3]);
113 		assertCommit(commits[3], rw.next());
114 		assertCommit(commits[2], rw.next());
115 		assertNull(rw.next());
116 	}
117 
118 	private RevCommit[] setupLinearChain() throws Exception {
119 		RevCommit[] commits = new RevCommit[4];
120 		RevCommit parent = null;
121 		for (int i = 0; i < commits.length; i++) {
122 			commits[i] = parent != null ? commit(parent) : commit();
123 			parent = commits[i];
124 		}
125 		return commits;
126 	}
127 
128 	@Test
129 	public void testMergeCommitOneParentShallow() throws Exception {
130 		RevCommit[] commits = setupMergeChain();
131 
132 		createShallowFile(commits[4]);
133 		updateCommits(commits);
134 
135 		markStart(commits[5]);
136 		assertCommit(commits[5], rw.next());
137 		assertCommit(commits[4], rw.next());
138 		assertCommit(commits[2], rw.next());
139 		assertCommit(commits[1], rw.next());
140 		assertCommit(commits[0], rw.next());
141 		assertNull(rw.next());
142 	}
143 
144 	@Test
145 	public void testMergeCommitEntirelyShallow() throws Exception {
146 		RevCommit[] commits = setupMergeChain();
147 
148 		createShallowFile(commits[2], commits[4]);
149 		updateCommits(commits);
150 
151 		markStart(commits[5]);
152 		assertCommit(commits[5], rw.next());
153 		assertCommit(commits[4], rw.next());
154 		assertCommit(commits[2], rw.next());
155 		assertNull(rw.next());
156 	}
157 
158 	private RevCommit[] setupMergeChain() throws Exception {
159 		/*-
160 		 * Create a history like this, diverging at 1 and merging at 5:
161 		 *
162 		 *      ---o--o       commits 3,4
163 		 *     /       \
164 		 * o--o--o------o   commits 0,1,2,5
165 		 */
166 		RevCommit[] commits = new RevCommit[6];
167 		commits[0] = commit();
168 		commits[1] = commit(commits[0]);
169 		commits[2] = commit(commits[1]);
170 		commits[3] = commit(commits[1]);
171 		commits[4] = commit(commits[3]);
172 		commits[5] = commit(commits[2], commits[4]);
173 		return commits;
174 	}
175 
176 	private void updateCommits(RevCommit[] commits) {
177 		// Relookup commits using the new RevWalk
178 		for (int i = 0; i < commits.length; i++) {
179 			commits[i] = rw.lookupCommit(commits[i].getId());
180 		}
181 	}
182 
183 	private void createShallowFile(ObjectId... shallowCommits)
184 			throws IOException {
185 		// Reset the RevWalk since the new shallow file invalidates the existing
186 		// RevWalk's shallow state.
187 		rw.close();
188 		rw = createRevWalk();
189 		StringBuilder builder = new StringBuilder();
190 		for (ObjectId commit : shallowCommits) {
191 			builder.append(commit.getName() + "\n");
192 		}
193 		JGitTestUtil.write(new File(db.getDirectory(), "shallow"),
194 				builder.toString());
195 	}
196 
197 	@Test
198 	public void testShallowCommitParse() throws Exception {
199 		RevCommit a = commit();
200 		RevCommit b = commit(a);
201 
202 		createShallowFile(b);
203 
204 		rw.close();
205 		rw = createRevWalk();
206 		b = rw.parseCommit(b);
207 
208 		markStart(b);
209 		assertCommit(b, rw.next());
210 		assertNull(rw.next());
211 	}
212 }