Treat the absence of a Git index as an empty index.
[egit.git] / org.spearce.jgit / tst / org / spearce / jgit / lib / T0007_Index.java
blobf4b2f83a2738ec8981d09f33e0114c2d9413903d
1 package org.spearce.jgit.lib;
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.lang.reflect.InvocationTargetException;
8 import java.lang.reflect.Method;
10 import org.spearce.jgit.lib.GitIndex.Entry;
12 public class T0007_Index extends RepositoryTestCase {
14 static boolean canrungitstatus;
15 static {
16 try {
17 canrungitstatus = system(new File("."),"git --version") == 0;
18 } catch (IOException e) {
19 System.out.println("Warning: cannot invvoke native git to validate index");
20 } catch (InterruptedException e) {
21 e.printStackTrace();
25 private static int system(File dir, String cmd) throws IOException,
26 InterruptedException {
27 final Process process = Runtime.getRuntime().exec(cmd, null, dir);
28 new Thread() {
29 public void run() {
30 try {
31 InputStream s = process.getErrorStream();
32 for (int c = s.read(); c != -1; c = s.read()) {
33 System.err.print((char) c);
35 s.close();
36 } catch (IOException e1) {
37 // TODO Auto-generated catch block
38 e1.printStackTrace();
41 }.start();
42 final Thread t2 = new Thread() {
43 public void run() {
44 synchronized (this) {
45 try {
46 InputStream e = process.getInputStream();
47 for (int c = e.read(); c != -1; c = e.read()) {
48 System.out.print((char) c);
50 e.close();
51 } catch (IOException e1) {
52 // TODO Auto-generated catch block
53 e1.printStackTrace();
58 t2.start();
59 process.getOutputStream().close();
60 int ret = process.waitFor();
61 synchronized (t2) {
62 return ret;
66 public void testCreateEmptyIndex() throws Exception {
67 GitIndex index = new GitIndex(db);
68 index.write();
69 // native git doesn't like an empty index
70 // assertEquals(0,system(trash,"git status"));
72 GitIndex indexr = new GitIndex(db);
73 indexr.read();
74 assertEquals(0, indexr.getMembers().length);
77 public void testReadWithNoIndex() throws Exception {
78 GitIndex index = new GitIndex(db);
79 index.read();
80 assertEquals(0, index.getMembers().length);
83 public void testCreateSimpleSortTestIndex() throws Exception {
84 GitIndex index = new GitIndex(db);
85 writeTrashFile("a/b", "data:a/b");
86 writeTrashFile("a:b", "data:a:b");
87 writeTrashFile("a.b", "data:a.b");
88 index.add(trash, new File(trash, "a/b"));
89 index.add(trash, new File(trash, "a:b"));
90 index.add(trash, new File(trash, "a.b"));
91 index.write();
93 assertEquals("a/b", index.getEntry("a/b").getName());
94 assertEquals("a:b", index.getEntry("a:b").getName());
95 assertEquals("a.b", index.getEntry("a.b").getName());
96 assertNull(index.getEntry("a*b"));
98 // Repeat test for re-read index
99 GitIndex indexr = new GitIndex(db);
100 indexr.read();
101 assertEquals("a/b", indexr.getEntry("a/b").getName());
102 assertEquals("a:b", indexr.getEntry("a:b").getName());
103 assertEquals("a.b", indexr.getEntry("a.b").getName());
104 assertNull(indexr.getEntry("a*b"));
106 if (canrungitstatus)
107 assertEquals(0, system(trash, "git status"));
110 public void testUpdateSimpleSortTestIndex() throws Exception {
111 GitIndex index = new GitIndex(db);
112 writeTrashFile("a/b", "data:a/b");
113 writeTrashFile("a:b", "data:a:b");
114 writeTrashFile("a.b", "data:a.b");
115 index.add(trash, new File(trash, "a/b"));
116 index.add(trash, new File(trash, "a:b"));
117 index.add(trash, new File(trash, "a.b"));
118 writeTrashFile("a/b", "data:a/b modified");
119 index.add(trash, new File(trash, "a/b"));
120 index.write();
121 if (canrungitstatus)
122 assertEquals(0, system(trash, "git status"));
125 public void testWriteTree() throws Exception {
126 GitIndex index = new GitIndex(db);
127 writeTrashFile("a/b", "data:a/b");
128 writeTrashFile("a:b", "data:a:b");
129 writeTrashFile("a.b", "data:a.b");
130 index.add(trash, new File(trash, "a/b"));
131 index.add(trash, new File(trash, "a:b"));
132 index.add(trash, new File(trash, "a.b"));
133 index.write();
135 ObjectId id = index.writeTree();
136 assertEquals("c696abc3ab8e091c665f49d00eb8919690b3aec3", id.toString());
138 writeTrashFile("a/b", "data:a/b");
139 index.add(trash, new File(trash, "a/b"));
141 if (canrungitstatus)
142 assertEquals(0, system(trash, "git status"));
145 public void testReadTree() throws Exception {
146 // Prepare tree
147 GitIndex index = new GitIndex(db);
148 writeTrashFile("a/b", "data:a/b");
149 writeTrashFile("a:b", "data:a:b");
150 writeTrashFile("a.b", "data:a.b");
151 index.add(trash, new File(trash, "a/b"));
152 index.add(trash, new File(trash, "a:b"));
153 index.add(trash, new File(trash, "a.b"));
154 index.write();
156 ObjectId id = index.writeTree();
157 System.out.println("wrote id " + id);
158 assertEquals("c696abc3ab8e091c665f49d00eb8919690b3aec3", id.toString());
159 GitIndex index2 = new GitIndex(db);
161 index2.readTree(db.mapTree(new ObjectId(
162 "c696abc3ab8e091c665f49d00eb8919690b3aec3")));
163 Entry[] members = index2.getMembers();
164 assertEquals(3, members.length);
165 assertEquals("a.b", members[0].getName());
166 assertEquals("a/b", members[1].getName());
167 assertEquals("a:b", members[2].getName());
168 assertEquals(3, members.length);
170 GitIndex indexr = new GitIndex(db);
171 indexr.read();
172 Entry[] membersr = indexr.getMembers();
173 assertEquals(3, membersr.length);
174 assertEquals("a.b", membersr[0].getName());
175 assertEquals("a/b", membersr[1].getName());
176 assertEquals("a:b", membersr[2].getName());
177 assertEquals(3, membersr.length);
179 if (canrungitstatus)
180 assertEquals(0, system(trash, "git status"));
183 public void testReadTree2() throws Exception {
184 // Prepare a larger tree to test some odd cases in tree writing
185 GitIndex index = new GitIndex(db);
186 File f1 = writeTrashFile("a/a/a/a", "data:a/a/a/a");
187 File f2 = writeTrashFile("a/c/c", "data:a/c/c");
188 File f3 = writeTrashFile("a/b", "data:a/b");
189 File f4 = writeTrashFile("a:b", "data:a:b");
190 File f5 = writeTrashFile("a/d", "data:a/d");
191 File f6 = writeTrashFile("a.b", "data:a.b");
192 index.add(trash, f1);
193 index.add(trash, f2);
194 index.add(trash, f3);
195 index.add(trash, f4);
196 index.add(trash, f5);
197 index.add(trash, f6);
198 index.write();
199 ObjectId id = index.writeTree();
200 System.out.println("wrote id " + id);
201 assertEquals("ba78e065e2c261d4f7b8f42107588051e87e18e9", id.toString());
202 GitIndex index2 = new GitIndex(db);
204 index2.readTree(db.mapTree(new ObjectId(
205 "ba78e065e2c261d4f7b8f42107588051e87e18e9")));
206 Entry[] members = index2.getMembers();
207 assertEquals(6, members.length);
208 assertEquals("a.b", members[0].getName());
209 assertEquals("a/a/a/a", members[1].getName());
210 assertEquals("a/b", members[2].getName());
211 assertEquals("a/c/c", members[3].getName());
212 assertEquals("a/d", members[4].getName());
213 assertEquals("a:b", members[5].getName());
215 // reread and test
216 GitIndex indexr = new GitIndex(db);
217 indexr.read();
218 Entry[] membersr = indexr.getMembers();
219 assertEquals(6, membersr.length);
220 assertEquals("a.b", membersr[0].getName());
221 assertEquals("a/a/a/a", membersr[1].getName());
222 assertEquals("a/b", membersr[2].getName());
223 assertEquals("a/c/c", membersr[3].getName());
224 assertEquals("a/d", membersr[4].getName());
225 assertEquals("a:b", membersr[5].getName());
228 public void testDelete() throws Exception {
229 GitIndex index = new GitIndex(db);
230 writeTrashFile("a/b", "data:a/b");
231 writeTrashFile("a:b", "data:a:b");
232 writeTrashFile("a.b", "data:a.b");
233 index.add(trash, new File(trash, "a/b"));
234 index.add(trash, new File(trash, "a:b"));
235 index.add(trash, new File(trash, "a.b"));
236 index.write();
237 index.writeTree();
238 index.remove(trash, new File(trash, "a:b"));
239 index.write();
240 assertEquals("a.b", index.getMembers()[0].getName());
241 assertEquals("a/b", index.getMembers()[1].getName());
243 GitIndex indexr = new GitIndex(db);
244 indexr.read();
245 assertEquals("a.b", indexr.getMembers()[0].getName());
246 assertEquals("a/b", indexr.getMembers()[1].getName());
248 if (canrungitstatus)
249 assertEquals(0, system(trash, "git status"));
252 public void testCheckout() throws Exception {
253 // Prepare tree, remote it and checkout
254 GitIndex index = new GitIndex(db);
255 File aslashb = writeTrashFile("a/b", "data:a/b");
256 File acolonb = writeTrashFile("a:b", "data:a:b");
257 File adotb = writeTrashFile("a.b", "data:a.b");
258 index.add(trash, aslashb);
259 index.add(trash, acolonb);
260 index.add(trash, adotb);
261 index.write();
262 index.writeTree();
263 delete(aslashb);
264 delete(acolonb);
265 delete(adotb);
266 delete(aslashb.getParentFile());
268 GitIndex index2 = new GitIndex(db);
269 assertEquals(0, index2.getMembers().length);
271 index2.readTree(db.mapTree(new ObjectId(
272 "c696abc3ab8e091c665f49d00eb8919690b3aec3")));
274 index2.checkout(trash);
275 assertEquals("data:a/b", content(aslashb));
276 assertEquals("data:a:b", content(acolonb));
277 assertEquals("data:a.b", content(adotb));
279 if (canrungitstatus)
280 assertEquals(0, system(trash, "git status"));
283 public void test030_executeBit_coreModeTrue() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
284 try {
285 // coremode true is the default, typically set to false
286 // by git init (but not jgit!)
287 Method canExecute = File.class.getMethod("canExecute", (Class[])null);
288 Method setExecute = File.class.getMethod("setExecutable", new Class[] { Boolean.TYPE });
289 File execFile = writeTrashFile("exec","exec");
290 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.TRUE })).booleanValue())
291 throw new Error("could not set execute bit on "+execFile.getAbsolutePath()+"for test");
292 File nonexecFile = writeTrashFile("nonexec","nonexec");
293 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.FALSE })).booleanValue())
294 throw new Error("could not clear execute bit on "+nonexecFile.getAbsolutePath()+"for test");
296 GitIndex index = new GitIndex(db);
297 index.filemode = Boolean.TRUE; // TODO: we need a way to set this using config
298 index.add(trash, execFile);
299 index.add(trash, nonexecFile);
300 Tree tree = db.mapTree(index.writeTree());
301 assertEquals(FileMode.EXECUTABLE_FILE, tree.findBlobMember(execFile.getName()).getMode());
302 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(nonexecFile.getName()).getMode());
304 index.write();
306 if (!execFile.delete())
307 throw new Error("Problem in test, cannot delete test file "+execFile.getAbsolutePath());
308 if (!nonexecFile.delete())
309 throw new Error("Problem in test, cannot delete test file "+nonexecFile.getAbsolutePath());
310 GitIndex index2 = new GitIndex(db);
311 index2.filemode = Boolean.TRUE; // TODO: we need a way to set this using config
312 index2.read();
313 index2.checkout(trash);
314 assertTrue(((Boolean)canExecute.invoke(execFile,(Object[])null)).booleanValue());
315 assertFalse(((Boolean)canExecute.invoke(nonexecFile,(Object[])null)).booleanValue());
317 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
318 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
320 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.FALSE })).booleanValue())
321 throw new Error("could not clear set execute bit on "+execFile.getAbsolutePath()+"for test");
322 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.TRUE })).booleanValue())
323 throw new Error("could set execute bit on "+nonexecFile.getAbsolutePath()+"for test");
325 assertTrue(index2.getEntry(execFile.getName()).isModified(trash));
326 assertTrue(index2.getEntry(nonexecFile.getName()).isModified(trash));
328 } catch (NoSuchMethodException e) {
329 System.err.println("Test ignored when running under JDk < 1.6");
330 return;
334 public void test031_executeBit_coreModeFalse() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
335 try {
336 // coremode true is the default, typically set to false
337 // by git init (but not jgit!)
338 Method canExecute = File.class.getMethod("canExecute", (Class[])null);
339 Method setExecute = File.class.getMethod("setExecutable", new Class[] { Boolean.TYPE });
340 File execFile = writeTrashFile("exec","exec");
341 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.TRUE })).booleanValue())
342 throw new Error("could not set execute bit on "+execFile.getAbsolutePath()+"for test");
343 File nonexecFile = writeTrashFile("nonexec","nonexec");
344 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.FALSE })).booleanValue())
345 throw new Error("could not clear execute bit on "+nonexecFile.getAbsolutePath()+"for test");
347 GitIndex index = new GitIndex(db);
348 index.filemode = Boolean.FALSE; // TODO: we need a way to set this using config
349 index.add(trash, execFile);
350 index.add(trash, nonexecFile);
351 Tree tree = db.mapTree(index.writeTree());
352 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(execFile.getName()).getMode());
353 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(nonexecFile.getName()).getMode());
355 index.write();
357 if (!execFile.delete())
358 throw new Error("Problem in test, cannot delete test file "+execFile.getAbsolutePath());
359 if (!nonexecFile.delete())
360 throw new Error("Problem in test, cannot delete test file "+nonexecFile.getAbsolutePath());
361 GitIndex index2 = new GitIndex(db);
362 index2.filemode = Boolean.FALSE; // TODO: we need a way to set this using config
363 index2.read();
364 index2.checkout(trash);
365 assertFalse(((Boolean)canExecute.invoke(execFile,(Object[])null)).booleanValue());
366 assertFalse(((Boolean)canExecute.invoke(nonexecFile,(Object[])null)).booleanValue());
368 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
369 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
371 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.FALSE })).booleanValue())
372 throw new Error("could not clear set execute bit on "+execFile.getAbsolutePath()+"for test");
373 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.TRUE })).booleanValue())
374 throw new Error("could set execute bit on "+nonexecFile.getAbsolutePath()+"for test");
376 // no change since we ignore the execute bit
377 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
378 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
380 } catch (NoSuchMethodException e) {
381 System.err.println("Test ignored when running under JDk < 1.6");
382 return;
386 private String content(File f) throws IOException {
387 byte[] buf = new byte[(int) f.length()];
388 FileInputStream is = new FileInputStream(f);
389 int read = is.read(buf);
390 assertEquals(f.length(), read);
391 return new String(buf, 0);
394 private void delete(File f) throws IOException {
395 if (!f.delete())
396 throw new IOException("Failed to delete f");